ceedling 0.28.2 → 0.28.3
Sign up to get free protection for your applications and to get access to all the features.
- 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,323 @@
|
|
1
|
+
#============================================================
|
2
|
+
# Author: John Theofanopoulos
|
3
|
+
# A simple parser. Takes the output files generated during the
|
4
|
+
# build process and extracts information relating to the tests.
|
5
|
+
#
|
6
|
+
# Notes:
|
7
|
+
# To capture an output file under VS builds use the following:
|
8
|
+
# devenv [build instructions] > Output.txt & type Output.txt
|
9
|
+
#
|
10
|
+
# To capture an output file under Linux builds use the following:
|
11
|
+
# make | tee Output.txt
|
12
|
+
#
|
13
|
+
# This script can handle the following output formats:
|
14
|
+
# - normal output (raw unity)
|
15
|
+
# - fixture output (unity_fixture.h/.c)
|
16
|
+
# - fixture output with verbose flag set ("-v")
|
17
|
+
#
|
18
|
+
# To use this parser use the following command
|
19
|
+
# ruby parseOutput.rb [options] [file]
|
20
|
+
# options: -xml : produce a JUnit compatible XML file
|
21
|
+
# file: file to scan for results
|
22
|
+
#============================================================
|
23
|
+
|
24
|
+
# Parser class for handling the input file
|
25
|
+
class ParseOutput
|
26
|
+
def initialize
|
27
|
+
# internal data
|
28
|
+
@class_name_idx = 0
|
29
|
+
@path_delim = nil
|
30
|
+
|
31
|
+
# xml output related
|
32
|
+
@xml_out = false
|
33
|
+
@array_list = false
|
34
|
+
|
35
|
+
# current suite name and statistics
|
36
|
+
@test_suite = nil
|
37
|
+
@total_tests = 0
|
38
|
+
@test_passed = 0
|
39
|
+
@test_failed = 0
|
40
|
+
@test_ignored = 0
|
41
|
+
end
|
42
|
+
|
43
|
+
# Set the flag to indicate if there will be an XML output file or not
|
44
|
+
def set_xml_output
|
45
|
+
@xml_out = true
|
46
|
+
end
|
47
|
+
|
48
|
+
# If write our output to XML
|
49
|
+
def write_xml_output
|
50
|
+
output = File.open('report.xml', 'w')
|
51
|
+
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
52
|
+
@array_list.each do |item|
|
53
|
+
output << item << "\n"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Pushes the suite info as xml to the array list, which will be written later
|
58
|
+
def push_xml_output_suite_info
|
59
|
+
# Insert opening tag at front
|
60
|
+
heading = '<testsuite name="Unity" tests="' + @total_tests.to_s + '" failures="' + @test_failed.to_s + '"' + ' skips="' + @test_ignored.to_s + '">'
|
61
|
+
@array_list.insert(0, heading)
|
62
|
+
# Push back the closing tag
|
63
|
+
@array_list.push '</testsuite>'
|
64
|
+
end
|
65
|
+
|
66
|
+
# Pushes xml output data to the array list, which will be written later
|
67
|
+
def push_xml_output_passed(test_name)
|
68
|
+
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '"/>'
|
69
|
+
end
|
70
|
+
|
71
|
+
# Pushes xml output data to the array list, which will be written later
|
72
|
+
def push_xml_output_failed(test_name, reason)
|
73
|
+
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
|
74
|
+
@array_list.push ' <failure type="ASSERT FAILED">' + reason + '</failure>'
|
75
|
+
@array_list.push ' </testcase>'
|
76
|
+
end
|
77
|
+
|
78
|
+
# Pushes xml output data to the array list, which will be written later
|
79
|
+
def push_xml_output_ignored(test_name, reason)
|
80
|
+
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
|
81
|
+
@array_list.push ' <skipped type="TEST IGNORED">' + reason + '</skipped>'
|
82
|
+
@array_list.push ' </testcase>'
|
83
|
+
end
|
84
|
+
|
85
|
+
# This function will try and determine when the suite is changed. This is
|
86
|
+
# is the name that gets added to the classname parameter.
|
87
|
+
def test_suite_verify(test_suite_name)
|
88
|
+
# Split the path name
|
89
|
+
test_name = test_suite_name.split(@path_delim)
|
90
|
+
|
91
|
+
# Remove the extension and extract the base_name
|
92
|
+
base_name = test_name[test_name.size - 1].split('.')[0]
|
93
|
+
|
94
|
+
# Return if the test suite hasn't changed
|
95
|
+
return unless base_name.to_s != @test_suite.to_s
|
96
|
+
|
97
|
+
@test_suite = base_name
|
98
|
+
printf "New Test: %s\n", @test_suite
|
99
|
+
end
|
100
|
+
|
101
|
+
# Prepares the line for verbose fixture output ("-v")
|
102
|
+
def prepare_fixture_line(line)
|
103
|
+
line = line.sub('IGNORE_TEST(', '')
|
104
|
+
line = line.sub('TEST(', '')
|
105
|
+
line = line.sub(')', ',')
|
106
|
+
line = line.chomp
|
107
|
+
array = line.split(',')
|
108
|
+
array.map { |x| x.to_s.lstrip.chomp }
|
109
|
+
end
|
110
|
+
|
111
|
+
# Test was flagged as having passed so format the output.
|
112
|
+
# This is using the Unity fixture output and not the original Unity output.
|
113
|
+
def test_passed_unity_fixture(array)
|
114
|
+
class_name = array[0]
|
115
|
+
test_name = array[1]
|
116
|
+
test_suite_verify(class_name)
|
117
|
+
printf "%-40s PASS\n", test_name
|
118
|
+
|
119
|
+
push_xml_output_passed(test_name) if @xml_out
|
120
|
+
end
|
121
|
+
|
122
|
+
# Test was flagged as having failed so format the output.
|
123
|
+
# This is using the Unity fixture output and not the original Unity output.
|
124
|
+
def test_failed_unity_fixture(array)
|
125
|
+
class_name = array[0]
|
126
|
+
test_name = array[1]
|
127
|
+
test_suite_verify(class_name)
|
128
|
+
reason_array = array[2].split(':')
|
129
|
+
reason = reason_array[-1].lstrip.chomp + ' at line: ' + reason_array[-4]
|
130
|
+
|
131
|
+
printf "%-40s FAILED\n", test_name
|
132
|
+
|
133
|
+
push_xml_output_failed(test_name, reason) if @xml_out
|
134
|
+
end
|
135
|
+
|
136
|
+
# Test was flagged as being ignored so format the output.
|
137
|
+
# This is using the Unity fixture output and not the original Unity output.
|
138
|
+
def test_ignored_unity_fixture(array)
|
139
|
+
class_name = array[0]
|
140
|
+
test_name = array[1]
|
141
|
+
reason = 'No reason given'
|
142
|
+
if array.size > 2
|
143
|
+
reason_array = array[2].split(':')
|
144
|
+
tmp_reason = reason_array[-1].lstrip.chomp
|
145
|
+
reason = tmp_reason == 'IGNORE' ? 'No reason given' : tmp_reason
|
146
|
+
end
|
147
|
+
test_suite_verify(class_name)
|
148
|
+
printf "%-40s IGNORED\n", test_name
|
149
|
+
|
150
|
+
push_xml_output_ignored(test_name, reason) if @xml_out
|
151
|
+
end
|
152
|
+
|
153
|
+
# Test was flagged as having passed so format the output
|
154
|
+
def test_passed(array)
|
155
|
+
last_item = array.length - 1
|
156
|
+
test_name = array[last_item - 1]
|
157
|
+
test_suite_verify(array[@class_name_idx])
|
158
|
+
printf "%-40s PASS\n", test_name
|
159
|
+
|
160
|
+
return unless @xml_out
|
161
|
+
|
162
|
+
push_xml_output_passed(test_name) if @xml_out
|
163
|
+
end
|
164
|
+
|
165
|
+
# Test was flagged as having failed so format the line
|
166
|
+
def test_failed(array)
|
167
|
+
last_item = array.length - 1
|
168
|
+
test_name = array[last_item - 2]
|
169
|
+
reason = array[last_item].chomp.lstrip + ' at line: ' + array[last_item - 3]
|
170
|
+
class_name = array[@class_name_idx]
|
171
|
+
|
172
|
+
if test_name.start_with? 'TEST('
|
173
|
+
array2 = test_name.split(' ')
|
174
|
+
|
175
|
+
test_suite = array2[0].sub('TEST(', '')
|
176
|
+
test_suite = test_suite.sub(',', '')
|
177
|
+
class_name = test_suite
|
178
|
+
|
179
|
+
test_name = array2[1].sub(')', '')
|
180
|
+
end
|
181
|
+
|
182
|
+
test_suite_verify(class_name)
|
183
|
+
printf "%-40s FAILED\n", test_name
|
184
|
+
|
185
|
+
push_xml_output_failed(test_name, reason) if @xml_out
|
186
|
+
end
|
187
|
+
|
188
|
+
# Test was flagged as being ignored so format the output
|
189
|
+
def test_ignored(array)
|
190
|
+
last_item = array.length - 1
|
191
|
+
test_name = array[last_item - 2]
|
192
|
+
reason = array[last_item].chomp.lstrip
|
193
|
+
class_name = array[@class_name_idx]
|
194
|
+
|
195
|
+
if test_name.start_with? 'TEST('
|
196
|
+
array2 = test_name.split(' ')
|
197
|
+
|
198
|
+
test_suite = array2[0].sub('TEST(', '')
|
199
|
+
test_suite = test_suite.sub(',', '')
|
200
|
+
class_name = test_suite
|
201
|
+
|
202
|
+
test_name = array2[1].sub(')', '')
|
203
|
+
end
|
204
|
+
|
205
|
+
test_suite_verify(class_name)
|
206
|
+
printf "%-40s IGNORED\n", test_name
|
207
|
+
|
208
|
+
push_xml_output_ignored(test_name, reason) if @xml_out
|
209
|
+
end
|
210
|
+
|
211
|
+
# Adjusts the os specific members according to the current path style
|
212
|
+
# (Windows or Unix based)
|
213
|
+
def set_os_specifics(line)
|
214
|
+
if line.include? '\\'
|
215
|
+
# Windows X:\Y\Z
|
216
|
+
@class_name_idx = 1
|
217
|
+
@path_delim = '\\'
|
218
|
+
else
|
219
|
+
# Unix Based /X/Y/Z
|
220
|
+
@class_name_idx = 0
|
221
|
+
@path_delim = '/'
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Main function used to parse the file that was captured.
|
226
|
+
def process(file_name)
|
227
|
+
@array_list = []
|
228
|
+
|
229
|
+
puts 'Parsing file: ' + file_name
|
230
|
+
|
231
|
+
@test_passed = 0
|
232
|
+
@test_failed = 0
|
233
|
+
@test_ignored = 0
|
234
|
+
puts ''
|
235
|
+
puts '=================== RESULTS ====================='
|
236
|
+
puts ''
|
237
|
+
File.open(file_name).each do |line|
|
238
|
+
# Typical test lines look like these:
|
239
|
+
# ----------------------------------------------------
|
240
|
+
# 1. normal output:
|
241
|
+
# <path>/<test_file>.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0
|
242
|
+
# <path>/<test_file>.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented
|
243
|
+
# <path>/<test_file>.c:115:test_tc5100_initCanVoidPtrs:PASS
|
244
|
+
#
|
245
|
+
# 2. fixture output
|
246
|
+
# <path>/<test_file>.c:63:TEST(<test_group>, <test_function>):FAIL: Expected 0x00001234 Was 0x00005A5A
|
247
|
+
# <path>/<test_file>.c:36:TEST(<test_group>, <test_function>):IGNORE
|
248
|
+
# Note: "PASS" information won't be generated in this mode
|
249
|
+
#
|
250
|
+
# 3. fixture output with verbose information ("-v")
|
251
|
+
# TEST(<test_group, <test_file>)<path>/<test_file>:168::FAIL: Expected 0x8D Was 0x8C
|
252
|
+
# TEST(<test_group>, <test_file>)<path>/<test_file>:22::IGNORE: This Test Was Ignored On Purpose
|
253
|
+
# IGNORE_TEST(<test_group, <test_file>)
|
254
|
+
# TEST(<test_group, <test_file>) PASS
|
255
|
+
#
|
256
|
+
# Note: Where path is different on Unix vs Windows devices (Windows leads with a drive letter)!
|
257
|
+
set_os_specifics(line)
|
258
|
+
line_array = line.split(':')
|
259
|
+
|
260
|
+
# If we were able to split the line then we can look to see if any of our target words
|
261
|
+
# were found. Case is important.
|
262
|
+
if (line_array.size >= 4) || (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(')
|
263
|
+
|
264
|
+
# check if the output is fixture output (with verbose flag "-v")
|
265
|
+
if (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(')
|
266
|
+
line_array = prepare_fixture_line(line)
|
267
|
+
if line.include? ' PASS'
|
268
|
+
test_passed_unity_fixture(line_array)
|
269
|
+
@test_passed += 1
|
270
|
+
elsif line.include? 'FAIL'
|
271
|
+
test_failed_unity_fixture(line_array)
|
272
|
+
@test_failed += 1
|
273
|
+
elsif line.include? 'IGNORE'
|
274
|
+
test_ignored_unity_fixture(line_array)
|
275
|
+
@test_ignored += 1
|
276
|
+
end
|
277
|
+
# normal output / fixture output (without verbose "-v")
|
278
|
+
elsif line.include? ':PASS'
|
279
|
+
test_passed(line_array)
|
280
|
+
@test_passed += 1
|
281
|
+
elsif line.include? ':FAIL'
|
282
|
+
test_failed(line_array)
|
283
|
+
@test_failed += 1
|
284
|
+
elsif line.include? ':IGNORE:'
|
285
|
+
test_ignored(line_array)
|
286
|
+
@test_ignored += 1
|
287
|
+
elsif line.include? ':IGNORE'
|
288
|
+
line_array.push('No reason given')
|
289
|
+
test_ignored(line_array)
|
290
|
+
@test_ignored += 1
|
291
|
+
end
|
292
|
+
@total_tests = @test_passed + @test_failed + @test_ignored
|
293
|
+
end
|
294
|
+
end
|
295
|
+
puts ''
|
296
|
+
puts '=================== SUMMARY ====================='
|
297
|
+
puts ''
|
298
|
+
puts 'Tests Passed : ' + @test_passed.to_s
|
299
|
+
puts 'Tests Failed : ' + @test_failed.to_s
|
300
|
+
puts 'Tests Ignored : ' + @test_ignored.to_s
|
301
|
+
|
302
|
+
return unless @xml_out
|
303
|
+
|
304
|
+
# push information about the suite
|
305
|
+
push_xml_output_suite_info
|
306
|
+
# write xml output file
|
307
|
+
write_xml_output
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
# If the command line has no values in, used a default value of Output.txt
|
312
|
+
parse_my_file = ParseOutput.new
|
313
|
+
|
314
|
+
if ARGV.size >= 1
|
315
|
+
ARGV.each do |arg|
|
316
|
+
if arg == '-xml'
|
317
|
+
parse_my_file.set_xml_output
|
318
|
+
else
|
319
|
+
parse_my_file.process(arg)
|
320
|
+
break
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# unity_to_junit.rb
|
4
|
+
#
|
5
|
+
require 'fileutils'
|
6
|
+
require 'optparse'
|
7
|
+
require 'ostruct'
|
8
|
+
require 'set'
|
9
|
+
|
10
|
+
require 'pp'
|
11
|
+
|
12
|
+
VERSION = 1.0
|
13
|
+
|
14
|
+
class ArgvParser
|
15
|
+
#
|
16
|
+
# Return a structure describing the options.
|
17
|
+
#
|
18
|
+
def self.parse(args)
|
19
|
+
# The options specified on the command line will be collected in *options*.
|
20
|
+
# We set default values here.
|
21
|
+
options = OpenStruct.new
|
22
|
+
options.results_dir = '.'
|
23
|
+
options.root_path = '.'
|
24
|
+
options.out_file = 'results.xml'
|
25
|
+
|
26
|
+
opts = OptionParser.new do |o|
|
27
|
+
o.banner = 'Usage: unity_to_junit.rb [options]'
|
28
|
+
|
29
|
+
o.separator ''
|
30
|
+
o.separator 'Specific options:'
|
31
|
+
|
32
|
+
o.on('-r', '--results <dir>', 'Look for Unity Results files here.') do |results|
|
33
|
+
# puts "results #{results}"
|
34
|
+
options.results_dir = results
|
35
|
+
end
|
36
|
+
|
37
|
+
o.on('-p', '--root_path <path>', 'Prepend this path to files in results.') do |root_path|
|
38
|
+
options.root_path = root_path
|
39
|
+
end
|
40
|
+
|
41
|
+
o.on('-o', '--output <filename>', 'XML file to generate.') do |out_file|
|
42
|
+
# puts "out_file: #{out_file}"
|
43
|
+
options.out_file = out_file
|
44
|
+
end
|
45
|
+
|
46
|
+
o.separator ''
|
47
|
+
o.separator 'Common options:'
|
48
|
+
|
49
|
+
# No argument, shows at tail. This will print an options summary.
|
50
|
+
o.on_tail('-h', '--help', 'Show this message') do
|
51
|
+
puts o
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
|
55
|
+
# Another typical switch to print the version.
|
56
|
+
o.on_tail('--version', 'Show version') do
|
57
|
+
puts "unity_to_junit.rb version #{VERSION}"
|
58
|
+
exit
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.parse!(args)
|
63
|
+
options
|
64
|
+
end # parse()
|
65
|
+
end # class OptparseExample
|
66
|
+
|
67
|
+
class UnityToJUnit
|
68
|
+
include FileUtils::Verbose
|
69
|
+
attr_reader :report, :total_tests, :failures, :ignored
|
70
|
+
attr_writer :targets, :root, :out_file
|
71
|
+
|
72
|
+
def initialize
|
73
|
+
@report = ''
|
74
|
+
@unit_name = ''
|
75
|
+
end
|
76
|
+
|
77
|
+
def run
|
78
|
+
# Clean up result file names
|
79
|
+
results = @targets.map { |target| target.tr('\\', '/') }
|
80
|
+
# puts "Output File: #{@out_file}"
|
81
|
+
f = File.new(@out_file, 'w')
|
82
|
+
write_xml_header(f)
|
83
|
+
write_suites_header(f)
|
84
|
+
results.each do |result_file|
|
85
|
+
lines = File.readlines(result_file).map(&:chomp)
|
86
|
+
|
87
|
+
raise "Empty test result file: #{result_file}" if lines.empty?
|
88
|
+
|
89
|
+
result_output = get_details(result_file, lines)
|
90
|
+
tests, failures, ignored = parse_test_summary(lines)
|
91
|
+
result_output[:counts][:total] = tests
|
92
|
+
result_output[:counts][:failed] = failures
|
93
|
+
result_output[:counts][:ignored] = ignored
|
94
|
+
result_output[:counts][:passed] = (result_output[:counts][:total] - result_output[:counts][:failed] - result_output[:counts][:ignored])
|
95
|
+
|
96
|
+
# use line[0] from the test output to get the test_file path and name
|
97
|
+
test_file_str = lines[0].tr('\\', '/')
|
98
|
+
test_file_str = test_file_str.split(':')
|
99
|
+
test_file = if test_file_str.length < 2
|
100
|
+
result_file
|
101
|
+
else
|
102
|
+
test_file_str[0] + ':' + test_file_str[1]
|
103
|
+
end
|
104
|
+
result_output[:source][:path] = File.dirname(test_file)
|
105
|
+
result_output[:source][:file] = File.basename(test_file)
|
106
|
+
|
107
|
+
# save result_output
|
108
|
+
@unit_name = File.basename(test_file, '.*')
|
109
|
+
|
110
|
+
write_suite_header(result_output[:counts], f)
|
111
|
+
write_failures(result_output, f)
|
112
|
+
write_tests(result_output, f)
|
113
|
+
write_ignored(result_output, f)
|
114
|
+
write_suite_footer(f)
|
115
|
+
end
|
116
|
+
write_suites_footer(f)
|
117
|
+
f.close
|
118
|
+
end
|
119
|
+
|
120
|
+
def usage(err_msg = nil)
|
121
|
+
puts "\nERROR: "
|
122
|
+
puts err_msg if err_msg
|
123
|
+
puts 'Usage: unity_to_junit.rb [options]'
|
124
|
+
puts ''
|
125
|
+
puts 'Specific options:'
|
126
|
+
puts ' -r, --results <dir> Look for Unity Results files here.'
|
127
|
+
puts ' -p, --root_path <path> Prepend this path to files in results.'
|
128
|
+
puts ' -o, --output <filename> XML file to generate.'
|
129
|
+
puts ''
|
130
|
+
puts 'Common options:'
|
131
|
+
puts ' -h, --help Show this message'
|
132
|
+
puts ' --version Show version'
|
133
|
+
|
134
|
+
exit 1
|
135
|
+
end
|
136
|
+
|
137
|
+
protected
|
138
|
+
|
139
|
+
def get_details(_result_file, lines)
|
140
|
+
results = results_structure
|
141
|
+
lines.each do |line|
|
142
|
+
line = line.tr('\\', '/')
|
143
|
+
_src_file, src_line, test_name, status, msg = line.split(/:/)
|
144
|
+
case status
|
145
|
+
when 'IGNORE' then results[:ignores] << { test: test_name, line: src_line, message: msg }
|
146
|
+
when 'FAIL' then results[:failures] << { test: test_name, line: src_line, message: msg }
|
147
|
+
when 'PASS' then results[:successes] << { test: test_name, line: src_line, message: msg }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
results
|
151
|
+
end
|
152
|
+
|
153
|
+
def parse_test_summary(summary)
|
154
|
+
raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
|
155
|
+
[Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i]
|
156
|
+
end
|
157
|
+
|
158
|
+
def here
|
159
|
+
File.expand_path(File.dirname(__FILE__))
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def results_structure
|
165
|
+
{
|
166
|
+
source: { path: '', file: '' },
|
167
|
+
successes: [],
|
168
|
+
failures: [],
|
169
|
+
ignores: [],
|
170
|
+
counts: { total: 0, passed: 0, failed: 0, ignored: 0 },
|
171
|
+
stdout: []
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
def write_xml_header(stream)
|
176
|
+
stream.puts "<?xml version='1.0' encoding='utf-8' ?>"
|
177
|
+
end
|
178
|
+
|
179
|
+
def write_suites_header(stream)
|
180
|
+
stream.puts '<testsuites>'
|
181
|
+
end
|
182
|
+
|
183
|
+
def write_suite_header(counts, stream)
|
184
|
+
stream.puts "\t<testsuite errors=\"0\" skipped=\"#{counts[:ignored]}\" failures=\"#{counts[:failed]}\" tests=\"#{counts[:total]}\" name=\"unity\">"
|
185
|
+
end
|
186
|
+
|
187
|
+
def write_failures(results, stream)
|
188
|
+
result = results[:failures]
|
189
|
+
result.each do |item|
|
190
|
+
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
|
191
|
+
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\">"
|
192
|
+
stream.puts "\t\t\t<failure message=\"#{item[:message]}\" type=\"Assertion\"/>"
|
193
|
+
stream.puts "\t\t\t<system-err>
[File] #{filename}
[Line] #{item[:line]}
</system-err>"
|
194
|
+
stream.puts "\t\t</testcase>"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def write_tests(results, stream)
|
199
|
+
result = results[:successes]
|
200
|
+
result.each do |item|
|
201
|
+
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\" />"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def write_ignored(results, stream)
|
206
|
+
result = results[:ignores]
|
207
|
+
result.each do |item|
|
208
|
+
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
|
209
|
+
puts "Writing ignored tests for test harness: #{filename}"
|
210
|
+
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\">"
|
211
|
+
stream.puts "\t\t\t<skipped message=\"#{item[:message]}\" type=\"Assertion\"/>"
|
212
|
+
stream.puts "\t\t\t<system-err>
[File] #{filename}
[Line] #{item[:line]}
</system-err>"
|
213
|
+
stream.puts "\t\t</testcase>"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def write_suite_footer(stream)
|
218
|
+
stream.puts "\t</testsuite>"
|
219
|
+
end
|
220
|
+
|
221
|
+
def write_suites_footer(stream)
|
222
|
+
stream.puts '</testsuites>'
|
223
|
+
end
|
224
|
+
end # UnityToJUnit
|
225
|
+
|
226
|
+
if __FILE__ == $0
|
227
|
+
# parse out the command options
|
228
|
+
options = ArgvParser.parse(ARGV)
|
229
|
+
|
230
|
+
# create an instance to work with
|
231
|
+
utj = UnityToJUnit.new
|
232
|
+
begin
|
233
|
+
# look in the specified or current directory for result files
|
234
|
+
targets = "#{options.results_dir.tr('\\', '/')}**/*.test*"
|
235
|
+
|
236
|
+
results = Dir[targets]
|
237
|
+
raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
|
238
|
+
utj.targets = results
|
239
|
+
|
240
|
+
# set the root path
|
241
|
+
utj.root = options.root_path
|
242
|
+
|
243
|
+
# set the output XML file name
|
244
|
+
# puts "Output File from options: #{options.out_file}"
|
245
|
+
utj.out_file = options.out_file
|
246
|
+
|
247
|
+
# run the summarizer
|
248
|
+
puts utj.run
|
249
|
+
rescue StandardError => e
|
250
|
+
utj.usage e.message
|
251
|
+
end
|
252
|
+
end
|