mirror of
https://github.com/ThrowTheSwitch/Unity.git
synced 2025-06-14 18:07:49 +08:00
Switch from the inconsistent use of weak symbols to handling setup, etc in script generators
This commit is contained in:
@ -58,6 +58,7 @@ class UnityTestRunnerGenerator
|
|||||||
used_mocks = find_mocks(testfile_includes)
|
used_mocks = find_mocks(testfile_includes)
|
||||||
testfile_includes = (testfile_includes - used_mocks)
|
testfile_includes = (testfile_includes - used_mocks)
|
||||||
testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ }
|
testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ }
|
||||||
|
find_setup_and_teardown()
|
||||||
|
|
||||||
# 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)
|
||||||
@ -165,11 +166,17 @@ class UnityTestRunnerGenerator
|
|||||||
mock_headers
|
mock_headers
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_setup_and_teardown(source)
|
||||||
|
@has_setup = source =~ /void\s+#{@options[setup_name]}\s*\(/
|
||||||
|
@has_teardown = source =~ /void\s+#{@options[teardown_name]}\s*\(/
|
||||||
|
@has_suite_setup = (!@options[:suite_setup].nil?) || (source =~ /void\s+suiteSetUp\s*\(/)
|
||||||
|
@has_suite_teardown = (!@options[:suite_teardown].nil?) || (source =~ /void\s+suiteTearDown\s*\(/)
|
||||||
|
end
|
||||||
|
|
||||||
def create_header(output, mocks, testfile_includes = [])
|
def create_header(output, mocks, testfile_includes = [])
|
||||||
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
|
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
|
||||||
create_runtest(output, mocks)
|
create_runtest(output, mocks)
|
||||||
output.puts("\n/*=======Automagically Detected Files To Include=====*/")
|
output.puts("\n/*=======Automagically Detected Files To Include=====*/")
|
||||||
output.puts('#define UNITY_INCLUDE_SETUP_STUBS') if @options[:suite_setup].nil?
|
|
||||||
output.puts("#include \"#{@options[:framework]}.h\"")
|
output.puts("#include \"#{@options[:framework]}.h\"")
|
||||||
output.puts('#include "cmock.h"') unless mocks.empty?
|
output.puts('#include "cmock.h"') unless mocks.empty?
|
||||||
output.puts('#ifndef UNITY_EXCLUDE_SETJMP_H')
|
output.puts('#ifndef UNITY_EXCLUDE_SETJMP_H')
|
||||||
@ -204,8 +211,8 @@ class UnityTestRunnerGenerator
|
|||||||
|
|
||||||
def create_externs(output, tests, _mocks)
|
def create_externs(output, tests, _mocks)
|
||||||
output.puts("\n/*=======External Functions This Runner Calls=====*/")
|
output.puts("\n/*=======External Functions This Runner Calls=====*/")
|
||||||
output.puts("extern void #{@options[:setup_name]}(void);")
|
output.puts("extern void #{@options[:setup_name]}(void);") if @has_setup
|
||||||
output.puts("extern void #{@options[:teardown_name]}(void);")
|
output.puts("extern void #{@options[:teardown_name]}(void);") if @has_teardown
|
||||||
output.puts("\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif") if @options[:externc]
|
output.puts("\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif") if @options[:externc]
|
||||||
tests.each do |test|
|
tests.each do |test|
|
||||||
output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});")
|
output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});")
|
||||||
@ -252,37 +259,31 @@ class UnityTestRunnerGenerator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_suite_setup(output)
|
def create_suite_setup(output)
|
||||||
output.puts("\n/*=======Suite Setup=====*/")
|
if @has_suite_setup
|
||||||
output.puts('static void suite_setup(void)')
|
if @options[:suite_setup].nil?
|
||||||
output.puts('{')
|
output.puts("\n/*=======Suite Setup=====*/")
|
||||||
if @options[:suite_setup].nil?
|
output.puts('static void suiteSetUp(void)')
|
||||||
# New style, call suiteSetUp() if we can use weak symbols
|
output.puts('{')
|
||||||
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
|
output.puts(@options[:suite_setup])
|
||||||
output.puts(' suiteSetUp();')
|
output.puts('}')
|
||||||
output.puts('#endif')
|
else
|
||||||
else
|
output.puts('extern void suiteSetUp(void);')
|
||||||
# Old style, C code embedded in the :suite_setup option
|
end
|
||||||
output.puts(@options[:suite_setup])
|
|
||||||
end
|
end
|
||||||
output.puts('}')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_suite_teardown(output)
|
def create_suite_teardown(output)
|
||||||
output.puts("\n/*=======Suite Teardown=====*/")
|
if (@has_suite_teardown)
|
||||||
output.puts('static int suite_teardown(int num_failures)')
|
if @options[:suite_teardown].nil?
|
||||||
output.puts('{')
|
output.puts("\n/*=======Suite Teardown=====*/")
|
||||||
if @options[:suite_teardown].nil?
|
output.puts('static int suite_teardown(int num_failures)')
|
||||||
# New style, call suiteTearDown() if we can use weak symbols
|
output.puts('{')
|
||||||
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
|
output.puts(@options[:suite_teardown])
|
||||||
output.puts(' return suiteTearDown(num_failures);')
|
output.puts('}')
|
||||||
output.puts('#else')
|
else
|
||||||
output.puts(' return num_failures;')
|
output.puts('extern int suite_teardown(int num_failures);')
|
||||||
output.puts('#endif')
|
end
|
||||||
else
|
|
||||||
# Old style, C code embedded in the :suite_teardown option
|
|
||||||
output.puts(@options[:suite_teardown])
|
|
||||||
end
|
end
|
||||||
output.puts('}')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_runtest(output, used_mocks)
|
def create_runtest(output, used_mocks)
|
||||||
@ -304,13 +305,13 @@ class UnityTestRunnerGenerator
|
|||||||
output.puts(' { \\')
|
output.puts(' { \\')
|
||||||
output.puts(' CEXCEPTION_T e; \\') if cexception
|
output.puts(' CEXCEPTION_T e; \\') if cexception
|
||||||
output.puts(' Try { \\') if cexception
|
output.puts(' Try { \\') if cexception
|
||||||
output.puts(" #{@options[:setup_name]}(); \\")
|
output.puts(" #{@options[:setup_name]}(); \\") if @has_setup
|
||||||
output.puts(" TestFunc(#{va_args2}); \\")
|
output.puts(" TestFunc(#{va_args2}); \\")
|
||||||
output.puts(' } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); } \\') if cexception
|
output.puts(' } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); } \\') if cexception
|
||||||
output.puts(' } \\')
|
output.puts(' } \\')
|
||||||
output.puts(' if (TEST_PROTECT()) \\')
|
output.puts(' if (TEST_PROTECT()) \\')
|
||||||
output.puts(' { \\')
|
output.puts(' { \\')
|
||||||
output.puts(" #{@options[:teardown_name]}(); \\")
|
output.puts(" #{@options[:teardown_name]}(); \\") if @has_teardown
|
||||||
output.puts(' CMock_Verify(); \\') unless used_mocks.empty?
|
output.puts(' CMock_Verify(); \\') unless used_mocks.empty?
|
||||||
output.puts(' } \\')
|
output.puts(' } \\')
|
||||||
output.puts(' CMock_Destroy(); \\') unless used_mocks.empty?
|
output.puts(' CMock_Destroy(); \\') unless used_mocks.empty?
|
||||||
@ -327,9 +328,9 @@ class UnityTestRunnerGenerator
|
|||||||
output.puts('{')
|
output.puts('{')
|
||||||
output.puts(' CMock_Verify();') unless used_mocks.empty?
|
output.puts(' CMock_Verify();') unless used_mocks.empty?
|
||||||
output.puts(' CMock_Destroy();') unless used_mocks.empty?
|
output.puts(' CMock_Destroy();') unless used_mocks.empty?
|
||||||
output.puts(" #{@options[:teardown_name]}();")
|
output.puts(" #{@options[:teardown_name]}();") if @has_teardown
|
||||||
output.puts(' CMock_Init();') unless used_mocks.empty?
|
output.puts(' CMock_Init();') unless used_mocks.empty?
|
||||||
output.puts(" #{@options[:setup_name]}();")
|
output.puts(" #{@options[:setup_name]}();") if @has_setup
|
||||||
output.puts('}')
|
output.puts('}')
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -375,7 +376,7 @@ class UnityTestRunnerGenerator
|
|||||||
output.puts("int #{main_name}(void)")
|
output.puts("int #{main_name}(void)")
|
||||||
output.puts('{')
|
output.puts('{')
|
||||||
end
|
end
|
||||||
output.puts(' suite_setup();')
|
output.puts(' suiteSetUp();') if @has_suite_setup
|
||||||
output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
|
output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
|
||||||
if @options[:use_param_tests]
|
if @options[:use_param_tests]
|
||||||
tests.each do |test|
|
tests.each do |test|
|
||||||
@ -390,7 +391,11 @@ class UnityTestRunnerGenerator
|
|||||||
end
|
end
|
||||||
output.puts
|
output.puts
|
||||||
output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty?
|
output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty?
|
||||||
output.puts(' return suite_teardown(UnityEnd());')
|
if (@has_suite_teardown)
|
||||||
|
output.puts(' return suiteTearDown(UnityEnd());')
|
||||||
|
else
|
||||||
|
output.puts(' return UnityEnd();')
|
||||||
|
end
|
||||||
output.puts('}')
|
output.puts('}')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
33
src/unity.h
33
src/unity.h
@ -24,39 +24,22 @@ extern "C"
|
|||||||
* Test Setup / Teardown
|
* Test Setup / Teardown
|
||||||
*-------------------------------------------------------*/
|
*-------------------------------------------------------*/
|
||||||
|
|
||||||
/* These functions are intended to be called before and after each test. */
|
/* These functions are intended to be called before and after each test.
|
||||||
|
* If using unity directly, these will need to be provided for each test
|
||||||
|
* executable built. If you are using the test runner generator and/or
|
||||||
|
* Ceedling, these are optional. */
|
||||||
void setUp(void);
|
void setUp(void);
|
||||||
void tearDown(void);
|
void tearDown(void);
|
||||||
|
|
||||||
/* These functions are intended to be called at the beginning and end of an
|
/* These functions are intended to be called at the beginning and end of an
|
||||||
* entire test suite. suiteTearDown() is passed the number of tests that
|
* entire test suite. suiteTearDown() is passed the number of tests that
|
||||||
* failed, and its return value becomes the exit code of main(). */
|
* failed, and its return value becomes the exit code of main(). If using
|
||||||
|
* Unity directly, you're in charge of calling these if they are desired.
|
||||||
|
* If using Ceedling or the test runner generator, these will be called
|
||||||
|
* automatically if they exist. */
|
||||||
void suiteSetUp(void);
|
void suiteSetUp(void);
|
||||||
int suiteTearDown(int num_failures);
|
int suiteTearDown(int num_failures);
|
||||||
|
|
||||||
/* If the compiler supports it, the following block provides stub
|
|
||||||
* implementations of the above functions as weak symbols. Note that on
|
|
||||||
* some platforms (MinGW for example), weak function implementations need
|
|
||||||
* to be in the same translation unit they are called from. This can be
|
|
||||||
* achieved by defining UNITY_INCLUDE_SETUP_STUBS before including unity.h. */
|
|
||||||
#ifdef UNITY_INCLUDE_SETUP_STUBS
|
|
||||||
#ifdef UNITY_WEAK_ATTRIBUTE
|
|
||||||
UNITY_WEAK_ATTRIBUTE void setUp(void) { }
|
|
||||||
UNITY_WEAK_ATTRIBUTE void tearDown(void) { }
|
|
||||||
UNITY_WEAK_ATTRIBUTE void suiteSetUp(void) { }
|
|
||||||
UNITY_WEAK_ATTRIBUTE int suiteTearDown(int num_failures) { return num_failures; }
|
|
||||||
#elif defined(UNITY_WEAK_PRAGMA)
|
|
||||||
#pragma weak setUp
|
|
||||||
void setUp(void) { }
|
|
||||||
#pragma weak tearDown
|
|
||||||
void tearDown(void) { }
|
|
||||||
#pragma weak suiteSetUp
|
|
||||||
void suiteSetUp(void) { }
|
|
||||||
#pragma weak suiteTearDown
|
|
||||||
int suiteTearDown(int num_failures) { return num_failures; }
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------
|
/*-------------------------------------------------------
|
||||||
* Configuration Options
|
* Configuration Options
|
||||||
*-------------------------------------------------------
|
*-------------------------------------------------------
|
||||||
|
@ -372,22 +372,6 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT;
|
|||||||
#define UNITY_COUNTER_TYPE UNITY_UINT
|
#define UNITY_COUNTER_TYPE UNITY_UINT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-------------------------------------------------------
|
|
||||||
* Language Features Available
|
|
||||||
*-------------------------------------------------------*/
|
|
||||||
#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA)
|
|
||||||
# if defined(__GNUC__) || defined(__ghs__) /* __GNUC__ includes clang */
|
|
||||||
# if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__)
|
|
||||||
# define UNITY_WEAK_ATTRIBUTE __attribute__((weak))
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNITY_NO_WEAK
|
|
||||||
# undef UNITY_WEAK_ATTRIBUTE
|
|
||||||
# undef UNITY_WEAK_PRAGMA
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------
|
/*-------------------------------------------------------
|
||||||
* Internal Structs Needed
|
* Internal Structs Needed
|
||||||
*-------------------------------------------------------*/
|
*-------------------------------------------------------*/
|
||||||
|
Reference in New Issue
Block a user