提交 a7b85335 编写于 作者: M Mark VanderVoord

the test runner generator now has the ability to also output a header file for...

the test runner generator now has the ability to also output a header file for the tests, which can get pulled into the test itself if desired.
上级 ab7e322a
...@@ -55,8 +55,10 @@ class UnityTestRunnerGenerator ...@@ -55,8 +55,10 @@ class UnityTestRunnerGenerator
source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) if ($QUICK_RUBY_VERSION > 10900) source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) if ($QUICK_RUBY_VERSION > 10900)
tests = find_tests(source) tests = find_tests(source)
headers = find_includes(source) headers = find_includes(source)
testfile_includes = headers[:local] + headers[:system] testfile_includes = (headers[:local] + headers[:system])
used_mocks = find_mocks(testfile_includes) used_mocks = find_mocks(testfile_includes)
testfile_includes = (testfile_includes - used_mocks)
testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/}
#build runner file #build runner file
generate(input_file, output_file, tests, used_mocks, testfile_includes) generate(input_file, output_file, tests, used_mocks, testfile_includes)
...@@ -77,6 +79,12 @@ class UnityTestRunnerGenerator ...@@ -77,6 +79,12 @@ class UnityTestRunnerGenerator
create_reset(output, used_mocks) create_reset(output, used_mocks)
create_main(output, input_file, tests, used_mocks) create_main(output, input_file, tests, used_mocks)
end 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 end
def find_tests(source) def find_tests(source)
...@@ -93,12 +101,13 @@ class UnityTestRunnerGenerator ...@@ -93,12 +101,13 @@ class UnityTestRunnerGenerator
arguments = $1 arguments = $1
name = $2 name = $2
call = $3 call = $3
params = $4
args = nil args = nil
if (@options[:use_param_tests] and !arguments.empty?) if (@options[:use_param_tests] and !arguments.empty?)
args = [] args = []
arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]} arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]}
end 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
end end
tests_and_line_numbers.uniq! {|v| v[:test] } tests_and_line_numbers.uniq! {|v| v[:test] }
...@@ -148,17 +157,19 @@ class UnityTestRunnerGenerator ...@@ -148,17 +157,19 @@ class UnityTestRunnerGenerator
output.puts("\n//=======Automagically Detected Files To Include=====") output.puts("\n//=======Automagically Detected Files To Include=====")
output.puts("#include \"#{@options[:framework].to_s}.h\"") output.puts("#include \"#{@options[:framework].to_s}.h\"")
output.puts('#include "cmock.h"') unless (mocks.empty?) 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 <setjmp.h>') output.puts('#include <setjmp.h>')
output.puts('#include <stdio.h>') output.puts('#include <stdio.h>')
output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception) output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception)
testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/} if (@options[:header_file] && !@options[:header_file].empty?)
testrunner_includes = testfile_includes - mocks output.puts("#include \"#{File.basename(@options[:header_file])}\"")
testrunner_includes.each do |inc| else
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") @options[:includes].flatten.uniq.compact.each do |inc|
end 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| mocks.each do |mock|
output.puts("#include \"#{mock.gsub('.h','')}.h\"") output.puts("#include \"#{mock.gsub('.h','')}.h\"")
end end
...@@ -296,8 +307,23 @@ class UnityTestRunnerGenerator ...@@ -296,8 +307,23 @@ class UnityTestRunnerGenerator
output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());") output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());")
output.puts("}") output.puts("}")
end 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__) if ($0 == __FILE__)
options = { :includes => [] } options = { :includes => [] }
...@@ -335,6 +361,7 @@ if ($0 == __FILE__) ...@@ -335,6 +361,7 @@ if ($0 == __FILE__)
" --suite_setup=\"\" - code to execute for setup of entire suite", " --suite_setup=\"\" - code to execute for setup of entire suite",
" --suite_teardown=\"\" - code to execute for teardown of entire suite", " --suite_teardown=\"\" - code to execute for teardown of entire suite",
" --use_param_tests=1 - enable parameterized tests (disabled by default)", " --use_param_tests=1 - enable parameterized tests (disabled by default)",
" --header_file=\"\" - path/name of test header file to generate too"
].join("\n") ].join("\n")
exit 1 exit 1
end end
......
/* 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 <setjmp.h>
#include <stdio.h>
#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());
}
/* 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 <setjmp.h>
void test_TheFirstThingToTest();
void test_TheSecondThingToTest();
#endif
/* 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 <setjmp.h>
#include <stdio.h>
#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());
}
/* 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 <setjmp.h>
void test_TheFirstThingToTest();
void test_TheSecondThingToTest();
#endif
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
//=======Automagically Detected Files To Include===== //=======Automagically Detected Files To Include=====
#include "unity.h" #include "unity.h"
#include "cmock.h" #include "cmock.h"
#include "one.h"
#include "two.h"
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include "CException.h" #include "CException.h"
#include "one.h"
#include "two.h"
#include "funky.h" #include "funky.h"
#include <setjmp.h> #include <setjmp.h>
#include "Mockstanky.h" #include "Mockstanky.h"
......
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
//=======Automagically Detected Files To Include===== //=======Automagically Detected Files To Include=====
#include "unity.h" #include "unity.h"
#include "cmock.h" #include "cmock.h"
#include "one.h"
#include "two.h"
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include "CException.h" #include "CException.h"
#include "one.h"
#include "two.h"
#include "funky.h" #include "funky.h"
#include <setjmp.h> #include <setjmp.h>
#include "Mockstanky.h" #include "Mockstanky.h"
......
...@@ -27,12 +27,12 @@ ...@@ -27,12 +27,12 @@
//=======Automagically Detected Files To Include===== //=======Automagically Detected Files To Include=====
#include "unity.h" #include "unity.h"
#include "cmock.h" #include "cmock.h"
#include "two.h"
#include "three.h"
#include <four.h>
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include "CException.h" #include "CException.h"
#include "two.h"
#include "three.h"
#include <four.h>
#include "funky.h" #include "funky.h"
#include <setjmp.h> #include <setjmp.h>
#include "Mockstanky.h" #include "Mockstanky.h"
......
...@@ -23,11 +23,11 @@ ...@@ -23,11 +23,11 @@
//=======Automagically Detected Files To Include===== //=======Automagically Detected Files To Include=====
#include "unity.h" #include "unity.h"
#include "one.h"
#include "two.h"
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include "CException.h" #include "CException.h"
#include "one.h"
#include "two.h"
#include "funky.h" #include "funky.h"
#include "stanky.h" #include "stanky.h"
#include <setjmp.h> #include <setjmp.h>
......
...@@ -23,11 +23,11 @@ ...@@ -23,11 +23,11 @@
//=======Automagically Detected Files To Include===== //=======Automagically Detected Files To Include=====
#include "unity.h" #include "unity.h"
#include "one.h"
#include "two.h"
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include "CException.h" #include "CException.h"
#include "one.h"
#include "two.h"
#include "funky.h" #include "funky.h"
#include "stanky.h" #include "stanky.h"
#include <setjmp.h> #include <setjmp.h>
......
...@@ -23,12 +23,12 @@ ...@@ -23,12 +23,12 @@
//=======Automagically Detected Files To Include===== //=======Automagically Detected Files To Include=====
#include "unity.h" #include "unity.h"
#include "two.h"
#include "three.h"
#include <four.h>
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include "CException.h" #include "CException.h"
#include "two.h"
#include "three.h"
#include <four.h>
#include "funky.h" #include "funky.h"
#include "stanky.h" #include "stanky.h"
#include <setjmp.h> #include <setjmp.h>
......
...@@ -38,6 +38,20 @@ should "GenerateARunnerByCreatingRunnerWithOptions" do ...@@ -38,6 +38,20 @@ should "GenerateARunnerByCreatingRunnerWithOptions" do
end end
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 should "GenerateARunnerByRunningRunnerWithOptions" do
sets = { 'run1' => { :plugins => [:cexception], :includes => ['one.h', 'two.h'], :enforce_strict_ordering => true }, 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();" } 'run2' => { :plugins => [:ignore], :suite_setup => "a_custom_setup();", :suite_teardown => "a_custom_teardown();" }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册