Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 53 additions & 39 deletions auto/generate_test_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,19 @@ class UnityTestRunnerGenerator
def initialize(options = nil)
@options = UnityTestRunnerGenerator.default_options
case options
when NilClass then @options
when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options))
when Hash then @options.merge!(options)
else raise 'If you specify arguments, it should be a filename or a hash of options'
when NilClass
@options
when String
@options.merge!(UnityTestRunnerGenerator.grab_config(options))
when Hash
# Check if some of these have been specified
@options[:has_setup] = !options[:setup_name].nil?
@options[:has_teardown] = !options[:teardown_name].nil?
@options[:has_suite_setup] = !options[:suite_setup].nil?
@options[:has_suite_teardown] = !options[:suite_teardown].nil?
@options.merge!(options)
else
raise 'If you specify arguments, it should be a filename or a hash of options'
end
require_relative 'type_sanitizer'
end
Expand Down Expand Up @@ -58,6 +67,7 @@ def run(input_file, output_file, options = nil)
used_mocks = find_mocks(testfile_includes)
testfile_includes = (testfile_includes - used_mocks)
testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ }
find_setup_and_teardown(source)

# build runner file
generate(input_file, output_file, tests, used_mocks, testfile_includes)
Expand Down Expand Up @@ -165,11 +175,17 @@ def find_mocks(includes)
mock_headers
end

def find_setup_and_teardown(source)
@options[:has_setup] = source =~ /void\s+#{@options[:setup_name]}\s*\(/
@options[:has_teardown] = source =~ /void\s+#{@options[:teardown_name]}\s*\(/
@options[:has_suite_setup] ||= (source =~ /void\s+suiteSetUp\s*\(/)
@options[:has_suite_teardown] ||= (source =~ /void\s+suiteTearDown\s*\(/)
end

def create_header(output, mocks, testfile_includes = [])
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
create_runtest(output, mocks)
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 "cmock.h"') unless mocks.empty?
output.puts('#ifndef UNITY_EXCLUDE_SETJMP_H')
Expand Down Expand Up @@ -204,8 +220,8 @@ def create_header(output, mocks, testfile_includes = [])

def create_externs(output, tests, _mocks)
output.puts("\n/*=======External Functions This Runner Calls=====*/")
output.puts("extern void #{@options[:setup_name]}(void);")
output.puts("extern void #{@options[:teardown_name]}(void);")
output.puts("extern void #{@options[:setup_name]}(void);") if @options[:has_setup]
output.puts("extern void #{@options[:teardown_name]}(void);") if @options[:has_teardown]
output.puts("\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif") if @options[:externc]
tests.each do |test|
output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});")
Expand Down Expand Up @@ -252,37 +268,31 @@ def create_mock_management(output, mock_headers)
end

def create_suite_setup(output)
output.puts("\n/*=======Suite Setup=====*/")
output.puts('static void suite_setup(void)')
output.puts('{')
if @options[:suite_setup].nil?
# New style, call suiteSetUp() if we can use weak symbols
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
output.puts(' suiteSetUp();')
output.puts('#endif')
else
# Old style, C code embedded in the :suite_setup option
output.puts(@options[:suite_setup])
if @options[:has_suite_setup]
if !@options[:suite_setup].nil?
output.puts("\n/*=======Suite Setup=====*/")
output.puts('void suiteSetUp(void)')
output.puts('{')
output.puts(@options[:suite_setup])
output.puts('}')
else
output.puts('extern void suiteSetUp(void);')
end
end
output.puts('}')
end

def create_suite_teardown(output)
output.puts("\n/*=======Suite Teardown=====*/")
output.puts('static int suite_teardown(int num_failures)')
output.puts('{')
if @options[:suite_teardown].nil?
# New style, call suiteTearDown() if we can use weak symbols
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
output.puts(' return suiteTearDown(num_failures);')
output.puts('#else')
output.puts(' return num_failures;')
output.puts('#endif')
else
# Old style, C code embedded in the :suite_teardown option
output.puts(@options[:suite_teardown])
if @options[:has_suite_teardown]
if !@options[:suite_teardown].nil?
output.puts("\n/*=======Suite Teardown=====*/")
output.puts('int suiteTearDown(int num_failures)')
output.puts('{')
output.puts(@options[:suite_teardown])
output.puts('}')
else
output.puts('extern int suiteTearDown(int num_failures);')
end
end
output.puts('}')
end

def create_runtest(output, used_mocks)
Expand All @@ -304,13 +314,13 @@ def create_runtest(output, used_mocks)
output.puts(' { \\')
output.puts(' CEXCEPTION_T e; \\') if cexception
output.puts(' Try { \\') if cexception
output.puts(" #{@options[:setup_name]}(); \\")
output.puts(" #{@options[:setup_name]}(); \\") if @options[:has_setup]
output.puts(" TestFunc(#{va_args2}); \\")
output.puts(' } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); } \\') if cexception
output.puts(' } \\')
output.puts(' if (TEST_PROTECT()) \\')
output.puts(' { \\')
output.puts(" #{@options[:teardown_name]}(); \\")
output.puts(" #{@options[:teardown_name]}(); \\") if @options[:has_teardown]
output.puts(' CMock_Verify(); \\') unless used_mocks.empty?
output.puts(' } \\')
output.puts(' CMock_Destroy(); \\') unless used_mocks.empty?
Expand All @@ -327,9 +337,9 @@ def create_reset(output, used_mocks)
output.puts('{')
output.puts(' CMock_Verify();') unless used_mocks.empty?
output.puts(' CMock_Destroy();') unless used_mocks.empty?
output.puts(" #{@options[:teardown_name]}();")
output.puts(" #{@options[:teardown_name]}();") if @options[:has_teardown]
output.puts(' CMock_Init();') unless used_mocks.empty?
output.puts(" #{@options[:setup_name]}();")
output.puts(" #{@options[:setup_name]}();") if @options[:has_setup]
output.puts('}')
end

Expand Down Expand Up @@ -375,7 +385,7 @@ def create_main(output, filename, tests, used_mocks)
output.puts("int #{main_name}(void)")
output.puts('{')
end
output.puts(' suite_setup();')
output.puts(' suiteSetUp();') if @options[:has_suite_setup]
output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
if @options[:use_param_tests]
tests.each do |test|
Expand All @@ -390,7 +400,11 @@ def create_main(output, filename, tests, used_mocks)
end
output.puts
output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty?
output.puts(' return suite_teardown(UnityEnd());')
if @options[:has_suite_teardown]
output.puts(' return suiteTearDown(UnityEnd());')
else
output.puts(' return UnityEnd();')
end
output.puts('}')
end

Expand Down
34 changes: 2 additions & 32 deletions docs/UnityConfigurationGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ Define this to be the number of bits a pointer takes up on your system. The
default, if not autodetected, is 32-bits. If you're getting ugly compiler
warnings about casting from pointers, this is the one to look at.

_Hint:_ In order to support exotic processors (for example TI C55x with a pointer
_Hint:_ In order to support exotic processors (for example TI C55x with a pointer
width of 23-bit), choose the next power of two (in this case 32-bit).

_Supported values:_ 16, 32 and 64
_Supported values:_ 16, 32 and 64

_Example:_
```C
Expand Down Expand Up @@ -343,36 +343,6 @@ _Note:_
specifying `UNITY_USE_FLUSH_STDOUT`. No other defines are required.


##### `UNITY_WEAK_ATTRIBUTE`

##### `UNITY_WEAK_PRAGMA`

##### `UNITY_NO_WEAK`

For some targets, Unity can make the otherwise required setUp() and tearDown()
functions optional. This is a nice convenience for test writers since setUp and
tearDown don’t often actually do anything. If you’re using gcc or clang, this
option is automatically defined for you. Other compilers can also support this
behavior, if they support a C feature called weak functions. A weak function is
a function that is compiled into your executable unless a non-weak version of
the same function is defined elsewhere. If a non-weak version is found, the weak
version is ignored as if it never existed. If your compiler supports this feature,
you can let Unity know by defining UNITY_WEAK_ATTRIBUTE or UNITY_WEAK_PRAGMA as
the function attributes that would need to be applied to identify a function as
weak. If your compiler lacks support for weak functions, you will always need to
define setUp and tearDown functions (though they can be and often will be just
empty). You can also force Unity to NOT use weak functions by defining
UNITY_NO_WEAK. The most common options for this feature are:

_Example:_
```C
#define UNITY_WEAK_ATTRIBUTE weak
#define UNITY_WEAK_ATTRIBUTE __attribute__((weak))
#define UNITY_WEAK_PRAGMA
#define UNITY_NO_WEAK
```


##### `UNITY_PTR_ATTRIBUTE`

Some compilers require a custom attribute to be assigned to pointers, like
Expand Down
13 changes: 7 additions & 6 deletions docs/UnityGettingStartedGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ Next, a test file will include a `setUp()` and `tearDown()` function. The setUp
function can contain anything you would like to run before each test. The
tearDown function can contain anything you would like to run after each test.
Both functions accept no arguments and return nothing. You may leave either or
both of these blank if you have no need for them. If you're using a compiler
that is configured to make these functions optional, you may leave them off
both of these blank if you have no need for them.

If you're using Ceedling or the test runner generator script, you may leave these off
completely. Not sure? Give it a try. If you compiler complains that it can't
find setUp or tearDown when it links, you'll know you need to at least include
an empty function for these.
Expand All @@ -103,7 +104,7 @@ The majority of the file will be a series of test functions. Test functions
follow the convention of starting with the word "test_" or "spec_". You don't HAVE
to name them this way, but it makes it clear what functions are tests for other
developers. Also, the automated scripts that come with Unity or Ceedling will default
to looking for test functions to be prefixed this way. Test functions take no arguments
to looking for test functions to be prefixed this way. Test functions take no arguments
and return nothing. All test accounting is handled internally in Unity.

Finally, at the bottom of your test file, you will write a `main()` function.
Expand Down Expand Up @@ -156,7 +157,7 @@ This should be enough to get you going, though.

### Running Test Functions
When writing your own `main()` functions, for a test-runner. There are two ways
to execute the test.
to execute the test.

The classic variant
``` c
Expand All @@ -170,8 +171,8 @@ These macros perform the necessary setup before the test is called and
handles cleanup and result tabulation afterwards.

### Ignoring Test Functions
There are times when a test is incomplete or not valid for some reason.
At these times, TEST_IGNORE can be called. Control will immediately be
There are times when a test is incomplete or not valid for some reason.
At these times, TEST_IGNORE can be called. Control will immediately be
returned to the caller of the test, and no failures will be returned.
This is useful when your test runners are automatically generated.

Expand Down
33 changes: 8 additions & 25 deletions src/unity.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,22 @@ extern "C"
* 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 tearDown(void);

/* 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
* 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);
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
*-------------------------------------------------------
Expand Down
16 changes: 0 additions & 16 deletions src/unity_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,22 +372,6 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT;
#define UNITY_COUNTER_TYPE UNITY_UINT
#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
*-------------------------------------------------------*/
Expand Down