ceedling 0.28.2 → 0.28.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/assets/ceedling +3 -0
- data/assets/ceedling.cmd +1 -0
- data/assets/default_gitignore +5 -0
- data/assets/project_with_guts.yml +1 -0
- data/assets/project_with_guts_gcov.yml +3 -0
- data/assets/test_example_file_verbose.c +12 -0
- data/bin/ceedling +30 -6
- data/docs/CeedlingPacket.md +135 -23
- data/docs/CeedlingPacket.odt +0 -0
- data/examples/blinky/rakefile.rb +2 -1
- data/lib/ceedling/configurator.rb +7 -5
- data/lib/ceedling/configurator_builder.rb +10 -7
- data/lib/ceedling/configurator_plugins.rb +29 -24
- data/lib/ceedling/configurator_setup.rb +0 -1
- data/lib/ceedling/defaults.rb +7 -2
- data/lib/ceedling/dependinator.rb +10 -2
- data/lib/ceedling/file_finder.rb +57 -49
- data/lib/ceedling/file_path_utils.rb +12 -4
- data/lib/ceedling/file_wrapper.rb +4 -0
- data/lib/ceedling/generator.rb +4 -3
- data/lib/ceedling/generator_test_results.rb +15 -13
- data/lib/ceedling/plugin_manager.rb +18 -18
- data/lib/ceedling/plugin_reportinator.rb +3 -2
- data/lib/ceedling/plugin_reportinator_helper.rb +2 -3
- data/lib/ceedling/preprocessinator_extractor.rb +2 -2
- data/lib/ceedling/preprocessinator_includes_handler.rb +5 -0
- data/lib/ceedling/rakefile.rb +1 -0
- data/lib/ceedling/release_invoker_helper.rb +5 -2
- data/lib/ceedling/rules_release.rake +2 -1
- data/lib/ceedling/rules_tests.rake +18 -9
- data/lib/ceedling/rules_tests_deep_dependencies.rake +2 -2
- data/lib/ceedling/task_invoker.rb +15 -3
- data/lib/ceedling/tasks_vendor.rake +3 -3
- data/lib/ceedling/test_invoker.rb +39 -12
- data/lib/ceedling/test_invoker_helper.rb +5 -1
- data/lib/ceedling/tool_executor.rb +8 -4
- data/lib/ceedling/version.rb +1 -1
- data/out.fail +21 -0
- data/plugins/beep/README.md +22 -0
- data/plugins/beep/lib/beep.rb +40 -0
- data/plugins/bullseye/bullseye.rake +43 -36
- data/plugins/bullseye/config/defaults.yml +4 -0
- data/plugins/bullseye/lib/bullseye.rb +27 -5
- data/plugins/command_hooks/lib/command_hooks.rb +3 -0
- data/plugins/gcov/README.md +34 -1
- data/plugins/gcov/config/defaults.yml +3 -3
- data/plugins/gcov/gcov.rake +7 -5
- data/plugins/gcov/lib/gcov.rb +3 -1
- data/plugins/gcov/lib/gcov_constants.rb +2 -0
- data/plugins/junit_tests_report/lib/junit_tests_report.rb +12 -9
- data/plugins/module_generator/lib/module_generator.rb +14 -1
- data/plugins/module_generator/module_generator.rake +21 -4
- data/plugins/raw_output_report/lib/raw_output_report.rb +41 -0
- data/spec/gcov/gcov_deployment_spec.rb +1 -1
- data/spec/gcov/gcov_test_cases_spec.rb +2 -2
- data/spec/generator_test_results_spec.rb +5 -0
- data/spec/preprocessinator_includes_handler_spec.rb +1 -0
- data/spec/spec_system_helper.rb +178 -4
- data/spec/support/test_example.fail +1 -0
- data/spec/support/test_example.pass +1 -0
- data/spec/support/test_example_empty.pass +1 -0
- data/spec/support/test_example_ignore.pass +1 -0
- data/spec/support/test_example_mangled.pass +1 -0
- data/spec/support/test_example_with_time.pass +22 -0
- data/spec/system/deployment_spec.rb +33 -0
- data/vendor/cmock/README.md +4 -3
- data/vendor/cmock/docs/CMock_Summary.md +1 -1
- data/vendor/cmock/lib/cmock_config.rb +4 -0
- data/vendor/cmock/lib/cmock_generator.rb +5 -2
- data/vendor/cmock/lib/cmock_generator_plugin_array.rb +4 -4
- data/vendor/cmock/lib/cmock_generator_plugin_callback.rb +9 -11
- data/vendor/cmock/lib/cmock_generator_plugin_cexception.rb +0 -1
- data/vendor/cmock/lib/cmock_generator_plugin_ignore.rb +2 -3
- data/vendor/cmock/lib/cmock_generator_plugin_ignore_arg.rb +2 -4
- data/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb +0 -2
- data/vendor/cmock/lib/cmock_generator_utils.rb +16 -3
- data/vendor/cmock/lib/cmock_header_parser.rb +59 -34
- data/vendor/cmock/release/build.info +1 -1
- data/vendor/cmock/release/version.info +1 -1
- data/vendor/cmock/scripts/create_makefile.rb +17 -2
- data/vendor/cmock/src/cmock.c +13 -7
- data/vendor/cmock/test/test_helper.rb +11 -10
- data/vendor/cmock/test/unit/cmock_config_test.rb +4 -2
- data/vendor/cmock/test/unit/cmock_generator_main_test.rb +10 -4
- data/vendor/cmock/test/unit/cmock_generator_plugin_array_test.rb +20 -12
- data/vendor/cmock/test/unit/cmock_generator_plugin_expect_a_test.rb +2 -2
- data/vendor/cmock/test/unit/cmock_generator_plugin_expect_b_test.rb +2 -2
- data/vendor/cmock/test/unit/cmock_generator_plugin_ignore_arg_test.rb +3 -3
- data/vendor/cmock/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb +8 -6
- data/vendor/cmock/test/unit/cmock_generator_utils_test.rb +27 -10
- data/vendor/cmock/test/unit/cmock_header_parser_test.rb +108 -20
- data/vendor/cmock/vendor/c_exception/Gemfile +4 -0
- data/vendor/cmock/vendor/c_exception/Gemfile.lock +12 -0
- data/vendor/cmock/vendor/c_exception/LICENSE.txt +30 -0
- data/vendor/cmock/vendor/c_exception/README.md +162 -0
- data/vendor/cmock/vendor/c_exception/Rakefile +42 -0
- data/vendor/cmock/vendor/c_exception/docs/CException.md +292 -0
- data/vendor/cmock/vendor/c_exception/docs/ThrowTheSwitchCodingStandard.md +207 -0
- data/vendor/cmock/vendor/c_exception/lib/CException.c +46 -0
- data/vendor/cmock/vendor/c_exception/lib/CException.h +110 -0
- data/vendor/cmock/vendor/c_exception/makefile +24 -0
- data/vendor/cmock/vendor/c_exception/release/build.info +2 -0
- data/vendor/cmock/vendor/c_exception/release/version.info +2 -0
- data/vendor/cmock/vendor/c_exception/test/CExceptionConfig.h +46 -0
- data/vendor/cmock/vendor/c_exception/test/TestException.c +391 -0
- data/vendor/cmock/vendor/c_exception/test/TestException_Runner.c +67 -0
- data/vendor/cmock/vendor/unity/README.md +231 -0
- data/vendor/cmock/vendor/unity/auto/colour_prompt.rb +118 -0
- data/vendor/cmock/vendor/unity/auto/colour_reporter.rb +39 -0
- data/vendor/cmock/vendor/unity/auto/generate_config.yml +36 -0
- data/vendor/cmock/vendor/unity/auto/generate_module.rb +308 -0
- data/vendor/cmock/vendor/unity/auto/generate_test_runner.rb +457 -0
- data/vendor/cmock/vendor/unity/auto/parse_output.rb +323 -0
- data/vendor/cmock/vendor/unity/auto/stylize_as_junit.rb +252 -0
- data/vendor/cmock/vendor/unity/auto/test_file_filter.rb +25 -0
- data/vendor/cmock/vendor/unity/auto/type_sanitizer.rb +6 -0
- data/vendor/cmock/vendor/unity/auto/unity_test_summary.py +139 -0
- data/vendor/cmock/vendor/unity/auto/unity_test_summary.rb +136 -0
- data/vendor/cmock/vendor/unity/auto/unity_to_junit.py +146 -0
- data/vendor/cmock/vendor/unity/docs/ThrowTheSwitchCodingStandard.md +206 -0
- data/vendor/cmock/vendor/unity/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf +0 -0
- data/vendor/cmock/vendor/unity/docs/UnityAssertionsReference.md +779 -0
- data/vendor/cmock/vendor/unity/docs/UnityConfigurationGuide.md +433 -0
- data/vendor/cmock/vendor/unity/docs/UnityGettingStartedGuide.md +192 -0
- data/vendor/cmock/vendor/unity/docs/UnityHelperScriptsGuide.md +260 -0
- data/vendor/cmock/vendor/unity/docs/license.txt +21 -0
- data/vendor/cmock/vendor/unity/examples/example_1/makefile +71 -0
- data/vendor/cmock/vendor/unity/examples/example_1/readme.txt +5 -0
- data/vendor/cmock/vendor/unity/examples/example_1/src/ProductionCode.c +24 -0
- data/vendor/cmock/vendor/unity/examples/example_1/src/ProductionCode.h +3 -0
- data/vendor/cmock/vendor/unity/examples/example_1/src/ProductionCode2.c +11 -0
- data/vendor/cmock/vendor/unity/examples/example_1/src/ProductionCode2.h +2 -0
- data/vendor/cmock/vendor/unity/examples/example_1/test/TestProductionCode.c +62 -0
- data/vendor/cmock/vendor/unity/examples/example_1/test/TestProductionCode2.c +31 -0
- data/vendor/cmock/vendor/unity/examples/example_1/test/test_runners/TestProductionCode2_Runner.c +53 -0
- data/vendor/cmock/vendor/unity/examples/example_1/test/test_runners/TestProductionCode_Runner.c +57 -0
- data/vendor/cmock/vendor/unity/examples/example_2/makefile +70 -0
- data/vendor/cmock/vendor/unity/examples/example_2/readme.txt +5 -0
- data/vendor/cmock/vendor/unity/examples/example_2/src/ProductionCode.c +24 -0
- data/vendor/cmock/vendor/unity/examples/example_2/src/ProductionCode.h +3 -0
- data/vendor/cmock/vendor/unity/examples/example_2/src/ProductionCode2.c +11 -0
- data/vendor/cmock/vendor/unity/examples/example_2/src/ProductionCode2.h +2 -0
- data/vendor/cmock/vendor/unity/examples/example_2/test/TestProductionCode.c +64 -0
- data/vendor/cmock/vendor/unity/examples/example_2/test/TestProductionCode2.c +33 -0
- data/vendor/cmock/vendor/unity/examples/example_2/test/test_runners/TestProductionCode2_Runner.c +9 -0
- data/vendor/cmock/vendor/unity/examples/example_2/test/test_runners/TestProductionCode_Runner.c +11 -0
- data/vendor/cmock/vendor/unity/examples/example_2/test/test_runners/all_tests.c +12 -0
- data/vendor/cmock/vendor/unity/examples/example_3/helper/UnityHelper.c +10 -0
- data/vendor/cmock/vendor/unity/examples/example_3/helper/UnityHelper.h +12 -0
- data/vendor/cmock/vendor/unity/examples/example_3/rakefile.rb +43 -0
- data/vendor/cmock/vendor/unity/examples/example_3/rakefile_helper.rb +249 -0
- data/vendor/cmock/vendor/unity/examples/example_3/readme.txt +13 -0
- data/vendor/cmock/vendor/unity/examples/example_3/src/ProductionCode.c +24 -0
- data/vendor/cmock/vendor/unity/examples/example_3/src/ProductionCode.h +3 -0
- data/vendor/cmock/vendor/unity/examples/example_3/src/ProductionCode2.c +11 -0
- data/vendor/cmock/vendor/unity/examples/example_3/src/ProductionCode2.h +2 -0
- data/vendor/cmock/vendor/unity/examples/example_3/target_gcc_32.yml +46 -0
- data/vendor/cmock/vendor/unity/examples/example_3/test/TestProductionCode.c +62 -0
- data/vendor/cmock/vendor/unity/examples/example_3/test/TestProductionCode2.c +31 -0
- data/vendor/cmock/vendor/unity/examples/unity_config.h +247 -0
- data/vendor/cmock/vendor/unity/extras/eclipse/error_parsers.txt +26 -0
- data/vendor/cmock/vendor/unity/extras/fixture/rakefile.rb +48 -0
- data/vendor/cmock/vendor/unity/extras/fixture/rakefile_helper.rb +178 -0
- data/vendor/cmock/vendor/unity/extras/fixture/readme.txt +9 -0
- data/vendor/cmock/vendor/unity/extras/fixture/src/unity_fixture.c +436 -0
- data/vendor/cmock/vendor/unity/extras/fixture/src/unity_fixture.h +83 -0
- data/vendor/cmock/vendor/unity/extras/fixture/src/unity_fixture_internals.h +51 -0
- data/vendor/cmock/vendor/unity/extras/fixture/src/unity_fixture_malloc_overrides.h +47 -0
- data/vendor/cmock/vendor/unity/extras/fixture/test/Makefile +75 -0
- data/vendor/cmock/vendor/unity/extras/fixture/test/main/AllTests.c +22 -0
- data/vendor/cmock/vendor/unity/extras/fixture/test/template_fixture_tests.c +39 -0
- data/vendor/cmock/vendor/unity/extras/fixture/test/unity_fixture_Test.c +543 -0
- data/vendor/cmock/vendor/unity/extras/fixture/test/unity_fixture_TestRunner.c +57 -0
- data/vendor/cmock/vendor/unity/extras/fixture/test/unity_output_Spy.c +57 -0
- data/vendor/cmock/vendor/unity/extras/fixture/test/unity_output_Spy.h +17 -0
- data/vendor/cmock/vendor/unity/release/build.info +2 -0
- data/vendor/cmock/vendor/unity/release/version.info +2 -0
- data/vendor/cmock/vendor/unity/src/unity.c +1572 -0
- data/vendor/cmock/vendor/unity/src/unity.h +503 -0
- data/vendor/cmock/vendor/unity/src/unity_internals.h +924 -0
- data/vendor/cmock/vendor/unity/test/Makefile +68 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_cmd.c +61 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_def.c +57 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_head1.c +55 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_head1.h +15 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_cmd.c +80 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_def.c +76 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_head1.c +75 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_head1.h +13 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_new1.c +89 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_new2.c +89 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_param.c +77 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_run1.c +89 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_run2.c +89 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_mock_yaml.c +90 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_new1.c +67 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_new2.c +70 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_param.c +58 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_run1.c +67 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_run2.c +70 -0
- data/vendor/cmock/vendor/unity/test/expectdata/testsample_yaml.c +71 -0
- data/vendor/cmock/vendor/unity/test/rakefile +125 -0
- data/vendor/cmock/vendor/unity/test/rakefile_helper.rb +260 -0
- data/vendor/cmock/vendor/unity/test/spec/generate_module_existing_file_spec.rb +158 -0
- data/vendor/cmock/vendor/unity/test/targets/clang_file.yml +78 -0
- data/vendor/cmock/vendor/unity/test/targets/clang_strict.yml +78 -0
- data/vendor/cmock/vendor/unity/test/targets/gcc_32.yml +49 -0
- data/vendor/cmock/vendor/unity/test/targets/gcc_64.yml +50 -0
- data/vendor/cmock/vendor/unity/test/targets/gcc_auto_limits.yml +47 -0
- data/vendor/cmock/vendor/unity/test/targets/gcc_auto_stdint.yml +59 -0
- data/vendor/cmock/vendor/unity/test/targets/gcc_manual_math.yml +47 -0
- data/vendor/cmock/vendor/unity/test/targets/hitech_picc18.yml +101 -0
- data/vendor/cmock/vendor/unity/test/targets/iar_arm_v4.yml +90 -0
- data/vendor/cmock/vendor/unity/test/targets/iar_arm_v5.yml +80 -0
- data/vendor/cmock/vendor/unity/test/targets/iar_arm_v5_3.yml +80 -0
- data/vendor/cmock/vendor/unity/test/targets/iar_armcortex_LM3S9B92_v5_4.yml +94 -0
- data/vendor/cmock/vendor/unity/test/targets/iar_cortexm3_v5.yml +84 -0
- data/vendor/cmock/vendor/unity/test/targets/iar_msp430.yml +95 -0
- data/vendor/cmock/vendor/unity/test/targets/iar_sh2a_v6.yml +86 -0
- data/vendor/cmock/vendor/unity/test/testdata/CException.h +11 -0
- data/vendor/cmock/vendor/unity/test/testdata/Defs.h +8 -0
- data/vendor/cmock/vendor/unity/test/testdata/cmock.h +14 -0
- data/vendor/cmock/vendor/unity/test/testdata/mockMock.h +13 -0
- data/vendor/cmock/vendor/unity/test/testdata/testRunnerGenerator.c +186 -0
- data/vendor/cmock/vendor/unity/test/testdata/testRunnerGeneratorSmall.c +70 -0
- data/vendor/cmock/vendor/unity/test/testdata/testRunnerGeneratorWithMocks.c +195 -0
- data/vendor/cmock/vendor/unity/test/tests/test_generate_test_runner.rb +1252 -0
- data/vendor/cmock/vendor/unity/test/tests/testparameterized.c +113 -0
- data/vendor/cmock/vendor/unity/test/tests/testunity.c +5371 -0
- data/vendor/unity/auto/generate_test_runner.rb +30 -10
- data/vendor/unity/auto/parse_output.rb +212 -109
- data/vendor/unity/docs/ThrowTheSwitchCodingStandard.md +9 -10
- data/vendor/unity/docs/UnityAssertionsReference.md +11 -2
- data/vendor/unity/docs/UnityConfigurationGuide.md +90 -55
- data/vendor/unity/docs/UnityGettingStartedGuide.md +6 -5
- data/vendor/unity/docs/UnityHelperScriptsGuide.md +23 -5
- data/vendor/unity/examples/unity_config.h +8 -0
- data/vendor/unity/extras/fixture/src/unity_fixture.c +4 -0
- data/vendor/unity/extras/fixture/src/unity_fixture.h +1 -1
- data/vendor/unity/extras/fixture/src/unity_fixture_internals.h +2 -2
- data/vendor/unity/release/build.info +1 -1
- data/vendor/unity/release/version.info +1 -1
- data/vendor/unity/src/unity.c +64 -57
- data/vendor/unity/src/unity.h +111 -7
- data/vendor/unity/src/unity_internals.h +173 -73
- data/vendor/unity/test/Makefile +5 -1
- data/vendor/unity/test/testdata/testRunnerGenerator.c +4 -1
- data/vendor/unity/test/testdata/testRunnerGeneratorSmall.c +4 -1
- data/vendor/unity/test/testdata/testRunnerGeneratorWithMocks.c +4 -1
- data/vendor/unity/test/tests/testparameterized.c +5 -2
- data/vendor/unity/test/tests/testunity.c +34 -0
- metadata +150 -2
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#this is a sample configuration file for generate_module
|
|
2
|
+
#you would use it by calling generate_module with the -ygenerate_config.yml option
|
|
3
|
+
#files like this are useful for customizing generate_module to your environment
|
|
4
|
+
:generate_module:
|
|
5
|
+
:defaults:
|
|
6
|
+
#these defaults are used in place of any missing options at the command line
|
|
7
|
+
:path_src: ../src/
|
|
8
|
+
:path_inc: ../src/
|
|
9
|
+
:path_tst: ../test/
|
|
10
|
+
:update_svn: true
|
|
11
|
+
:includes:
|
|
12
|
+
#use [] for no additional includes, otherwise list the includes on separate lines
|
|
13
|
+
:src:
|
|
14
|
+
- Defs.h
|
|
15
|
+
- Board.h
|
|
16
|
+
:inc: []
|
|
17
|
+
:tst:
|
|
18
|
+
- Defs.h
|
|
19
|
+
- Board.h
|
|
20
|
+
- Exception.h
|
|
21
|
+
:boilerplates:
|
|
22
|
+
#these are inserted at the top of generated files.
|
|
23
|
+
#just comment out or remove if not desired.
|
|
24
|
+
#use %1$s where you would like the file name to appear (path/extension not included)
|
|
25
|
+
:src: |
|
|
26
|
+
//-------------------------------------------
|
|
27
|
+
// %1$s.c
|
|
28
|
+
//-------------------------------------------
|
|
29
|
+
:inc: |
|
|
30
|
+
//-------------------------------------------
|
|
31
|
+
// %1$s.h
|
|
32
|
+
//-------------------------------------------
|
|
33
|
+
:tst: |
|
|
34
|
+
//-------------------------------------------
|
|
35
|
+
// Test%1$s.c : Units tests for %1$s.c
|
|
36
|
+
//-------------------------------------------
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# ==========================================
|
|
2
|
+
# Unity Project - A Test Framework for C
|
|
3
|
+
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
|
4
|
+
# [Released under MIT License. Please refer to license.txt for details]
|
|
5
|
+
# ==========================================
|
|
6
|
+
|
|
7
|
+
# This script creates all the files with start code necessary for a new module.
|
|
8
|
+
# A simple module only requires a source file, header file, and test file.
|
|
9
|
+
# Triad modules require a source, header, and test file for each triad type (like model, conductor, and hardware).
|
|
10
|
+
|
|
11
|
+
require 'rubygems'
|
|
12
|
+
require 'fileutils'
|
|
13
|
+
require 'pathname'
|
|
14
|
+
|
|
15
|
+
# TEMPLATE_TST
|
|
16
|
+
TEMPLATE_TST ||= '#include "unity.h"
|
|
17
|
+
%2$s#include "%1$s.h"
|
|
18
|
+
|
|
19
|
+
void setUp(void)
|
|
20
|
+
{
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
void tearDown(void)
|
|
24
|
+
{
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
void test_%1$s_NeedToImplement(void)
|
|
28
|
+
{
|
|
29
|
+
TEST_IGNORE_MESSAGE("Need to Implement %1$s");
|
|
30
|
+
}
|
|
31
|
+
'.freeze
|
|
32
|
+
|
|
33
|
+
# TEMPLATE_SRC
|
|
34
|
+
TEMPLATE_SRC ||= '%2$s#include "%1$s.h"
|
|
35
|
+
'.freeze
|
|
36
|
+
|
|
37
|
+
# TEMPLATE_INC
|
|
38
|
+
TEMPLATE_INC ||= '#ifndef _%3$s_H
|
|
39
|
+
#define _%3$s_H
|
|
40
|
+
%2$s
|
|
41
|
+
|
|
42
|
+
#endif // _%3$s_H
|
|
43
|
+
'.freeze
|
|
44
|
+
|
|
45
|
+
class UnityModuleGenerator
|
|
46
|
+
############################
|
|
47
|
+
def initialize(options = nil)
|
|
48
|
+
here = File.expand_path(File.dirname(__FILE__)) + '/'
|
|
49
|
+
|
|
50
|
+
@options = UnityModuleGenerator.default_options
|
|
51
|
+
case options
|
|
52
|
+
when NilClass then @options
|
|
53
|
+
when String then @options.merge!(UnityModuleGenerator.grab_config(options))
|
|
54
|
+
when Hash then @options.merge!(options)
|
|
55
|
+
else raise 'If you specify arguments, it should be a filename or a hash of options'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Create default file paths if none were provided
|
|
59
|
+
@options[:path_src] = here + '../src/' if @options[:path_src].nil?
|
|
60
|
+
@options[:path_inc] = @options[:path_src] if @options[:path_inc].nil?
|
|
61
|
+
@options[:path_tst] = here + '../test/' if @options[:path_tst].nil?
|
|
62
|
+
@options[:path_src] += '/' unless @options[:path_src][-1] == 47
|
|
63
|
+
@options[:path_inc] += '/' unless @options[:path_inc][-1] == 47
|
|
64
|
+
@options[:path_tst] += '/' unless @options[:path_tst][-1] == 47
|
|
65
|
+
|
|
66
|
+
# Built in patterns
|
|
67
|
+
@patterns = {
|
|
68
|
+
'src' => {
|
|
69
|
+
'' => { inc: [] }
|
|
70
|
+
},
|
|
71
|
+
'test' => {
|
|
72
|
+
'' => { inc: [] }
|
|
73
|
+
},
|
|
74
|
+
'dh' => {
|
|
75
|
+
'Driver' => { inc: [create_filename('%1$s', 'Hardware.h')] },
|
|
76
|
+
'Hardware' => { inc: [] }
|
|
77
|
+
},
|
|
78
|
+
'dih' => {
|
|
79
|
+
'Driver' => { inc: [create_filename('%1$s', 'Hardware.h'), create_filename('%1$s', 'Interrupt.h')] },
|
|
80
|
+
'Interrupt' => { inc: [create_filename('%1$s', 'Hardware.h')] },
|
|
81
|
+
'Hardware' => { inc: [] }
|
|
82
|
+
},
|
|
83
|
+
'mch' => {
|
|
84
|
+
'Model' => { inc: [] },
|
|
85
|
+
'Conductor' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'Hardware.h')] },
|
|
86
|
+
'Hardware' => { inc: [] }
|
|
87
|
+
},
|
|
88
|
+
'mvp' => {
|
|
89
|
+
'Model' => { inc: [] },
|
|
90
|
+
'Presenter' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'View.h')] },
|
|
91
|
+
'View' => { inc: [] }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
############################
|
|
97
|
+
def self.default_options
|
|
98
|
+
{
|
|
99
|
+
pattern: 'src',
|
|
100
|
+
includes: {
|
|
101
|
+
src: [],
|
|
102
|
+
inc: [],
|
|
103
|
+
tst: []
|
|
104
|
+
},
|
|
105
|
+
update_svn: false,
|
|
106
|
+
boilerplates: {},
|
|
107
|
+
test_prefix: 'Test',
|
|
108
|
+
mock_prefix: 'Mock'
|
|
109
|
+
}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
############################
|
|
113
|
+
def self.grab_config(config_file)
|
|
114
|
+
options = default_options
|
|
115
|
+
unless config_file.nil? || config_file.empty?
|
|
116
|
+
require 'yaml'
|
|
117
|
+
yaml_guts = YAML.load_file(config_file)
|
|
118
|
+
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
|
|
119
|
+
raise "No :unity or :cmock section found in #{config_file}" unless options
|
|
120
|
+
end
|
|
121
|
+
options
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
############################
|
|
125
|
+
def files_to_operate_on(module_name, pattern = nil)
|
|
126
|
+
# strip any leading path information from the module name and save for later
|
|
127
|
+
subfolder = File.dirname(module_name)
|
|
128
|
+
module_name = File.basename(module_name)
|
|
129
|
+
|
|
130
|
+
# create triad definition
|
|
131
|
+
prefix = @options[:test_prefix] || 'Test'
|
|
132
|
+
triad = [{ ext: '.c', path: @options[:path_src], prefix: '', template: TEMPLATE_SRC, inc: :src, boilerplate: @options[:boilerplates][:src] },
|
|
133
|
+
{ ext: '.h', path: @options[:path_inc], prefix: '', template: TEMPLATE_INC, inc: :inc, boilerplate: @options[:boilerplates][:inc] },
|
|
134
|
+
{ ext: '.c', path: @options[:path_tst], prefix: prefix, template: TEMPLATE_TST, inc: :tst, boilerplate: @options[:boilerplates][:tst] }]
|
|
135
|
+
|
|
136
|
+
# prepare the pattern for use
|
|
137
|
+
pattern = (pattern || @options[:pattern] || 'src').downcase
|
|
138
|
+
patterns = @patterns[pattern]
|
|
139
|
+
raise "ERROR: The design pattern '#{pattern}' specified isn't one that I recognize!" if patterns.nil?
|
|
140
|
+
|
|
141
|
+
# single file patterns (currently just 'test') can reject the other parts of the triad
|
|
142
|
+
triad.select! { |v| v[:inc] == :tst } if pattern == 'test'
|
|
143
|
+
|
|
144
|
+
# Assemble the path/names of the files we need to work with.
|
|
145
|
+
files = []
|
|
146
|
+
triad.each do |cfg|
|
|
147
|
+
patterns.each_pair do |pattern_file, pattern_traits|
|
|
148
|
+
submodule_name = create_filename(module_name, pattern_file)
|
|
149
|
+
filename = cfg[:prefix] + submodule_name + cfg[:ext]
|
|
150
|
+
files << {
|
|
151
|
+
path: (Pathname.new("#{cfg[:path]}#{subfolder}") + filename).cleanpath,
|
|
152
|
+
name: submodule_name,
|
|
153
|
+
template: cfg[:template],
|
|
154
|
+
boilerplate: cfg[:boilerplate],
|
|
155
|
+
includes: case (cfg[:inc])
|
|
156
|
+
when :src then (@options[:includes][:src] || []) | (pattern_traits[:inc].map { |f| format(f, module_name) })
|
|
157
|
+
when :inc then (@options[:includes][:inc] || [])
|
|
158
|
+
when :tst then (@options[:includes][:tst] || []) | (pattern_traits[:inc].map { |f| format("#{@options[:mock_prefix]}#{f}", module_name) })
|
|
159
|
+
end
|
|
160
|
+
}
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
files
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
############################
|
|
168
|
+
def create_filename(part1, part2 = '')
|
|
169
|
+
if part2.empty?
|
|
170
|
+
case (@options[:naming])
|
|
171
|
+
when 'bumpy' then part1
|
|
172
|
+
when 'camel' then part1
|
|
173
|
+
when 'snake' then part1.downcase
|
|
174
|
+
when 'caps' then part1.upcase
|
|
175
|
+
else part1
|
|
176
|
+
end
|
|
177
|
+
else
|
|
178
|
+
case (@options[:naming])
|
|
179
|
+
when 'bumpy' then part1 + part2
|
|
180
|
+
when 'camel' then part1 + part2
|
|
181
|
+
when 'snake' then part1.downcase + '_' + part2.downcase
|
|
182
|
+
when 'caps' then part1.upcase + '_' + part2.upcase
|
|
183
|
+
else part1 + '_' + part2
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
############################
|
|
189
|
+
def generate(module_name, pattern = nil)
|
|
190
|
+
files = files_to_operate_on(module_name, pattern)
|
|
191
|
+
|
|
192
|
+
# Abort if all of the module files already exist
|
|
193
|
+
all_files_exist = true
|
|
194
|
+
files.each do |file|
|
|
195
|
+
all_files_exist = false unless File.exist?(file[:path])
|
|
196
|
+
end
|
|
197
|
+
raise "ERROR: File #{files[0][:name]} already exists. Exiting." if all_files_exist
|
|
198
|
+
|
|
199
|
+
# Create Source Modules
|
|
200
|
+
files.each_with_index do |file, _i|
|
|
201
|
+
# If this file already exists, don't overwrite it.
|
|
202
|
+
if File.exist?(file[:path])
|
|
203
|
+
puts "File #{file[:path]} already exists!"
|
|
204
|
+
next
|
|
205
|
+
end
|
|
206
|
+
# Create the path first if necessary.
|
|
207
|
+
FileUtils.mkdir_p(File.dirname(file[:path]), verbose: false)
|
|
208
|
+
File.open(file[:path], 'w') do |f|
|
|
209
|
+
f.write("#{file[:boilerplate]}\n" % [file[:name]]) unless file[:boilerplate].nil?
|
|
210
|
+
f.write(file[:template] % [file[:name],
|
|
211
|
+
file[:includes].map { |ff| "#include \"#{ff}\"\n" }.join,
|
|
212
|
+
file[:name].upcase])
|
|
213
|
+
end
|
|
214
|
+
if @options[:update_svn]
|
|
215
|
+
`svn add \"#{file[:path]}\"`
|
|
216
|
+
if $!.exitstatus.zero?
|
|
217
|
+
puts "File #{file[:path]} created and added to source control"
|
|
218
|
+
else
|
|
219
|
+
puts "File #{file[:path]} created but FAILED adding to source control!"
|
|
220
|
+
end
|
|
221
|
+
else
|
|
222
|
+
puts "File #{file[:path]} created"
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
puts 'Generate Complete'
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
############################
|
|
229
|
+
def destroy(module_name, pattern = nil)
|
|
230
|
+
files_to_operate_on(module_name, pattern).each do |filespec|
|
|
231
|
+
file = filespec[:path]
|
|
232
|
+
if File.exist?(file)
|
|
233
|
+
if @options[:update_svn]
|
|
234
|
+
`svn delete \"#{file}\" --force`
|
|
235
|
+
puts "File #{file} deleted and removed from source control"
|
|
236
|
+
else
|
|
237
|
+
FileUtils.remove(file)
|
|
238
|
+
puts "File #{file} deleted"
|
|
239
|
+
end
|
|
240
|
+
else
|
|
241
|
+
puts "File #{file} does not exist so cannot be removed."
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
puts 'Destroy Complete'
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
############################
|
|
249
|
+
# Handle As Command Line If Called That Way
|
|
250
|
+
if $0 == __FILE__
|
|
251
|
+
destroy = false
|
|
252
|
+
options = {}
|
|
253
|
+
module_name = nil
|
|
254
|
+
|
|
255
|
+
# Parse the command line parameters.
|
|
256
|
+
ARGV.each do |arg|
|
|
257
|
+
case arg
|
|
258
|
+
when /^-d/ then destroy = true
|
|
259
|
+
when /^-u/ then options[:update_svn] = true
|
|
260
|
+
when /^-p\"?(\w+)\"?/ then options[:pattern] = Regexp.last_match(1)
|
|
261
|
+
when /^-s\"?(.+)\"?/ then options[:path_src] = Regexp.last_match(1)
|
|
262
|
+
when /^-i\"?(.+)\"?/ then options[:path_inc] = Regexp.last_match(1)
|
|
263
|
+
when /^-t\"?(.+)\"?/ then options[:path_tst] = Regexp.last_match(1)
|
|
264
|
+
when /^-n\"?(.+)\"?/ then options[:naming] = Regexp.last_match(1)
|
|
265
|
+
when /^-y\"?(.+)\"?/ then options = UnityModuleGenerator.grab_config(Regexp.last_match(1))
|
|
266
|
+
when /^(\w+)/
|
|
267
|
+
raise "ERROR: You can't have more than one Module name specified!" unless module_name.nil?
|
|
268
|
+
module_name = arg
|
|
269
|
+
when /^-(h|-help)/
|
|
270
|
+
ARGV = [].freeze
|
|
271
|
+
else
|
|
272
|
+
raise "ERROR: Unknown option specified '#{arg}'"
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
unless ARGV[0]
|
|
277
|
+
puts ["\nGENERATE MODULE\n-------- ------",
|
|
278
|
+
"\nUsage: ruby generate_module [options] module_name",
|
|
279
|
+
" -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)",
|
|
280
|
+
" -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)",
|
|
281
|
+
" -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)",
|
|
282
|
+
' -p"MCH" sets the output pattern to MCH.',
|
|
283
|
+
' dh - driver hardware.',
|
|
284
|
+
' dih - driver interrupt hardware.',
|
|
285
|
+
' mch - model conductor hardware.',
|
|
286
|
+
' mvp - model view presenter.',
|
|
287
|
+
' src - just a source module, header and test. (DEFAULT)',
|
|
288
|
+
' test - just a test file.',
|
|
289
|
+
' -d destroy module instead of creating it.',
|
|
290
|
+
' -n"camel" sets the file naming convention.',
|
|
291
|
+
' bumpy - BumpyCaseFilenames.',
|
|
292
|
+
' camel - camelCaseFilenames.',
|
|
293
|
+
' snake - snake_case_filenames.',
|
|
294
|
+
' caps - CAPS_CASE_FILENAMES.',
|
|
295
|
+
' -u update subversion too (requires subversion command line)',
|
|
296
|
+
' -y"my.yml" selects a different yaml config file for module generation',
|
|
297
|
+
''].join("\n")
|
|
298
|
+
exit
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
raise 'ERROR: You must have a Module name specified! (use option -h for help)' if module_name.nil?
|
|
302
|
+
if destroy
|
|
303
|
+
UnityModuleGenerator.new(options).destroy(module_name)
|
|
304
|
+
else
|
|
305
|
+
UnityModuleGenerator.new(options).generate(module_name)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
end
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
# ==========================================
|
|
2
|
+
# Unity Project - A Test Framework for C
|
|
3
|
+
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
|
4
|
+
# [Released under MIT License. Please refer to license.txt for details]
|
|
5
|
+
# ==========================================
|
|
6
|
+
|
|
7
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'colour_prompt'))
|
|
8
|
+
|
|
9
|
+
class UnityTestRunnerGenerator
|
|
10
|
+
def initialize(options = nil)
|
|
11
|
+
@options = UnityTestRunnerGenerator.default_options
|
|
12
|
+
case options
|
|
13
|
+
when NilClass then @options
|
|
14
|
+
when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options))
|
|
15
|
+
when Hash then @options.merge!(options)
|
|
16
|
+
else raise 'If you specify arguments, it should be a filename or a hash of options'
|
|
17
|
+
end
|
|
18
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/type_sanitizer"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.default_options
|
|
22
|
+
{
|
|
23
|
+
includes: [],
|
|
24
|
+
defines: [],
|
|
25
|
+
plugins: [],
|
|
26
|
+
framework: :unity,
|
|
27
|
+
test_prefix: 'test|spec|should',
|
|
28
|
+
mock_prefix: 'Mock',
|
|
29
|
+
mock_suffix: '',
|
|
30
|
+
setup_name: 'setUp',
|
|
31
|
+
teardown_name: 'tearDown',
|
|
32
|
+
main_name: 'main', # set to :auto to automatically generate each time
|
|
33
|
+
main_export_decl: '',
|
|
34
|
+
cmdline_args: false,
|
|
35
|
+
use_param_tests: false
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.grab_config(config_file)
|
|
40
|
+
options = default_options
|
|
41
|
+
unless config_file.nil? || config_file.empty?
|
|
42
|
+
require 'yaml'
|
|
43
|
+
yaml_guts = YAML.load_file(config_file)
|
|
44
|
+
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
|
|
45
|
+
raise "No :unity or :cmock section found in #{config_file}" unless options
|
|
46
|
+
end
|
|
47
|
+
options
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def run(input_file, output_file, options = nil)
|
|
51
|
+
@options.merge!(options) unless options.nil?
|
|
52
|
+
|
|
53
|
+
# pull required data from source file
|
|
54
|
+
source = File.read(input_file)
|
|
55
|
+
source = source.force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
|
|
56
|
+
tests = find_tests(source)
|
|
57
|
+
headers = find_includes(source)
|
|
58
|
+
testfile_includes = (headers[:local] + headers[:system])
|
|
59
|
+
used_mocks = find_mocks(testfile_includes)
|
|
60
|
+
testfile_includes = (testfile_includes - used_mocks)
|
|
61
|
+
testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ }
|
|
62
|
+
|
|
63
|
+
# build runner file
|
|
64
|
+
generate(input_file, output_file, tests, used_mocks, testfile_includes)
|
|
65
|
+
|
|
66
|
+
# determine which files were used to return them
|
|
67
|
+
all_files_used = [input_file, output_file]
|
|
68
|
+
all_files_used += testfile_includes.map { |filename| filename + '.c' } unless testfile_includes.empty?
|
|
69
|
+
all_files_used += @options[:includes] unless @options[:includes].empty?
|
|
70
|
+
all_files_used += headers[:linkonly] unless headers[:linkonly].empty?
|
|
71
|
+
all_files_used.uniq
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def generate(input_file, output_file, tests, used_mocks, testfile_includes)
|
|
75
|
+
File.open(output_file, 'w') do |output|
|
|
76
|
+
create_header(output, used_mocks, testfile_includes)
|
|
77
|
+
create_externs(output, tests, used_mocks)
|
|
78
|
+
create_mock_management(output, used_mocks)
|
|
79
|
+
create_suite_setup(output)
|
|
80
|
+
create_suite_teardown(output)
|
|
81
|
+
create_reset(output, used_mocks)
|
|
82
|
+
create_main(output, input_file, tests, used_mocks)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
return unless @options[:header_file] && !@options[:header_file].empty?
|
|
86
|
+
|
|
87
|
+
File.open(@options[:header_file], 'w') do |output|
|
|
88
|
+
create_h_file(output, @options[:header_file], tests, testfile_includes, used_mocks)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def find_tests(source)
|
|
93
|
+
tests_and_line_numbers = []
|
|
94
|
+
|
|
95
|
+
source_scrubbed = source.clone
|
|
96
|
+
source_scrubbed = source_scrubbed.gsub(/"[^"\n]*"/, '') # remove things in strings
|
|
97
|
+
source_scrubbed = source_scrubbed.gsub(/\/\/.*$/, '') # remove line comments
|
|
98
|
+
source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments
|
|
99
|
+
lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line
|
|
100
|
+
| (;|\{|\}) /x) # Match ;, {, and } as end of lines
|
|
101
|
+
|
|
102
|
+
lines.each_with_index do |line, _index|
|
|
103
|
+
# find tests
|
|
104
|
+
next unless line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/
|
|
105
|
+
arguments = Regexp.last_match(1)
|
|
106
|
+
name = Regexp.last_match(2)
|
|
107
|
+
call = Regexp.last_match(3)
|
|
108
|
+
params = Regexp.last_match(4)
|
|
109
|
+
args = nil
|
|
110
|
+
if @options[:use_param_tests] && !arguments.empty?
|
|
111
|
+
args = []
|
|
112
|
+
arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) { |a| args << a[0] }
|
|
113
|
+
end
|
|
114
|
+
tests_and_line_numbers << { test: name, args: args, call: call, params: params, line_number: 0 }
|
|
115
|
+
end
|
|
116
|
+
tests_and_line_numbers.uniq! { |v| v[:test] }
|
|
117
|
+
|
|
118
|
+
# determine line numbers and create tests to run
|
|
119
|
+
source_lines = source.split("\n")
|
|
120
|
+
source_index = 0
|
|
121
|
+
tests_and_line_numbers.size.times do |i|
|
|
122
|
+
source_lines[source_index..-1].each_with_index do |line, index|
|
|
123
|
+
next unless line =~ /\s+#{tests_and_line_numbers[i][:test]}(?:\s|\()/
|
|
124
|
+
source_index += index
|
|
125
|
+
tests_and_line_numbers[i][:line_number] = source_index + 1
|
|
126
|
+
break
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
tests_and_line_numbers
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def find_includes(source)
|
|
134
|
+
# remove comments (block and line, in three steps to ensure correct precedence)
|
|
135
|
+
source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
|
|
136
|
+
source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
|
|
137
|
+
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
|
|
138
|
+
|
|
139
|
+
# parse out includes
|
|
140
|
+
includes = {
|
|
141
|
+
local: source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten,
|
|
142
|
+
system: source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" },
|
|
143
|
+
linkonly: source.scan(/^TEST_FILE\(\s*\"\s*(.+)\.[cC]\w*\s*\"/).flatten
|
|
144
|
+
}
|
|
145
|
+
includes
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def find_mocks(includes)
|
|
149
|
+
mock_headers = []
|
|
150
|
+
includes.each do |include_path|
|
|
151
|
+
include_file = File.basename(include_path)
|
|
152
|
+
mock_headers << include_path if include_file =~ /^#{@options[:mock_prefix]}.*#{@options[:mock_suffix]}$/i
|
|
153
|
+
end
|
|
154
|
+
mock_headers
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def create_header(output, mocks, testfile_includes = [])
|
|
158
|
+
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
|
|
159
|
+
create_runtest(output, mocks)
|
|
160
|
+
output.puts("\n/*=======Automagically Detected Files To Include=====*/")
|
|
161
|
+
output.puts('#ifdef __WIN32__')
|
|
162
|
+
output.puts('#define UNITY_INCLUDE_SETUP_STUBS')
|
|
163
|
+
output.puts('#endif')
|
|
164
|
+
output.puts("#include \"#{@options[:framework]}.h\"")
|
|
165
|
+
output.puts('#include "cmock.h"') unless mocks.empty?
|
|
166
|
+
output.puts('#ifndef UNITY_EXCLUDE_SETJMP_H')
|
|
167
|
+
output.puts('#include <setjmp.h>')
|
|
168
|
+
output.puts("#endif")
|
|
169
|
+
output.puts('#include <stdio.h>')
|
|
170
|
+
if @options[:defines] && !@options[:defines].empty?
|
|
171
|
+
@options[:defines].each { |d| output.puts("#define #{d}") }
|
|
172
|
+
end
|
|
173
|
+
if @options[:header_file] && !@options[:header_file].empty?
|
|
174
|
+
output.puts("#include \"#{File.basename(@options[:header_file])}\"")
|
|
175
|
+
else
|
|
176
|
+
@options[:includes].flatten.uniq.compact.each do |inc|
|
|
177
|
+
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
|
178
|
+
end
|
|
179
|
+
testfile_includes.each do |inc|
|
|
180
|
+
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
mocks.each do |mock|
|
|
184
|
+
output.puts("#include \"#{mock.gsub('.h', '')}.h\"")
|
|
185
|
+
end
|
|
186
|
+
output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception)
|
|
187
|
+
|
|
188
|
+
return unless @options[:enforce_strict_ordering]
|
|
189
|
+
|
|
190
|
+
output.puts('')
|
|
191
|
+
output.puts('int GlobalExpectCount;')
|
|
192
|
+
output.puts('int GlobalVerifyOrder;')
|
|
193
|
+
output.puts('char* GlobalOrderError;')
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def create_externs(output, tests, _mocks)
|
|
197
|
+
output.puts("\n/*=======External Functions This Runner Calls=====*/")
|
|
198
|
+
output.puts("extern void #{@options[:setup_name]}(void);")
|
|
199
|
+
output.puts("extern void #{@options[:teardown_name]}(void);")
|
|
200
|
+
tests.each do |test|
|
|
201
|
+
output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});")
|
|
202
|
+
end
|
|
203
|
+
output.puts('')
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def create_mock_management(output, mock_headers)
|
|
207
|
+
return if mock_headers.empty?
|
|
208
|
+
|
|
209
|
+
output.puts("\n/*=======Mock Management=====*/")
|
|
210
|
+
output.puts('static void CMock_Init(void)')
|
|
211
|
+
output.puts('{')
|
|
212
|
+
|
|
213
|
+
if @options[:enforce_strict_ordering]
|
|
214
|
+
output.puts(' GlobalExpectCount = 0;')
|
|
215
|
+
output.puts(' GlobalVerifyOrder = 0;')
|
|
216
|
+
output.puts(' GlobalOrderError = NULL;')
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
mocks = mock_headers.map { |mock| File.basename(mock) }
|
|
220
|
+
mocks.each do |mock|
|
|
221
|
+
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
|
222
|
+
output.puts(" #{mock_clean}_Init();")
|
|
223
|
+
end
|
|
224
|
+
output.puts("}\n")
|
|
225
|
+
|
|
226
|
+
output.puts('static void CMock_Verify(void)')
|
|
227
|
+
output.puts('{')
|
|
228
|
+
mocks.each do |mock|
|
|
229
|
+
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
|
230
|
+
output.puts(" #{mock_clean}_Verify();")
|
|
231
|
+
end
|
|
232
|
+
output.puts("}\n")
|
|
233
|
+
|
|
234
|
+
output.puts('static void CMock_Destroy(void)')
|
|
235
|
+
output.puts('{')
|
|
236
|
+
mocks.each do |mock|
|
|
237
|
+
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
|
|
238
|
+
output.puts(" #{mock_clean}_Destroy();")
|
|
239
|
+
end
|
|
240
|
+
output.puts("}\n")
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def create_suite_setup(output)
|
|
244
|
+
output.puts("\n/*=======Suite Setup=====*/")
|
|
245
|
+
output.puts('static void suite_setup(void)')
|
|
246
|
+
output.puts('{')
|
|
247
|
+
if @options[:suite_setup].nil?
|
|
248
|
+
# New style, call suiteSetUp() if we can use weak symbols
|
|
249
|
+
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
|
|
250
|
+
output.puts(' suiteSetUp();')
|
|
251
|
+
output.puts('#endif')
|
|
252
|
+
else
|
|
253
|
+
# Old style, C code embedded in the :suite_setup option
|
|
254
|
+
output.puts(@options[:suite_setup])
|
|
255
|
+
end
|
|
256
|
+
output.puts('}')
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def create_suite_teardown(output)
|
|
260
|
+
output.puts("\n/*=======Suite Teardown=====*/")
|
|
261
|
+
output.puts('static int suite_teardown(int num_failures)')
|
|
262
|
+
output.puts('{')
|
|
263
|
+
if @options[:suite_teardown].nil?
|
|
264
|
+
# New style, call suiteTearDown() if we can use weak symbols
|
|
265
|
+
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
|
|
266
|
+
output.puts(' return suiteTearDown(num_failures);')
|
|
267
|
+
output.puts('#else')
|
|
268
|
+
output.puts(' return num_failures;')
|
|
269
|
+
output.puts('#endif')
|
|
270
|
+
else
|
|
271
|
+
# Old style, C code embedded in the :suite_teardown option
|
|
272
|
+
output.puts(@options[:suite_teardown])
|
|
273
|
+
end
|
|
274
|
+
output.puts('}')
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def create_runtest(output, used_mocks)
|
|
278
|
+
cexception = @options[:plugins].include? :cexception
|
|
279
|
+
va_args1 = @options[:use_param_tests] ? ', ...' : ''
|
|
280
|
+
va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : ''
|
|
281
|
+
output.puts("\n/*=======Test Runner Used To Run Each Test Below=====*/")
|
|
282
|
+
output.puts('#define RUN_TEST_NO_ARGS') if @options[:use_param_tests]
|
|
283
|
+
output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\")
|
|
284
|
+
output.puts('{ \\')
|
|
285
|
+
output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\")
|
|
286
|
+
output.puts(' Unity.CurrentTestLineNumber = TestLineNum; \\')
|
|
287
|
+
output.puts(' if (UnityTestMatches()) { \\') if @options[:cmdline_args]
|
|
288
|
+
output.puts(' Unity.NumberOfTests++; \\')
|
|
289
|
+
output.puts(' CMock_Init(); \\') unless used_mocks.empty?
|
|
290
|
+
output.puts(' UNITY_CLR_DETAILS(); \\') unless used_mocks.empty?
|
|
291
|
+
output.puts(' if (TEST_PROTECT()) \\')
|
|
292
|
+
output.puts(' { \\')
|
|
293
|
+
output.puts(' CEXCEPTION_T e; \\') if cexception
|
|
294
|
+
output.puts(' Try { \\') if cexception
|
|
295
|
+
output.puts(" #{@options[:setup_name]}(); \\")
|
|
296
|
+
output.puts(" TestFunc(#{va_args2}); \\")
|
|
297
|
+
output.puts(' } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); } \\') if cexception
|
|
298
|
+
output.puts(' } \\')
|
|
299
|
+
output.puts(' if (TEST_PROTECT()) \\')
|
|
300
|
+
output.puts(' { \\')
|
|
301
|
+
output.puts(" #{@options[:teardown_name]}(); \\")
|
|
302
|
+
output.puts(' CMock_Verify(); \\') unless used_mocks.empty?
|
|
303
|
+
output.puts(' } \\')
|
|
304
|
+
output.puts(' CMock_Destroy(); \\') unless used_mocks.empty?
|
|
305
|
+
output.puts(' UnityConcludeTest(); \\')
|
|
306
|
+
output.puts(' } \\') if @options[:cmdline_args]
|
|
307
|
+
output.puts("}\n")
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def create_reset(output, used_mocks)
|
|
311
|
+
output.puts("\n/*=======Test Reset Option=====*/")
|
|
312
|
+
output.puts('void resetTest(void);')
|
|
313
|
+
output.puts('void resetTest(void)')
|
|
314
|
+
output.puts('{')
|
|
315
|
+
output.puts(' CMock_Verify();') unless used_mocks.empty?
|
|
316
|
+
output.puts(' CMock_Destroy();') unless used_mocks.empty?
|
|
317
|
+
output.puts(" #{@options[:teardown_name]}();")
|
|
318
|
+
output.puts(' CMock_Init();') unless used_mocks.empty?
|
|
319
|
+
output.puts(" #{@options[:setup_name]}();")
|
|
320
|
+
output.puts('}')
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def create_main(output, filename, tests, used_mocks)
|
|
324
|
+
output.puts("\n\n/*=======MAIN=====*/")
|
|
325
|
+
main_name = @options[:main_name].to_sym == :auto ? "main_#{filename.gsub('.c', '')}" : (@options[:main_name]).to_s
|
|
326
|
+
if @options[:cmdline_args]
|
|
327
|
+
if main_name != 'main'
|
|
328
|
+
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv);")
|
|
329
|
+
end
|
|
330
|
+
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv)")
|
|
331
|
+
output.puts('{')
|
|
332
|
+
output.puts(' int parse_status = UnityParseOptions(argc, argv);')
|
|
333
|
+
output.puts(' if (parse_status != 0)')
|
|
334
|
+
output.puts(' {')
|
|
335
|
+
output.puts(' if (parse_status < 0)')
|
|
336
|
+
output.puts(' {')
|
|
337
|
+
output.puts(" UnityPrint(\"#{filename.gsub('.c', '')}.\");")
|
|
338
|
+
output.puts(' UNITY_PRINT_EOL();')
|
|
339
|
+
if @options[:use_param_tests]
|
|
340
|
+
tests.each do |test|
|
|
341
|
+
if test[:args].nil? || test[:args].empty?
|
|
342
|
+
output.puts(" UnityPrint(\" #{test[:test]}(RUN_TEST_NO_ARGS)\");")
|
|
343
|
+
output.puts(' UNITY_PRINT_EOL();')
|
|
344
|
+
else
|
|
345
|
+
test[:args].each do |args|
|
|
346
|
+
output.puts(" UnityPrint(\" #{test[:test]}(#{args})\");")
|
|
347
|
+
output.puts(' UNITY_PRINT_EOL();')
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
else
|
|
352
|
+
tests.each { |test| output.puts(" UnityPrint(\" #{test[:test]}\");\n UNITY_PRINT_EOL();") }
|
|
353
|
+
end
|
|
354
|
+
output.puts(' return 0;')
|
|
355
|
+
output.puts(' }')
|
|
356
|
+
output.puts(' return parse_status;')
|
|
357
|
+
output.puts(' }')
|
|
358
|
+
else
|
|
359
|
+
if main_name != 'main'
|
|
360
|
+
output.puts("#{@options[:main_export_decl]} int #{main_name}(void);")
|
|
361
|
+
end
|
|
362
|
+
output.puts("int #{main_name}(void)")
|
|
363
|
+
output.puts('{')
|
|
364
|
+
end
|
|
365
|
+
output.puts(' suite_setup();')
|
|
366
|
+
output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
|
|
367
|
+
if @options[:use_param_tests]
|
|
368
|
+
tests.each do |test|
|
|
369
|
+
if test[:args].nil? || test[:args].empty?
|
|
370
|
+
output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);")
|
|
371
|
+
else
|
|
372
|
+
test[:args].each { |args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});") }
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
else
|
|
376
|
+
tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") }
|
|
377
|
+
end
|
|
378
|
+
output.puts
|
|
379
|
+
output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty?
|
|
380
|
+
output.puts(" return suite_teardown(UnityEnd());")
|
|
381
|
+
output.puts('}')
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def create_h_file(output, filename, tests, testfile_includes, used_mocks)
|
|
385
|
+
filename = File.basename(filename).gsub(/[-\/\\\.\,\s]/, '_').upcase
|
|
386
|
+
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
|
|
387
|
+
output.puts("#ifndef _#{filename}")
|
|
388
|
+
output.puts("#define _#{filename}\n\n")
|
|
389
|
+
output.puts("#include \"#{@options[:framework]}.h\"")
|
|
390
|
+
output.puts('#include "cmock.h"') unless used_mocks.empty?
|
|
391
|
+
@options[:includes].flatten.uniq.compact.each do |inc|
|
|
392
|
+
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
|
393
|
+
end
|
|
394
|
+
testfile_includes.each do |inc|
|
|
395
|
+
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
|
|
396
|
+
end
|
|
397
|
+
output.puts "\n"
|
|
398
|
+
tests.each do |test|
|
|
399
|
+
if test[:params].nil? || test[:params].empty?
|
|
400
|
+
output.puts("void #{test[:test]}(void);")
|
|
401
|
+
else
|
|
402
|
+
output.puts("void #{test[:test]}(#{test[:params]});")
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
output.puts("#endif\n\n")
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
if $0 == __FILE__
|
|
410
|
+
options = { includes: [] }
|
|
411
|
+
|
|
412
|
+
# parse out all the options first (these will all be removed as we go)
|
|
413
|
+
ARGV.reject! do |arg|
|
|
414
|
+
case arg
|
|
415
|
+
when '-cexception'
|
|
416
|
+
options[:plugins] = [:cexception]
|
|
417
|
+
true
|
|
418
|
+
when /\.*\.ya?ml/
|
|
419
|
+
options = UnityTestRunnerGenerator.grab_config(arg)
|
|
420
|
+
true
|
|
421
|
+
when /--(\w+)=\"?(.*)\"?/
|
|
422
|
+
options[Regexp.last_match(1).to_sym] = Regexp.last_match(2)
|
|
423
|
+
true
|
|
424
|
+
when /\.*\.h/
|
|
425
|
+
options[:includes] << arg
|
|
426
|
+
true
|
|
427
|
+
else false
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
# make sure there is at least one parameter left (the input file)
|
|
432
|
+
unless ARGV[0]
|
|
433
|
+
puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)",
|
|
434
|
+
"\n input_test_file - this is the C file you want to create a runner for",
|
|
435
|
+
' output - this is the name of the runner file to generate',
|
|
436
|
+
' defaults to (input_test_file)_Runner',
|
|
437
|
+
' files:',
|
|
438
|
+
' *.yml / *.yaml - loads configuration from here in :unity or :cmock',
|
|
439
|
+
' *.h - header files are added as #includes in runner',
|
|
440
|
+
' options:',
|
|
441
|
+
' -cexception - include cexception support',
|
|
442
|
+
' --setup_name="" - redefine setUp func name to something else',
|
|
443
|
+
' --teardown_name="" - redefine tearDown func name to something else',
|
|
444
|
+
' --main_name="" - redefine main func name to something else',
|
|
445
|
+
' --test_prefix="" - redefine test prefix from default test|spec|should',
|
|
446
|
+
' --suite_setup="" - code to execute for setup of entire suite',
|
|
447
|
+
' --suite_teardown="" - code to execute for teardown of entire suite',
|
|
448
|
+
' --use_param_tests=1 - enable parameterized tests (disabled by default)',
|
|
449
|
+
' --header_file="" - path/name of test header file to generate too'].join("\n")
|
|
450
|
+
exit 1
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
# create the default test runner name if not specified
|
|
454
|
+
ARGV[1] = ARGV[0].gsub('.c', '_Runner.c') unless ARGV[1]
|
|
455
|
+
|
|
456
|
+
UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1])
|
|
457
|
+
end
|