ceedling 1.1.6 → 1.1.7

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/GIT_COMMIT_SHA +1 -1
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +2 -0
  5. data/README.md +4 -1
  6. data/docs/Changelog.md +11 -0
  7. data/docs/KnownIssues.md +1 -0
  8. data/docs/mkdocs/configuration/project-file.md +25 -7
  9. data/docs/mkdocs/configuration/reference/cexception.md +1 -1
  10. data/docs/mkdocs/configuration/reference/cmock.md +1 -1
  11. data/docs/mkdocs/configuration/reference/unity.md +1 -1
  12. data/docs/mkdocs/getting-started/quick-start.md +11 -8
  13. data/docs/mkdocs/plugins/gcov/gcovr.md +324 -189
  14. data/docs/mkdocs/plugins/gcov/reportgenerator.md +113 -31
  15. data/docs/mkdocs/reference/gcov-plugin.md +21 -3
  16. data/docs/mkdocs/snapshot/plugins/gcov/config/defaults.yml +0 -1
  17. data/lib/ceedling/generators/generator_test_results_backtrace.rb +16 -8
  18. data/lib/ceedling/plugins/plugin_reportinator.rb +9 -0
  19. data/lib/ceedling/plugins/report_tests_stdout_plugin.rb +1 -1
  20. data/lib/version.rb +1 -1
  21. data/plugins/gcov/config/defaults.yml +0 -1
  22. data/plugins/gcov/lib/gcov.rb +35 -16
  23. data/plugins/gcov/lib/gcovr_reportinator.rb +31 -1
  24. data/plugins/valgrind/lib/valgrind.rb +1 -1
  25. data/site-local/configuration/project-file.html +78 -8
  26. data/site-local/configuration/reference/cexception.html +5 -5
  27. data/site-local/configuration/reference/cmock.html +5 -5
  28. data/site-local/configuration/reference/unity.html +5 -5
  29. data/site-local/getting-started/quick-start.html +13 -9
  30. data/site-local/plugins/gcov/gcovr.html +1215 -255
  31. data/site-local/plugins/gcov/reportgenerator.html +404 -46
  32. data/site-local/reference/gcov-plugin.html +40 -7
  33. data/site-local/sitemap.xml.gz +0 -0
  34. data/site-local/snapshot/plugins/gcov/config/defaults.yml +0 -1
  35. data/spec/support/system/system_context.rb +7 -3
  36. data/spec/system/deployment_as_gem_spec.rb +2 -0
  37. data/spec/system/deployment_as_vendor_spec.rb +2 -0
  38. data/spec/system/gcov_deployment_spec.rb +2 -0
  39. data/spec/system/support/common_test_cases.rb +42 -0
  40. data/spec/system/support/gcov_common_test_cases.rb +52 -0
  41. data/spec/units/generators/generator_test_results_backtrace_spec.rb +51 -0
  42. data/spec/units/plugin_reportinator_spec.rb +38 -0
  43. metadata +4 -2
@@ -90,6 +90,8 @@ ceedling_system_tests do
90
90
 
91
91
  describe "Verbosity and output" do
92
92
  test_case :test_project_with_named_verbosity
93
+ test_case :test_project_with_warnings_verbosity_prints_overall_summary
94
+ test_case :test_project_with_errors_verbosity_prints_overall_summary_on_passing_run
93
95
  test_case :test_project_with_numerical_verbosity
94
96
  test_case :report_tests_raw_output_log_plugin
95
97
  end
@@ -33,8 +33,10 @@ ceedling_system_tests do
33
33
  end
34
34
  end
35
35
 
36
+ test_case :project_with_gcov_enabled_test_all_does_not_require_gcovr
36
37
  test_case :project_with_gcov_success
37
38
  test_case :project_with_gcov_fail
39
+ test_case :project_with_gcov_fail_under_decision
38
40
  test_case :gcov_console_report_with_system_header
39
41
  test_case :gcov_console_report_with_partial
40
42
  # TODO: Restore these tests when the :abort_on_uncovered option is restored in the Gcov plugin
@@ -201,6 +201,48 @@ module CommonSystemTestCases
201
201
  end
202
202
  end
203
203
 
204
+ # The Overall Test Summary must still print at :warnings verbosity
205
+ # (`--verbosity=warnings`, Verbosity::COMPLAIN) on an all-passing run, not just
206
+ # when verbosity is :normal or higher, or when a test fails.
207
+ def test_project_with_warnings_verbosity_prints_overall_summary
208
+ @c.with_context do
209
+ Dir.chdir @proj_name do
210
+ FileUtils.cp test_asset_path("example_file.h"), 'src/'
211
+ FileUtils.cp test_asset_path("example_file.c"), 'src/'
212
+ FileUtils.cp test_asset_path("test_example_file_success.c"), 'test/'
213
+
214
+ output = @c.ceedling_build_exec("--verbosity=warnings")
215
+ expect(@c.last_exit_status).to eq(0)
216
+ expect(output).to match(/OVERALL TEST SUMMARY/)
217
+ expect(output).to match(/TESTED:\s+\d/)
218
+ expect(output).to match(/PASSED:\s+\d/)
219
+ expect(output).to match(/FAILED:\s+\d/)
220
+ expect(output).to match(/IGNORED:\s+\d/)
221
+ end
222
+ end
223
+ end
224
+
225
+ # ERRORS is the true floor for the Overall Test Summary -- a build's own
226
+ # test results are core information, visible even at the most restrictive
227
+ # verbosity short of :silent, whether the run passed or failed.
228
+ def test_project_with_errors_verbosity_prints_overall_summary_on_passing_run
229
+ @c.with_context do
230
+ Dir.chdir @proj_name do
231
+ FileUtils.cp test_asset_path("example_file.h"), 'src/'
232
+ FileUtils.cp test_asset_path("example_file.c"), 'src/'
233
+ FileUtils.cp test_asset_path("test_example_file_success.c"), 'test/'
234
+
235
+ output = @c.ceedling_build_exec("--verbosity=errors")
236
+ expect(@c.last_exit_status).to eq(0)
237
+ expect(output).to match(/OVERALL TEST SUMMARY/)
238
+ expect(output).to match(/TESTED:\s+\d/)
239
+ expect(output).to match(/PASSED:\s+\d/)
240
+ expect(output).to match(/FAILED:\s+\d/)
241
+ expect(output).to match(/IGNORED:\s+\d/)
242
+ end
243
+ end
244
+ end
245
+
204
246
  def test_project_with_numerical_verbosity
205
247
  @c.with_context do
206
248
  Dir.chdir @proj_name do
@@ -10,6 +10,38 @@ require_relative 'gcov_helpers'
10
10
  module GcovCommonTestCases
11
11
  include GcovHelpers
12
12
 
13
+ # #1252 -- Enabling the gcov plugin must not make gcovr a hard dependency of every
14
+ # build. Deliberately does NOT call prep_project_yml_for_coverage (which conditionally
15
+ # strips :utilities ➡️ gcovr when the host lacks a real gcovr) -- the point here is
16
+ # gcovr enabled in config but genuinely unreachable, reproducing #1252 regardless of
17
+ # what's actually installed on the machine running this spec.
18
+ def project_with_gcov_enabled_test_all_does_not_require_gcovr
19
+ @c.with_context do
20
+ Dir.chdir @proj_name do
21
+ @c.uncomment_project_yml_option_for_test("- gcov")
22
+ # Default :gcov ↳ :utilities already includes gcovr and :reports already
23
+ # includes HtmlBasic -- exactly the enabled-but-unused shape #1252 reported.
24
+ @c.merge_project_yml_for_test(
25
+ { :tools => { :gcov_gcovr_report => { :executable => 'nonexistent_gcovr_binary_for_1252_test' } } }
26
+ )
27
+ FileUtils.cp test_asset_path("example_file.h"), 'src/'
28
+ FileUtils.cp test_asset_path("example_file.c"), 'src/'
29
+ FileUtils.cp test_asset_path("test_example_file_success.c"), 'test/'
30
+
31
+ # An ordinary test:all run must succeed -- it never needs gcovr at all.
32
+ output = @c.ceedling_build_exec("test:all")
33
+ expect(@c.last_exit_status).to eq(0)
34
+ expect(output).to_not match(/nonexistent_gcovr_binary_for_1252_test/)
35
+
36
+ # A real gcov: build still needs gcovr and must still fail loudly when it's missing --
37
+ # the fix defers gcovr's tool validation, it doesn't remove it.
38
+ output = @c.ceedling_build_exec("gcov:all")
39
+ expect(@c.last_exit_status).to_not eq(0)
40
+ expect(output).to match(/nonexistent_gcovr_binary_for_1252_test/)
41
+ end
42
+ end
43
+ end
44
+
13
45
  def project_with_gcov_success
14
46
  @c.with_context do
15
47
  Dir.chdir @proj_name do
@@ -46,6 +78,26 @@ module GcovCommonTestCases
46
78
  end
47
79
  end
48
80
 
81
+ # gcovr's own --fail-under-decision is a no-op without --decisions also present --
82
+ # Ceedling supplies --decisions automatically whenever :fail_under_decision is
83
+ # configured, so a passing run reports success instead of gcovr's own opaque
84
+ # "need also option --decision" CLI error.
85
+ def project_with_gcov_fail_under_decision
86
+ @c.with_context do
87
+ Dir.chdir @proj_name do
88
+ prep_project_yml_for_coverage
89
+ @c.merge_project_yml_for_test( { :gcov => { :gcovr => { :fail_under_decision => 1 } } } )
90
+ FileUtils.cp test_asset_path("example_file.h"), 'src/'
91
+ FileUtils.cp test_asset_path("example_file.c"), 'src/'
92
+ FileUtils.cp test_asset_path("test_example_file_success.c"), 'test/'
93
+
94
+ output = @c.ceedling_build_exec("gcov:all")
95
+ expect(@c.last_exit_status).to eq(0)
96
+ expect(output).to_not match(/need also option --decision/)
97
+ end
98
+ end
99
+ end
100
+
49
101
  # TODO: Restore this test when the :abort_on_uncovered option is restored in the Gcov plugin
50
102
  # def project_with_gcov_fail_because_of_uncovered_files
51
103
  # @c.with_context do
@@ -130,6 +130,7 @@ SIMPLE_ASSERT_CRASH_OUTPUT =
130
130
  SIMPLE_PASS_OUTPUT = "test_lib.c:3:test_empty:PASS\n---------\n1 Tests 0 Failures 0 Ignored\nOK\n"
131
131
  SIMPLE_FAIL_OUTPUT = "test_lib.c:8:test_bad:FAIL: Expected 1 Was 2\n---------\n1 Tests 1 Failures 0 Ignored\nFAIL\n"
132
132
  SIMPLE_IGNORE_OUTPUT = "test_lib.c:12:test_skip:IGNORE\n---------\n1 Tests 0 Failures 1 Ignored\nOK\n"
133
+ SIMPLE_IGNORE_WITH_MESSAGE_OUTPUT = "test_lib.c:12:test_skip:IGNORE: Not yet implemented\n---------\n1 Tests 0 Failures 1 Ignored\nOK\n"
133
134
 
134
135
 
135
136
  describe GeneratorTestResultsBacktrace do
@@ -255,6 +256,31 @@ describe GeneratorTestResultsBacktrace do
255
256
  expect(expected_output_lines).to include('test_lib.c:9:test_asserting:FAIL: Expected 1 Was 2')
256
257
  end
257
258
 
259
+ # Ignored-crash false positive: a TEST_IGNORE_MESSAGE(...) test case carries a
260
+ # trailing message, same as FAIL. Before this fix, only FAIL tolerated one --
261
+ # a message-carrying IGNORE fell through to "unresolved" and was misreported
262
+ # as crash evidence (a second @file_wrapper.write, for a companion_case that
263
+ # never actually crashed).
264
+ it 'handles an IGNORE test case with a trailing message and does not write a log' do
265
+ allow(@tool_executor).to receive(:exec).and_return(
266
+ { output: GDB_NO_SIGNAL_OUTPUT, time: 0.1, exit_code: 1, stderr: '', status: @ok_status },
267
+ { output: "test_lib.c:9:test_asserting:IGNORE: Not yet implemented\n---------\n1 Tests 0 Failures 1 Ignored\nOK\n",
268
+ time: 0.1, exit_code: 0, stderr: '', status: @ok_status }
269
+ )
270
+
271
+ expect(@file_wrapper).to receive(:write).once.with(%r{test_crashes_elsewhere}, anything, anything)
272
+
273
+ expected_output_lines = []
274
+ allow(@generator_test_results).to receive(:regenerate_test_executable_stdout) do |**kwargs|
275
+ expected_output_lines = kwargs[:output]
276
+ 'regenerated'
277
+ end
278
+
279
+ @backtrace.do_gdb( filename, executable, shell_result, [companion_case] + test_cases, context: :test )
280
+
281
+ expect(expected_output_lines).to include('test_lib.c:9:test_asserting:IGNORE: Not yet implemented')
282
+ end
283
+
258
284
  it "does not trust a matched PASS line when the retry's own real status contradicts it" do
259
285
  # Regression test for issue #1198: a diagnostic retry can print a clean Unity
260
286
  # result line while its own real process outcome says otherwise.
@@ -471,6 +497,31 @@ describe GeneratorTestResultsBacktrace do
471
497
  expect(expected_output_lines).to include('test_lib.c:12:test_skip:IGNORE')
472
498
  end
473
499
 
500
+ # Ignored-crash false positive: a TEST_IGNORE_MESSAGE(...) test case carries a
501
+ # trailing message, same as FAIL (handled just above). Before this fix, only FAIL
502
+ # tolerated one -- a message-carrying IGNORE fell through to the "no result line"
503
+ # branch and was misreported as a second crashed test case (test_skip, alongside
504
+ # the real crash attributed to test_crashes_elsewhere).
505
+ it 'handles an IGNORE test case with a trailing message' do
506
+ test_cases_ignore = [{ test: 'test_crashes_elsewhere', line_number: 20 }, { test: 'test_skip', line_number: 12 }]
507
+
508
+ allow(@tool_executor).to receive(:exec).and_return(
509
+ { output: SIMPLE_ASSERT_CRASH_OUTPUT, time: 0.1, exit_code: 134, stderr: '', status: @ok_status },
510
+ { output: SIMPLE_IGNORE_WITH_MESSAGE_OUTPUT, time: 0.02, exit_code: 0, stderr: '', status: @ok_status }
511
+ )
512
+
513
+ expected_output_lines = []
514
+ allow(@generator_test_results).to receive(:regenerate_test_executable_stdout) do |**kwargs|
515
+ expected_output_lines = kwargs[:output]
516
+ 'regenerated'
517
+ end
518
+
519
+ @backtrace.do_simple( filename, executable, shell_result, test_cases_ignore, context: :test )
520
+
521
+ expect(expected_output_lines).to include('test_lib.c:12:test_skip:IGNORE: Not yet implemented')
522
+ expect(expected_output_lines).to_not include(a_string_matching(/test_skip:FAIL/))
523
+ end
524
+
474
525
  it "does not trust a matched PASS line when the retry's own real status contradicts it" do
475
526
  # Regression test for issue #1198: a diagnostic retry can print a clean Unity
476
527
  # result line while its own real process outcome says otherwise.
@@ -0,0 +1,38 @@
1
+ # =========================================================================
2
+ # Ceedling - Test-Centered Build System for C
3
+ # ThrowTheSwitch.org
4
+ # Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ # SPDX-License-Identifier: MIT
6
+ # =========================================================================
7
+
8
+ require 'spec_helper'
9
+ require 'ceedling/constants'
10
+ require 'ceedling/plugins/plugin_reportinator'
11
+
12
+ describe PluginReportinator do
13
+ before(:each) do
14
+ @plugin_reportinator_helper = double('plugin_reportinator_helper')
15
+ @plugin_manager = double('plugin_manager')
16
+ @reportinator = double('reportinator')
17
+ @loginator = double('loginator')
18
+
19
+ @reportinator_plugin = described_class.new(
20
+ {
21
+ :plugin_reportinator_helper => @plugin_reportinator_helper,
22
+ :plugin_manager => @plugin_manager,
23
+ :reportinator => @reportinator,
24
+ :loginator => @loginator
25
+ }
26
+ )
27
+ end
28
+
29
+ # A build's own test results -- pass or fail -- are core information a user
30
+ # silencing routine build chatter still wants to see, so every plugin that
31
+ # prints post-build test results (report_tests_stdout_plugin, gcov, valgrind)
32
+ # shares this one answer instead of each deciding independently.
33
+ describe '#test_results_floor_verbosity' do
34
+ it 'is ERRORS' do
35
+ expect( @reportinator_plugin.test_results_floor_verbosity ).to eq( Verbosity::ERRORS )
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ceedling
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark VanderVoord
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2026-08-25 00:00:00.000000000 Z
13
+ date: 2026-09-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -996,6 +996,7 @@ files:
996
996
  - spec/units/partials/partializer_spec.rb
997
997
  - spec/units/partials/partializer_utils_spec.rb
998
998
  - spec/units/plugin_manager_spec.rb
999
+ - spec/units/plugin_reportinator_spec.rb
999
1000
  - spec/units/plugins/cppcheck_spec.rb
1000
1001
  - spec/units/preprocess/c_comment_scanner_spec.rb
1001
1002
  - spec/units/preprocess/c_preprocessor_conditionals_spec.rb
@@ -1847,6 +1848,7 @@ test_files:
1847
1848
  - spec/units/partials/partializer_spec.rb
1848
1849
  - spec/units/partials/partializer_utils_spec.rb
1849
1850
  - spec/units/plugin_manager_spec.rb
1851
+ - spec/units/plugin_reportinator_spec.rb
1850
1852
  - spec/units/plugins/cppcheck_spec.rb
1851
1853
  - spec/units/preprocess/c_comment_scanner_spec.rb
1852
1854
  - spec/units/preprocess/c_preprocessor_conditionals_spec.rb