diff --git a/auto/generate_test_runner.rb b/auto/generate_test_runner.rb index c528e77915f80c7f4715f24dcf648e9aa643bf86..e29a9be95747c81f9a59e576d81be6da0a7eace1 100644 --- a/auto/generate_test_runner.rb +++ b/auto/generate_test_runner.rb @@ -55,8 +55,10 @@ class UnityTestRunnerGenerator source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) if ($QUICK_RUBY_VERSION > 10900) tests = find_tests(source) headers = find_includes(source) - testfile_includes = headers[:local] + headers[:system] + testfile_includes = (headers[:local] + headers[:system]) used_mocks = find_mocks(testfile_includes) + testfile_includes = (testfile_includes - used_mocks) + testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/} #build runner file generate(input_file, output_file, tests, used_mocks, testfile_includes) @@ -77,6 +79,12 @@ class UnityTestRunnerGenerator create_reset(output, used_mocks) create_main(output, input_file, tests, used_mocks) end + + if (@options[:header_file] && !@options[:header_file].empty?) + File.open(@options[:header_file], 'w') do |output| + create_h_file(output, @options[:header_file], tests, testfile_includes) + end + end end def find_tests(source) @@ -93,12 +101,13 @@ class UnityTestRunnerGenerator arguments = $1 name = $2 call = $3 + params = $4 args = nil if (@options[:use_param_tests] and !arguments.empty?) args = [] arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]} end - tests_and_line_numbers << { :test => name, :args => args, :call => call, :line_number => 0 } + tests_and_line_numbers << { :test => name, :args => args, :call => call, :params => params, :line_number => 0 } end end tests_and_line_numbers.uniq! {|v| v[:test] } @@ -148,17 +157,19 @@ class UnityTestRunnerGenerator output.puts("\n//=======Automagically Detected Files To Include=====") output.puts("#include \"#{@options[:framework].to_s}.h\"") output.puts('#include "cmock.h"') unless (mocks.empty?) - @options[:includes].flatten.uniq.compact.each do |inc| - output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") - end output.puts('#include ') output.puts('#include ') output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception) - testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/} - testrunner_includes = testfile_includes - mocks - testrunner_includes.each do |inc| - output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") - end + if (@options[:header_file] && !@options[:header_file].empty?) + output.puts("#include \"#{File.basename(@options[:header_file])}\"") + else + @options[:includes].flatten.uniq.compact.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") + end + testfile_includes.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") + end + end mocks.each do |mock| output.puts("#include \"#{mock.gsub('.h','')}.h\"") end @@ -296,8 +307,23 @@ class UnityTestRunnerGenerator output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());") output.puts("}") end -end + def create_h_file(output, filename, tests, testfile_includes) + filename = filename.upcase.gsub(/(?:\/|\\|\.)*/,'_') + output.puts("/* AUTOGENERATED FILE. DO NOT EDIT. */") + output.puts("#ifndef _#{filename}") + output.puts("#define _#{filename}\n\n") + @options[:includes].flatten.uniq.compact.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") + end + testfile_includes.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") + end + output.puts "\n" + tests.each {|test| output.puts("void #{test[:test]}(#{test[:params]});") } + output.puts("#endif\n\n") + end +end if ($0 == __FILE__) options = { :includes => [] } @@ -335,6 +361,7 @@ if ($0 == __FILE__) " --suite_setup=\"\" - code to execute for setup of entire suite", " --suite_teardown=\"\" - code to execute for teardown of entire suite", " --use_param_tests=1 - enable parameterized tests (disabled by default)", + " --header_file=\"\" - path/name of test header file to generate too" ].join("\n") exit 1 end diff --git a/test/expectdata/testsample_head1.c b/test/expectdata/testsample_head1.c new file mode 100644 index 0000000000000000000000000000000000000000..feb823c8d930451ca6b34caec8511b60e6dd58c5 --- /dev/null +++ b/test/expectdata/testsample_head1.c @@ -0,0 +1,51 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ + +//=======Test Runner Used To Run Each Test Below===== +#define RUN_TEST(TestFunc, TestLineNum) \ +{ \ + Unity.CurrentTestName = #TestFunc; \ + Unity.CurrentTestLineNumber = TestLineNum; \ + Unity.NumberOfTests++; \ + if (TEST_PROTECT()) \ + { \ + setUp(); \ + TestFunc(); \ + } \ + if (TEST_PROTECT() && !TEST_IS_IGNORED) \ + { \ + tearDown(); \ + } \ + UnityConcludeTest(); \ +} + +//=======Automagically Detected Files To Include===== +#include "unity.h" +#include +#include +#include "testsample_head1.h" + +//=======External Functions This Runner Calls===== +extern void setUp(void); +extern void tearDown(void); +extern void test_TheFirstThingToTest(void); +extern void test_TheSecondThingToTest(void); + + +//=======Test Reset Option===== +void resetTest(void); +void resetTest(void) +{ + tearDown(); + setUp(); +} + + +//=======MAIN===== +int main(void) +{ + UnityBegin("testdata/testsample.c"); + RUN_TEST(test_TheFirstThingToTest, 21); + RUN_TEST(test_TheSecondThingToTest, 43); + + return (UnityEnd()); +} diff --git a/test/expectdata/testsample_head1.h b/test/expectdata/testsample_head1.h new file mode 100644 index 0000000000000000000000000000000000000000..3cc343835882ad37f63ad8425b9a3017f1212f43 --- /dev/null +++ b/test/expectdata/testsample_head1.h @@ -0,0 +1,12 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#ifndef __B_U_I_L_D__T_E_S_T_S_A_M_P_L_E___H_E_A_D_1__H_ +#define __B_U_I_L_D__T_E_S_T_S_A_M_P_L_E___H_E_A_D_1__H_ + +#include "funky.h" +#include "stanky.h" +#include + +void test_TheFirstThingToTest(); +void test_TheSecondThingToTest(); +#endif + diff --git a/test/expectdata/testsample_mock_head1.c b/test/expectdata/testsample_mock_head1.c new file mode 100644 index 0000000000000000000000000000000000000000..a3680ec7f1ec4709f4672edd224197aac3e277db --- /dev/null +++ b/test/expectdata/testsample_mock_head1.c @@ -0,0 +1,74 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ + +//=======Test Runner Used To Run Each Test Below===== +#define RUN_TEST(TestFunc, TestLineNum) \ +{ \ + Unity.CurrentTestName = #TestFunc; \ + Unity.CurrentTestLineNumber = TestLineNum; \ + Unity.NumberOfTests++; \ + CMock_Init(); \ + if (TEST_PROTECT()) \ + { \ + setUp(); \ + TestFunc(); \ + } \ + if (TEST_PROTECT() && !TEST_IS_IGNORED) \ + { \ + tearDown(); \ + CMock_Verify(); \ + } \ + CMock_Destroy(); \ + UnityConcludeTest(); \ +} + +//=======Automagically Detected Files To Include===== +#include "unity.h" +#include "cmock.h" +#include +#include +#include "testsample_mock_head1.h" +#include "Mockstanky.h" + +//=======External Functions This Runner Calls===== +extern void setUp(void); +extern void tearDown(void); +extern void test_TheFirstThingToTest(void); +extern void test_TheSecondThingToTest(void); + + +//=======Mock Management===== +static void CMock_Init(void) +{ + Mockstanky_Init(); +} +static void CMock_Verify(void) +{ + Mockstanky_Verify(); +} +static void CMock_Destroy(void) +{ + Mockstanky_Destroy(); +} + +//=======Test Reset Option===== +void resetTest(void); +void resetTest(void) +{ + CMock_Verify(); + CMock_Destroy(); + tearDown(); + CMock_Init(); + setUp(); +} + + +//=======MAIN===== +int main(void) +{ + UnityBegin("testdata/mocksample.c"); + RUN_TEST(test_TheFirstThingToTest, 21); + RUN_TEST(test_TheSecondThingToTest, 43); + + CMock_Guts_MemFreeFinal(); + return (UnityEnd()); +} diff --git a/test/expectdata/testsample_mock_head1.h b/test/expectdata/testsample_mock_head1.h new file mode 100644 index 0000000000000000000000000000000000000000..2819414692f44f53a5f632b0dc7b24b933241a50 --- /dev/null +++ b/test/expectdata/testsample_mock_head1.h @@ -0,0 +1,11 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#ifndef __B_U_I_L_D__T_E_S_T_S_A_M_P_L_E___M_O_C_K___H_E_A_D_1__H_ +#define __B_U_I_L_D__T_E_S_T_S_A_M_P_L_E___M_O_C_K___H_E_A_D_1__H_ + +#include "funky.h" +#include + +void test_TheFirstThingToTest(); +void test_TheSecondThingToTest(); +#endif + diff --git a/test/expectdata/testsample_mock_new1.c b/test/expectdata/testsample_mock_new1.c index 7f49c2e245f87a897c983e31945ece86acbcd01c..8dd68475992bd4a5d1929a9bd06696d385df403e 100644 --- a/test/expectdata/testsample_mock_new1.c +++ b/test/expectdata/testsample_mock_new1.c @@ -27,11 +27,11 @@ //=======Automagically Detected Files To Include===== #include "unity.h" #include "cmock.h" -#include "one.h" -#include "two.h" #include #include #include "CException.h" +#include "one.h" +#include "two.h" #include "funky.h" #include #include "Mockstanky.h" diff --git a/test/expectdata/testsample_mock_run1.c b/test/expectdata/testsample_mock_run1.c index 7f49c2e245f87a897c983e31945ece86acbcd01c..8dd68475992bd4a5d1929a9bd06696d385df403e 100644 --- a/test/expectdata/testsample_mock_run1.c +++ b/test/expectdata/testsample_mock_run1.c @@ -27,11 +27,11 @@ //=======Automagically Detected Files To Include===== #include "unity.h" #include "cmock.h" -#include "one.h" -#include "two.h" #include #include #include "CException.h" +#include "one.h" +#include "two.h" #include "funky.h" #include #include "Mockstanky.h" diff --git a/test/expectdata/testsample_mock_yaml.c b/test/expectdata/testsample_mock_yaml.c index 35377d7bd99bcfa8a521fc3e5a9583b8134c1dd9..b28c8f0c8fa2054341dbbc863eaf836c3dae465f 100644 --- a/test/expectdata/testsample_mock_yaml.c +++ b/test/expectdata/testsample_mock_yaml.c @@ -27,12 +27,12 @@ //=======Automagically Detected Files To Include===== #include "unity.h" #include "cmock.h" -#include "two.h" -#include "three.h" -#include #include #include #include "CException.h" +#include "two.h" +#include "three.h" +#include #include "funky.h" #include #include "Mockstanky.h" diff --git a/test/expectdata/testsample_new1.c b/test/expectdata/testsample_new1.c index 1bba7ea6e89effa77d7bd5430a36db9bc66df05e..641300639aa90f7614d72715565be1d5eebf9f9f 100644 --- a/test/expectdata/testsample_new1.c +++ b/test/expectdata/testsample_new1.c @@ -23,11 +23,11 @@ //=======Automagically Detected Files To Include===== #include "unity.h" -#include "one.h" -#include "two.h" #include #include #include "CException.h" +#include "one.h" +#include "two.h" #include "funky.h" #include "stanky.h" #include diff --git a/test/expectdata/testsample_run1.c b/test/expectdata/testsample_run1.c index 1bba7ea6e89effa77d7bd5430a36db9bc66df05e..641300639aa90f7614d72715565be1d5eebf9f9f 100644 --- a/test/expectdata/testsample_run1.c +++ b/test/expectdata/testsample_run1.c @@ -23,11 +23,11 @@ //=======Automagically Detected Files To Include===== #include "unity.h" -#include "one.h" -#include "two.h" #include #include #include "CException.h" +#include "one.h" +#include "two.h" #include "funky.h" #include "stanky.h" #include diff --git a/test/expectdata/testsample_yaml.c b/test/expectdata/testsample_yaml.c index 96ba511d5de8b121263a1c036b1402e0c411190b..2c916828983ce16087d48b8eb105ae14a302063b 100644 --- a/test/expectdata/testsample_yaml.c +++ b/test/expectdata/testsample_yaml.c @@ -23,12 +23,12 @@ //=======Automagically Detected Files To Include===== #include "unity.h" -#include "two.h" -#include "three.h" -#include #include #include #include "CException.h" +#include "two.h" +#include "three.h" +#include #include "funky.h" #include "stanky.h" #include diff --git a/test/tests/test_generate_test_runner.rb b/test/tests/test_generate_test_runner.rb index 1f60f9877b7abf14ed9f51a22423b5d7f7392973..7ac458d7d0dd7470594c6297ef22f925515ff49f 100644 --- a/test/tests/test_generate_test_runner.rb +++ b/test/tests/test_generate_test_runner.rb @@ -38,6 +38,20 @@ should "GenerateARunnerByCreatingRunnerWithOptions" do end end +should "GenerateARunnerAlongWithAHeaderIfSpecified" do + sets = { 'head1' => { :header_file => "#{OUT_FILE}head1.h" } } + sets.each_pair do |subtest, options| + UnityTestRunnerGenerator.new(options).run(TEST_FILE, OUT_FILE + subtest + '.c') + verify_output_equal(subtest) + end + + sets = { 'head1' => { :header_file => "#{OUT_FILE}mock_head1.h" } } + sets.each_pair do |subtest, options| + UnityTestRunnerGenerator.new(options).run(TEST_MOCK, OUT_FILE + 'mock_' + subtest + '.c') + verify_output_equal('mock_' + subtest) + end +end + should "GenerateARunnerByRunningRunnerWithOptions" do sets = { 'run1' => { :plugins => [:cexception], :includes => ['one.h', 'two.h'], :enforce_strict_ordering => true }, 'run2' => { :plugins => [:ignore], :suite_setup => "a_custom_setup();", :suite_teardown => "a_custom_teardown();" }