ceedling 1.1.10 → 1.2.1

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 (1145) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +3 -0
  3. data/.simplecov +73 -0
  4. data/GIT_COMMIT_SHA +1 -1
  5. data/Gemfile +84 -8
  6. data/Gemfile.lock +38 -8
  7. data/README.md +64 -45
  8. data/Rakefile +769 -16
  9. data/assets/{project.yml → features/project.yml} +4 -1
  10. data/assets/fixtures/bullseye_branch_coverage/src/branchy.c +24 -0
  11. data/assets/fixtures/bullseye_branch_coverage/src/branchy.h +14 -0
  12. data/assets/fixtures/bullseye_branch_coverage/test/test_branchy.c +18 -0
  13. data/assets/fixtures/cppcheck_findings/findings.c +23 -0
  14. data/assets/fixtures/cppcheck_findings/findings.h +13 -0
  15. data/assets/fixtures/header_include_path_validation/alt_drivers/foo.h +6 -0
  16. data/assets/fixtures/header_include_path_validation/bar.h +6 -0
  17. data/assets/fixtures/header_include_path_validation/drivers/foo.h +6 -0
  18. data/assets/fixtures/header_include_path_validation/dup.h +6 -0
  19. data/assets/fixtures/header_include_path_validation/other_inc/dup.h +6 -0
  20. data/assets/fixtures/header_include_path_validation/test_ambiguous_mock.c +15 -0
  21. data/assets/fixtures/header_include_path_validation/test_bare_mock.c +11 -0
  22. data/assets/fixtures/header_include_path_validation/test_bogus_mock_path.c +11 -0
  23. data/assets/fixtures/header_include_path_validation/test_bogus_vanilla_path.c +10 -0
  24. data/assets/fixtures/header_include_path_validation/test_include_outranks_test_include_path.c +16 -0
  25. data/assets/fixtures/header_include_path_validation/test_pathed_mock.c +11 -0
  26. data/assets/fixtures/header_include_path_validation/test_pathed_mock_ambiguous.c +14 -0
  27. data/assets/fixtures/header_include_path_validation/test_test_include_path_outranks_include.c +17 -0
  28. data/assets/fixtures/implicit_source_header_correspondence/alpha/dup.c +6 -0
  29. data/assets/fixtures/implicit_source_header_correspondence/alpha/dup.h +6 -0
  30. data/assets/fixtures/implicit_source_header_correspondence/beta/dup.c +6 -0
  31. data/assets/fixtures/implicit_source_header_correspondence/beta/dup.h +6 -0
  32. data/assets/fixtures/implicit_source_header_correspondence/gamma/dup_gamma.c +6 -0
  33. data/assets/fixtures/implicit_source_header_correspondence/test_dup_alpha.c +10 -0
  34. data/assets/fixtures/implicit_source_header_correspondence/test_dup_bare.c +10 -0
  35. data/assets/fixtures/implicit_source_header_correspondence/test_dup_beta.c +10 -0
  36. data/assets/fixtures/implicit_source_header_correspondence/test_dup_override.c +19 -0
  37. data/assets/fixtures/implicit_source_header_correspondence/test_dup_subtractive.c +19 -0
  38. data/assets/fixtures/implicit_source_header_correspondence/test_dup_subtractive_noop.c +16 -0
  39. data/assets/fixtures/parent_directory_references/alpha/extra.c +4 -0
  40. data/assets/fixtures/parent_directory_references/common/helper.c +6 -0
  41. data/assets/fixtures/parent_directory_references/common/helper.h +6 -0
  42. data/assets/fixtures/parent_directory_references/unit/test_dotdot_include.c +10 -0
  43. data/assets/fixtures/parent_directory_references/unit/test_dotdot_source.c +16 -0
  44. data/assets/fixtures/plain_inline_module.h +9 -0
  45. data/assets/fixtures/same_named_modules/include/drivers/spi/config.h +6 -0
  46. data/assets/fixtures/same_named_modules/include/drivers/uart/config.h +6 -0
  47. data/assets/fixtures/same_named_modules/src/drivers/spi/config.c +8 -0
  48. data/assets/fixtures/same_named_modules/src/drivers/uart/config.c +10 -0
  49. data/assets/fixtures/same_named_modules/test/test_both_configs.c +26 -0
  50. data/assets/fixtures/same_named_modules/test/test_both_configs_mocked.c +20 -0
  51. data/assets/fixtures/same_named_modules/test/test_both_configs_mocked_traditional.c +19 -0
  52. data/assets/fixtures/same_named_modules/test/test_both_modules.c +19 -0
  53. data/assets/fixtures/same_named_modules/test/test_uart_config_bare.c +19 -0
  54. data/assets/fixtures/same_named_modules/test/test_uart_config_partial_only.c +20 -0
  55. data/assets/fixtures/sources_with_duplicate_basenames/baz/bar.c +6 -0
  56. data/assets/fixtures/sources_with_duplicate_basenames/baz/bar.h +6 -0
  57. data/assets/fixtures/sources_with_duplicate_basenames/foo/bar.c +6 -0
  58. data/assets/fixtures/sources_with_duplicate_basenames/foo/bar.h +6 -0
  59. data/assets/fixtures/sources_with_duplicate_basenames/main.c +11 -0
  60. data/assets/fixtures/sources_with_duplicate_basenames/test_baz_bar.c +10 -0
  61. data/assets/fixtures/sources_with_duplicate_basenames/test_both_bars.c +12 -0
  62. data/assets/fixtures/sources_with_duplicate_basenames/test_foo_bar.c +10 -0
  63. data/assets/{test_example_file_boom.c → fixtures/test_nosanitize_boom.c} +9 -0
  64. data/assets/{test_example_file_crash_assert.c → fixtures/test_nosanitize_crash_assert.c} +8 -0
  65. data/assets/{test_example_file_crash_sigsegv.c → fixtures/test_nosanitize_crash_sigsegv.c} +8 -0
  66. data/assets/{test_example_file_crash_sigsegv_with_param.c → fixtures/test_nosanitize_crash_sigsegv_with_param.c} +8 -0
  67. data/assets/fixtures/test_nosanitize_heap_buffer_overflow.c +31 -0
  68. data/assets/fixtures/test_nosanitize_leak.c +34 -0
  69. data/assets/fixtures/test_nosanitize_two_findings.c +36 -0
  70. data/assets/{test_example_file_ub_shift_overflow.c → fixtures/test_nosanitize_ub_shift_overflow.c} +9 -0
  71. data/assets/fixtures/test_plain_inline_module.c +15 -0
  72. data/assets/fixtures/test_source_file_duplicate_basenames/alpha/calc.c +4 -0
  73. data/assets/fixtures/test_source_file_duplicate_basenames/beta/calc.c +4 -0
  74. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_alpha.c +15 -0
  75. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_ambiguous.c +15 -0
  76. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_beta.c +15 -0
  77. data/assets/fixtures/tests_with_conditional_includes/src/feature_extra2.h +13 -0
  78. data/assets/fixtures/tests_with_conditional_includes/src/macro_target_extra.h +13 -0
  79. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget.c +19 -3
  80. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget.h +1 -0
  81. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget_feature.c +17 -1
  82. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/test/test_widget.c +12 -4
  83. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/test/test_widget_feature.c +8 -5
  84. data/assets/fixtures/tests_with_conditional_mocks/src/Case_01.c +7 -0
  85. data/assets/fixtures/tests_with_conditional_mocks/src/Case_01.h +6 -0
  86. data/assets/fixtures/tests_with_conditional_mocks/src/Case_02.c +16 -0
  87. data/assets/fixtures/tests_with_conditional_mocks/src/Case_02.h +6 -0
  88. data/assets/fixtures/tests_with_conditional_mocks/src/FeatureConfig.h +6 -0
  89. data/assets/fixtures/tests_with_conditional_mocks/src/Gpt.h +6 -0
  90. data/assets/fixtures/tests_with_conditional_mocks/src/MyModuleConfig.h +17 -0
  91. data/assets/fixtures/tests_with_conditional_mocks/src/MyModulePart1.h +6 -0
  92. data/assets/fixtures/tests_with_conditional_mocks/src/MyModulePart2.h +6 -0
  93. data/assets/fixtures/tests_with_conditional_mocks/src/drivers/widget.h +6 -0
  94. data/assets/fixtures/tests_with_conditional_mocks/src/reader.c +7 -0
  95. data/assets/fixtures/tests_with_conditional_mocks/src/reader.h +6 -0
  96. data/assets/fixtures/tests_with_conditional_mocks/test/test_Case_01.c +21 -0
  97. data/assets/fixtures/tests_with_conditional_mocks/test/test_Case_01_legacy.c +16 -0
  98. data/assets/fixtures/tests_with_conditional_mocks/test/test_Case_02.c +31 -0
  99. data/assets/fixtures/tests_with_conditional_mocks/test/test_FeatureConfig.c +15 -0
  100. data/assets/fixtures/tests_with_conditional_mocks/test/test_reader.c +13 -0
  101. data/assets/fixtures/tests_with_duplicate_test_names/integration/test_foo.c +21 -0
  102. data/assets/fixtures/tests_with_duplicate_test_names/unit/test_foo.c +21 -0
  103. data/assets/fixtures/tests_with_fallback_conditionals/src/conditional_module.c +28 -0
  104. data/assets/{tests_with_fallback_conditionals → fixtures/tests_with_fallback_conditionals}/test/test_conditionals.c +8 -1
  105. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/asm_helper_lower.s +2 -0
  106. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/asm_helper_upper.S +13 -0
  107. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/counter_module.c +13 -0
  108. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/counter_module.h +13 -0
  109. data/assets/fixtures/tests_with_multiple_assembly_extensions/test/test_counter_module.c +27 -0
  110. data/assets/fixtures/tests_with_subdir_includes/src/module/app/config.h +13 -0
  111. data/assets/fixtures/tests_with_subdir_includes/src/module/drivers/config.h +13 -0
  112. data/assets/fixtures/tests_with_subdir_includes/src/module/sensor.c +30 -0
  113. data/assets/fixtures/tests_with_subdir_includes/src/module/sensor.h +13 -0
  114. data/assets/fixtures/tests_with_subdir_includes/src/shared/config.h +13 -0
  115. data/assets/fixtures/tests_with_subdir_includes/test/test_sensor.c +32 -0
  116. data/bin/actionator.rb +234 -0
  117. data/bin/app_cfg.rb +28 -0
  118. data/bin/cli.rb +78 -47
  119. data/bin/cli_handler.rb +96 -58
  120. data/bin/cli_helper.rb +95 -49
  121. data/bin/cli_options_transform.rb +22 -0
  122. data/bin/{configinator.rb → composinator.rb} +39 -32
  123. data/bin/mixin_resolvinator.rb +124 -0
  124. data/bin/mixin_standardizer.rb +31 -61
  125. data/bin/mixinator.rb +27 -29
  126. data/bin/mixins.rb +0 -5
  127. data/bin/objects.yml +20 -7
  128. data/bin/path_validator.rb +6 -5
  129. data/bin/projectinator.rb +51 -142
  130. data/bin/rake_patches.rb +36 -2
  131. data/bin/recursive_merger.rb +7 -1
  132. data/bin/versionator.rb +2 -3
  133. data/ceedling.gemspec +83 -12
  134. data/docs/BreakingChanges.md +46 -2
  135. data/docs/CONTRIBUTING.md +45 -29
  136. data/docs/CeedlingPullRequestChecklist.md +10 -9
  137. data/docs/Changelog.md +337 -37
  138. data/docs/KnownIssues.md +30 -4
  139. data/docs/ReleaseNotes.md +288 -12
  140. data/docs/SECURITY.md +46 -2
  141. data/docs/ThrowTheSwitchCodingStandard.md +21 -3
  142. data/docs/overrides/main.html +35 -0
  143. data/examples/temp_sensor/mixin/add_bullseye.yml +19 -0
  144. data/examples/wondrous_forest/README.md +3 -0
  145. data/examples/wondrous_forest/src/sensors/light/Calibration.c +21 -0
  146. data/examples/wondrous_forest/src/sensors/light/Calibration.h +14 -0
  147. data/examples/wondrous_forest/src/sensors/soil/Calibration.c +23 -0
  148. data/examples/wondrous_forest/src/sensors/soil/Calibration.h +14 -0
  149. data/examples/wondrous_forest/test/TestCalibration.c +39 -0
  150. data/lib/ceedling/batchinator.rb +81 -22
  151. data/lib/ceedling/c_extractor/README.md +61 -0
  152. data/lib/ceedling/c_extractor/c_extractor.rb +33 -2
  153. data/lib/ceedling/c_extractor/c_extractor_code_text.rb +18 -10
  154. data/lib/ceedling/c_extractor/c_extractor_constants.rb +10 -10
  155. data/lib/ceedling/c_extractor/c_extractor_declarations.rb +14 -14
  156. data/lib/ceedling/c_extractor/c_extractor_functions.rb +10 -13
  157. data/lib/ceedling/c_extractor/c_extractor_preprocessing.rb +77 -0
  158. data/lib/ceedling/c_extractor/c_extractor_types.rb +8 -5
  159. data/lib/ceedling/ceedling.h +33 -0
  160. data/lib/ceedling/config/config_matchinator.rb +36 -13
  161. data/lib/ceedling/config/configurator.rb +370 -531
  162. data/lib/ceedling/config/configurator_builder.rb +253 -365
  163. data/lib/ceedling/config/configurator_plugins.rb +68 -102
  164. data/lib/ceedling/config/configurator_setup.rb +360 -616
  165. data/lib/ceedling/config/configurator_validator.rb +114 -142
  166. data/lib/ceedling/config/line_marker_suppressors.rb +67 -0
  167. data/lib/ceedling/constants.rb +60 -6
  168. data/lib/ceedling/defaults.rb +28 -14
  169. data/lib/ceedling/defineinator.rb +9 -4
  170. data/lib/ceedling/dependencies/README.md +69 -0
  171. data/lib/ceedling/dependencies/dependency_cache_store.rb +160 -0
  172. data/lib/ceedling/dependencies/dependency_debug_tree.rb +129 -0
  173. data/lib/ceedling/dependencies/dependency_differ.rb +127 -0
  174. data/lib/ceedling/dependencies/dependency_hasher.rb +94 -0
  175. data/lib/ceedling/dependencies/dependency_path_normalizer.rb +80 -0
  176. data/lib/ceedling/dependencies/dependency_tracker.rb +405 -0
  177. data/lib/ceedling/dependencies/dependinator.rb +65 -0
  178. data/lib/ceedling/dependencies/gcc_dependency_parser.rb +86 -0
  179. data/lib/ceedling/encodinator.rb +23 -11
  180. data/lib/ceedling/file_finder.rb +373 -89
  181. data/lib/ceedling/file_finder_helper.rb +44 -33
  182. data/lib/ceedling/file_path_collection_utils.rb +17 -4
  183. data/lib/ceedling/file_path_utils.rb +310 -52
  184. data/lib/ceedling/file_wrapper.rb +275 -8
  185. data/lib/ceedling/filename_extension.rb +91 -0
  186. data/lib/ceedling/flaginator.rb +6 -2
  187. data/lib/ceedling/generators/generator.rb +192 -70
  188. data/lib/ceedling/generators/generator_helper.rb +116 -69
  189. data/lib/ceedling/generators/generator_mocks.rb +13 -8
  190. data/lib/ceedling/generators/generator_partials.rb +47 -15
  191. data/lib/ceedling/generators/generator_test_results.rb +29 -17
  192. data/lib/ceedling/generators/generator_test_results_backtrace.rb +199 -107
  193. data/lib/ceedling/generators/generator_test_results_sanity_checker.rb +1 -1
  194. data/lib/ceedling/includes/include_factory.rb +21 -6
  195. data/lib/ceedling/includes/include_pathinator.rb +40 -4
  196. data/lib/ceedling/includes/includes.rb +215 -61
  197. data/lib/ceedling/loginator.rb +13 -4
  198. data/lib/ceedling/objects.yml +216 -33
  199. data/lib/ceedling/parsing_parcels.rb +39 -13
  200. data/lib/ceedling/partials/README.md +53 -0
  201. data/lib/ceedling/partials/partializer.rb +118 -26
  202. data/lib/ceedling/partials/partializer_config.rb +141 -8
  203. data/lib/ceedling/partials/partializer_helper.rb +88 -2
  204. data/lib/ceedling/partials/partializer_utils.rb +1 -1
  205. data/lib/ceedling/partials/partials.rb +4 -4
  206. data/lib/ceedling/path_matcher.rb +163 -0
  207. data/lib/ceedling/path_mirror.rb +73 -0
  208. data/lib/ceedling/plugins/plugin.rb +1 -1
  209. data/lib/ceedling/plugins/plugin_manager.rb +31 -15
  210. data/lib/ceedling/plugins/plugin_manager_helper.rb +5 -1
  211. data/lib/ceedling/plugins/plugin_reportinator.rb +36 -7
  212. data/lib/ceedling/plugins/plugin_reportinator_helper.rb +3 -3
  213. data/lib/ceedling/plugins/report_log_writer_plugin.rb +66 -0
  214. data/lib/ceedling/plugins/report_tests_stdout_plugin.rb +18 -5
  215. data/lib/ceedling/preprocess/README.md +135 -120
  216. data/lib/ceedling/preprocess/c_comment_scanner.rb +9 -7
  217. data/lib/ceedling/preprocess/c_preprocessor_conditionals.rb +27 -10
  218. data/lib/ceedling/preprocess/preprocessinator.rb +253 -217
  219. data/lib/ceedling/preprocess/preprocessinator_bare_includes_extractor.rb +7 -10
  220. data/lib/ceedling/preprocess/preprocessinator_code_finder.rb +8 -6
  221. data/lib/ceedling/preprocess/preprocessinator_comment_stripper.rb +5 -3
  222. data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +86 -82
  223. data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +182 -163
  224. data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +174 -8
  225. data/lib/ceedling/preprocess/preprocessinator_reconstructor.rb +41 -20
  226. data/lib/ceedling/quote_include_isolator.rb +129 -0
  227. data/lib/ceedling/rake_app/rake_task_registry.rb +9 -9
  228. data/lib/ceedling/rake_app/rake_wrapper.rb +0 -13
  229. data/lib/ceedling/rake_app/rakefile_component_resolver.rb +24 -12
  230. data/lib/ceedling/rake_app/test_task_name.rb +29 -0
  231. data/lib/ceedling/rakefile.rb +3 -1
  232. data/lib/ceedling/{tasks_base.rake → rakefiles/base/tasks_base.rake} +1 -1
  233. data/lib/ceedling/{tasks_filesystem.rake → rakefiles/base/tasks_filesystem.rake} +3 -0
  234. data/lib/ceedling/rakefiles/release/rules_release.rake +52 -0
  235. data/lib/ceedling/{erb_wrapper.rb → rakefiles/release/tasks_release.rake} +5 -8
  236. data/lib/ceedling/{rules_tests.rake → rakefiles/tests/rules_tests.rake} +4 -18
  237. data/lib/ceedling/rakefiles/tests/rules_tests_generate.rake +54 -0
  238. data/lib/ceedling/{tasks_tests.rake → rakefiles/tests/tasks_tests.rake} +11 -20
  239. data/lib/ceedling/rakefiles/tests/tasks_tests_generate.rake +55 -0
  240. data/lib/ceedling/release_invoker/README.md +35 -0
  241. data/lib/ceedling/release_invoker/release_build_executor.rb +263 -0
  242. data/lib/ceedling/release_invoker/release_build_planner.rb +80 -0
  243. data/lib/ceedling/release_invoker/release_invoker.rb +78 -0
  244. data/lib/ceedling/release_invoker/release_invoker_types.rb +40 -0
  245. data/lib/ceedling/reportinator.rb +18 -2
  246. data/lib/ceedling/ruby_expandinator.rb +40 -1
  247. data/lib/ceedling/setupinator.rb +13 -3
  248. data/lib/ceedling/system_wrapper.rb +17 -0
  249. data/lib/ceedling/templateinator.rb +146 -0
  250. data/lib/ceedling/test_context_extractor.rb +59 -28
  251. data/lib/ceedling/test_invoker/HEADER_COLLISIONS.md +41 -0
  252. data/lib/ceedling/test_invoker/PIPELINE.md +142 -0
  253. data/lib/ceedling/test_invoker/README.md +6 -0
  254. data/lib/ceedling/test_invoker/mock_locator.rb +49 -0
  255. data/lib/ceedling/test_invoker/partials_manager.rb +426 -0
  256. data/lib/ceedling/test_invoker/standin_headerinator.rb +136 -0
  257. data/lib/ceedling/test_invoker/test_bare_includes_extractinator.rb +117 -0
  258. data/lib/ceedling/test_invoker/test_build_executor.rb +800 -429
  259. data/lib/ceedling/test_invoker/test_build_planner.rb +175 -70
  260. data/lib/ceedling/test_invoker/test_build_setup.rb +132 -241
  261. data/lib/ceedling/test_invoker/test_build_validations.rb +102 -0
  262. data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +148 -0
  263. data/lib/ceedling/test_invoker/test_includes_extractinator.rb +34 -0
  264. data/lib/ceedling/test_invoker/test_includes_preprocessinator.rb +118 -0
  265. data/lib/ceedling/test_invoker/test_includes_reconcilinator.rb +149 -0
  266. data/lib/ceedling/test_invoker/test_invoker.rb +16 -183
  267. data/lib/ceedling/test_invoker/test_invoker_types.rb +85 -16
  268. data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +121 -0
  269. data/lib/ceedling/test_invoker/test_pipeline_manager.rb +303 -0
  270. data/lib/ceedling/test_invoker/test_runner_generatinator.rb +105 -0
  271. data/lib/ceedling/test_invoker/test_search_paths.rb +73 -0
  272. data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +78 -0
  273. data/lib/ceedling/tool_executor.rb +42 -13
  274. data/lib/ceedling/tool_executor_helper.rb +1 -1
  275. data/lib/ceedling/tool_validator.rb +124 -123
  276. data/lib/ceedling/yaml_wrapper.rb +5 -3
  277. data/lib/version.rb +19 -2
  278. data/mkdocs.prerelease.yml +42 -0
  279. data/mkdocs.yml +10 -2
  280. data/plugins/bullseye/bullseye.rake +71 -111
  281. data/plugins/bullseye/config/defaults.yml +12 -54
  282. data/plugins/bullseye/config/defaults_bullseye.rb +182 -0
  283. data/plugins/bullseye/lib/bullseye.rb +511 -120
  284. data/plugins/bullseye/lib/bullseye_constants.rb +100 -0
  285. data/plugins/command_hooks/lib/command_hooks.rb +117 -199
  286. data/plugins/compile_commands_json_db/lib/compile_commands_json_db.rb +72 -27
  287. data/plugins/cppcheck/config/defaults.yml +6 -1
  288. data/plugins/cppcheck/config/defaults_cppcheck.rb +5 -1
  289. data/plugins/cppcheck/cppcheck.rake +7 -1
  290. data/plugins/cppcheck/lib/cppcheck.rb +175 -26
  291. data/plugins/cppcheck/lib/cppcheck_constants.rb +12 -0
  292. data/plugins/cppcheck/lib/cppcheck_reports.rb +5 -1
  293. data/plugins/dependencies/Rakefile +14 -2
  294. data/plugins/dependencies/config/defaults.yml +9 -6
  295. data/plugins/dependencies/dependencies.rake +46 -76
  296. data/plugins/dependencies/example/boss/project.yml +1 -1
  297. data/plugins/dependencies/example/supervisor/project.yml +1 -1
  298. data/plugins/dependencies/example/version.tar.gzip +0 -0
  299. data/plugins/dependencies/lib/dependencies.rb +232 -427
  300. data/plugins/dependencies/lib/dependency_commands.rb +72 -0
  301. data/plugins/dependencies/lib/dependency_environment.rb +57 -0
  302. data/plugins/dependencies/lib/dependency_spec.rb +145 -0
  303. data/plugins/fff/.rspec +1 -0
  304. data/plugins/fff/Rakefile +14 -2
  305. data/plugins/fff/examples/fff_example/project.yml +1 -1
  306. data/plugins/fff/lib/fff.rb +30 -9
  307. data/plugins/fff/lib/fff_mock_generator.rb +142 -128
  308. data/plugins/fff/spec/fff_mock_header_generator_spec.rb +15 -0
  309. data/plugins/fff/spec/fff_mock_source_generator_spec.rb +14 -0
  310. data/plugins/fff/spec/spec_helper.rb +45 -0
  311. data/plugins/fff/src/fff_unity_helper.h +5 -0
  312. data/plugins/fff/vendor/fff/fakegen.rb +5 -4
  313. data/plugins/fff/vendor/fff/fff.h +4 -4
  314. data/plugins/gcov/config/defaults.yml +5 -0
  315. data/plugins/gcov/gcov.rake +16 -15
  316. data/plugins/gcov/lib/console_reportinator.rb +140 -20
  317. data/plugins/gcov/lib/gcov.rb +155 -60
  318. data/plugins/gcov/lib/gcov_constants.rb +4 -7
  319. data/plugins/gcov/lib/gcov_reportinator.rb +90 -0
  320. data/plugins/gcov/lib/gcov_types.rb +62 -1
  321. data/plugins/gcov/lib/gcovr_reportinator.rb +255 -213
  322. data/plugins/gcov/lib/reportgenerator_reportinator.rb +122 -44
  323. data/plugins/module_generator/Rakefile +4 -4
  324. data/plugins/module_generator/config/module_generator.yml +0 -1
  325. data/plugins/module_generator/example/project.yml +1 -1
  326. data/plugins/module_generator/lib/module_generator.rb +117 -87
  327. data/plugins/module_generator/lib/module_generator_options.rb +150 -0
  328. data/plugins/module_generator/lib/module_generator_project.rb +45 -0
  329. data/plugins/module_generator/lib/module_generator_request.rb +83 -0
  330. data/plugins/module_generator/lib/module_generator_test_file.rb +68 -0
  331. data/plugins/module_generator/lib/module_generator_unity.rb +24 -0
  332. data/plugins/module_generator/module_generator.rake +24 -46
  333. data/plugins/report_build_warnings_log/config/defaults.yml +4 -1
  334. data/plugins/report_build_warnings_log/lib/report_build_warnings_log.rb +47 -55
  335. data/plugins/report_build_warnings_log/lib/warning_collector.rb +140 -0
  336. data/plugins/report_build_warnings_log/lib/warning_reports.rb +135 -0
  337. data/plugins/report_tests_gtestlike_stdout/assets/test_results.template +3 -0
  338. data/{spec/units/configurator_builder_spec.rb → plugins/report_tests_gtestlike_stdout/config/defaults.yml} +6 -10
  339. data/plugins/report_tests_gtestlike_stdout/lib/gtestlike_report.rb +168 -0
  340. data/plugins/report_tests_gtestlike_stdout/lib/report_tests_gtestlike_stdout.rb +25 -1
  341. data/plugins/report_tests_ide_stdout/assets/test_results.template +50 -0
  342. data/plugins/report_tests_ide_stdout/config/defaults.yml +13 -0
  343. data/plugins/report_tests_ide_stdout/lib/ide_report_lines.rb +103 -0
  344. data/plugins/report_tests_ide_stdout/lib/report_tests_ide_stdout.rb +12 -4
  345. data/plugins/report_tests_log_factory/lib/cppunit_tests_reporter.rb +33 -51
  346. data/plugins/report_tests_log_factory/lib/html_tests_reporter.rb +286 -295
  347. data/plugins/report_tests_log_factory/lib/json_tests_reporter.rb +22 -35
  348. data/plugins/report_tests_log_factory/lib/junit_tests_reporter.rb +91 -133
  349. data/plugins/report_tests_log_factory/lib/report_tests_log_factory.rb +72 -86
  350. data/plugins/report_tests_log_factory/lib/tests_reporter.rb +31 -12
  351. data/plugins/report_tests_pretty_stdout/assets/{template.erb → test_results.template} +8 -8
  352. data/plugins/report_tests_raw_output_log/lib/report_tests_raw_output_log.rb +18 -48
  353. data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +13 -2
  354. data/plugins/sanitize/config/defaults.yml +44 -0
  355. data/plugins/sanitize/config/defaults_sanitize.rb +20 -0
  356. data/plugins/sanitize/lib/sanitize.rb +174 -0
  357. data/plugins/sanitize/lib/sanitize_config.rb +110 -0
  358. data/plugins/sanitize/lib/sanitize_constants.rb +13 -0
  359. data/plugins/sanitize/lib/sanitize_findings.rb +85 -0
  360. data/plugins/sanitize/lib/sanitize_records.rb +115 -0
  361. data/plugins/sanitize/lib/sanitize_reports.rb +135 -0
  362. data/plugins/sanitize/sanitize.rake +108 -0
  363. data/plugins/valgrind/config/defaults.yml +7 -1
  364. data/plugins/valgrind/config/defaults_valgrind.rb +6 -1
  365. data/plugins/valgrind/lib/valgrind.rb +202 -39
  366. data/plugins/valgrind/lib/valgrind_constants.rb +4 -0
  367. data/plugins/valgrind/lib/valgrind_report.rb +52 -0
  368. data/plugins/valgrind/valgrind.rake +37 -15
  369. data/site-local/404.html +239 -19
  370. data/site-local/assets/javascripts/{bundle.d7400e89.min.js → bundle.c21346df.min.js} +3 -3
  371. data/site-local/assets/javascripts/{bundle.d7400e89.min.js.map → bundle.c21346df.min.js.map} +2 -2
  372. data/site-local/assets/javascripts/workers/{search.2c215733.min.js → search.a7633da7.min.js} +2 -2
  373. data/site-local/assets/javascripts/workers/{search.2c215733.min.js.map → search.a7633da7.min.js.map} +1 -1
  374. data/site-local/assets/stylesheets/main.57a0d79d.min.css +6 -0
  375. data/site-local/assets/stylesheets/main.57a0d79d.min.css.map +1 -0
  376. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css +4 -0
  377. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css.map +1 -0
  378. data/site-local/configuration/environment-vars.html +239 -19
  379. data/site-local/configuration/global-collections.html +239 -24
  380. data/site-local/configuration/index.html +240 -20
  381. data/site-local/configuration/loading.html +251 -27
  382. data/site-local/configuration/mixins.html +247 -26
  383. data/site-local/configuration/parallel-builds.html +239 -19
  384. data/site-local/configuration/project-file.html +268 -37
  385. data/site-local/configuration/reference/cexception.html +246 -25
  386. data/site-local/configuration/reference/cmock.html +272 -19
  387. data/site-local/configuration/reference/defines.html +263 -34
  388. data/site-local/configuration/reference/environment.html +246 -26
  389. data/site-local/configuration/reference/extension.html +352 -21
  390. data/site-local/configuration/reference/files.html +258 -24
  391. data/site-local/configuration/reference/flags.html +268 -31
  392. data/site-local/configuration/reference/index.html +239 -19
  393. data/site-local/configuration/reference/libraries.html +239 -19
  394. data/site-local/configuration/reference/mixins.html +239 -19
  395. data/site-local/configuration/reference/partials.html +240 -24
  396. data/site-local/configuration/reference/paths.html +269 -23
  397. data/site-local/configuration/reference/plugins.html +239 -19
  398. data/site-local/configuration/reference/project.html +292 -29
  399. data/site-local/configuration/reference/release-build.html +247 -19
  400. data/site-local/configuration/reference/test-build.html +281 -29
  401. data/site-local/configuration/reference/test-runner.html +279 -22
  402. data/site-local/configuration/reference/tools.html +257 -31
  403. data/site-local/configuration/reference/unity.html +271 -20
  404. data/site-local/configuration/which-ceedling.html +239 -19
  405. data/site-local/development/index.html +245 -19
  406. data/site-local/development/plugins/configuration.html +260 -22
  407. data/site-local/development/plugins/index.html +258 -20
  408. data/site-local/development/plugins/plugin-subclass.html +912 -174
  409. data/site-local/development/plugins/rake-tasks.html +269 -21
  410. data/site-local/development/releases.html +4759 -0
  411. data/site-local/development/workflow.html +1023 -58
  412. data/site-local/getting-started/builds.html +4593 -0
  413. data/site-local/getting-started/command-line.html +409 -39
  414. data/site-local/getting-started/example-projects/cipher-quest.html +239 -19
  415. data/site-local/getting-started/example-projects/index.html +240 -20
  416. data/site-local/getting-started/example-projects/temp-sensor.html +239 -19
  417. data/site-local/getting-started/example-projects/wondrous-forest.html +239 -19
  418. data/site-local/getting-started/index.html +246 -19
  419. data/site-local/getting-started/installation.html +249 -27
  420. data/site-local/getting-started/quick-start.html +242 -20
  421. data/site-local/help.html +246 -19
  422. data/site-local/index.html +284 -27
  423. data/site-local/overview/build-system.html +240 -20
  424. data/site-local/overview/index.html +239 -19
  425. data/site-local/overview/test-environments.html +248 -19
  426. data/site-local/overview/tools-and-frameworks.html +239 -19
  427. data/site-local/plugins/beep.html +242 -19
  428. data/site-local/plugins/bullseye/index.html +5068 -0
  429. data/site-local/plugins/bullseye/licensing.html +4826 -0
  430. data/site-local/plugins/command-hooks.html +258 -34
  431. data/site-local/plugins/compile-commands-json-db.html +247 -22
  432. data/site-local/plugins/cppcheck.html +1073 -268
  433. data/site-local/plugins/dependencies.html +927 -249
  434. data/site-local/plugins/fff.html +288 -21
  435. data/site-local/plugins/gcov/examples.html +243 -20
  436. data/site-local/plugins/gcov/gcovr.html +559 -71
  437. data/site-local/plugins/gcov/index.html +242 -19
  438. data/site-local/plugins/gcov/overview.html +253 -23
  439. data/site-local/plugins/gcov/reportgenerator.html +380 -46
  440. data/site-local/plugins/gcov/reporting.html +339 -105
  441. data/site-local/plugins/gcov/setup.html +244 -20
  442. data/site-local/plugins/gcov/tool-versions.html +292 -24
  443. data/site-local/plugins/gcov/troubleshooting.html +265 -42
  444. data/site-local/plugins/index.html +285 -41
  445. data/site-local/plugins/module-generator.html +770 -200
  446. data/site-local/plugins/report-build-warnings-log.html +569 -38
  447. data/site-local/plugins/report-tests-gtestlike-stdout.html +458 -89
  448. data/site-local/plugins/report-tests-ide-stdout.html +645 -56
  449. data/site-local/plugins/report-tests-log-factory.html +364 -111
  450. data/site-local/plugins/report-tests-pretty-stdout.html +243 -20
  451. data/site-local/plugins/report-tests-raw-output-log.html +242 -19
  452. data/site-local/plugins/report-tests-teamcity-stdout.html +252 -29
  453. data/site-local/plugins/sanitize.html +5322 -0
  454. data/site-local/plugins/valgrind.html +414 -34
  455. data/site-local/{plugins/bullseye.html → project/index.html} +288 -222
  456. data/site-local/project/release-history.html +242 -22
  457. data/site-local/project/sbom.html +4712 -0
  458. data/site-local/project/upgrade.html +241 -21
  459. data/site-local/reference/build-directives.html +248 -19
  460. data/site-local/reference/command-line.html +364 -21
  461. data/site-local/reference/environment-vars.html +239 -19
  462. data/site-local/reference/gcov-plugin.html +483 -23
  463. data/site-local/reference/global-collections.html +240 -20
  464. data/site-local/reference/index.html +239 -19
  465. data/site-local/reference/partials-macros.html +249 -19
  466. data/site-local/reference/project-configuration.html +239 -19
  467. data/site-local/sitemap.xml.gz +0 -0
  468. data/{docs/mkdocs/snapshot/assets → site-local/snapshot/assets/features}/project.yml +4 -1
  469. data/site-local/snapshot/examples/cipher_quest/index.html +249 -29
  470. data/site-local/snapshot/examples/temp_sensor/index.html +241 -21
  471. data/site-local/snapshot/examples/wondrous_forest/index.html +256 -30
  472. data/site-local/snapshot/plugins/bullseye/config/defaults.yml +24 -0
  473. data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +182 -0
  474. data/site-local/snapshot/plugins/gcov/config/defaults.yml +5 -0
  475. data/site-local/testing-guide/build-directives.html +331 -35
  476. data/site-local/testing-guide/conventions.html +671 -160
  477. data/site-local/testing-guide/frameworks.html +244 -24
  478. data/site-local/testing-guide/index.html +239 -26
  479. data/site-local/testing-guide/partials/configuration.html +241 -21
  480. data/site-local/testing-guide/partials/conventions.html +308 -23
  481. data/site-local/testing-guide/partials/directives.html +452 -58
  482. data/site-local/testing-guide/partials/example.html +247 -27
  483. data/site-local/testing-guide/partials/index.html +246 -19
  484. data/site-local/testing-guide/partials/overview.html +239 -19
  485. data/site-local/testing-guide/partials/variables.html +244 -24
  486. data/site-local/testing-guide/test-cases.html +246 -26
  487. data/site-local/testing-guide/test-sample.html +245 -25
  488. data/site-local/testing-guide/test-suite-anatomy.html +239 -19
  489. data/spec/integration/actionator_file_operations_spec.rb +287 -0
  490. data/spec/integration/analysis_tool_output_spec.rb +204 -0
  491. data/spec/{units/c_extractor/c_extractor_integration_spec.rb → integration/c_extractor_composition_spec.rb} +196 -17
  492. data/spec/integration/command_hooks_plugin_spec.rb +152 -0
  493. data/spec/integration/compile_commands_json_db_spec.rb +76 -0
  494. data/spec/integration/configurator_pipeline_spec.rb +190 -0
  495. data/spec/integration/configurator_plugins_spec.rb +122 -0
  496. data/spec/integration/configurator_validation_spec.rb +98 -0
  497. data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +396 -0
  498. data/spec/integration/dependencies/dependency_tracker_core_spec.rb +284 -0
  499. data/spec/integration/dependencies/dependency_tracker_diagnose_spec.rb +224 -0
  500. data/spec/integration/dependencies/dependency_tracker_filename_handling_spec.rb +118 -0
  501. data/spec/integration/dependencies/dependency_tracker_gcc_deps_spec.rb +199 -0
  502. data/spec/integration/dependencies/dependency_tracker_pruning_spec.rb +167 -0
  503. data/spec/integration/dependencies_plugin_spec.rb +473 -0
  504. data/spec/integration/erb_dependency_removed_spec.rb +167 -0
  505. data/spec/integration/includes_extraction_spec.rb +612 -0
  506. data/spec/integration/mixin_loading_spec.rb +414 -0
  507. data/spec/integration/module_generator_spec.rb +436 -0
  508. data/spec/integration/partials_fallback_preprocessing_spec.rb +316 -0
  509. data/spec/integration/partials_header_composition_spec.rb +889 -0
  510. data/spec/integration/partials_module_resolution_spec.rb +372 -0
  511. data/spec/integration/partials_symbol_linkage_spec.rb +371 -0
  512. data/spec/integration/preprocessing_transient_io_retry_spec.rb +135 -0
  513. data/spec/integration/quote_include_isolator_spec.rb +167 -0
  514. data/spec/integration/rake_task_registry_plugins_spec.rb +95 -0
  515. data/spec/integration/report_build_warnings_log_spec.rb +170 -0
  516. data/spec/integration/report_tests_log_factory_spec.rb +100 -0
  517. data/spec/integration/sanitizer_exclusions_spec.rb +126 -0
  518. data/spec/integration/system_harness_sanitizers_spec.rb +104 -0
  519. data/spec/integration/test_build_parallel_barrier_spec.rb +89 -0
  520. data/spec/integration/test_executable_manifest_spec.rb +118 -0
  521. data/spec/integration/test_includes_extractinator_spec.rb +293 -0
  522. data/spec/integration/tool_executor_spec.rb +224 -0
  523. data/spec/integration/tool_validator_spec.rb +133 -0
  524. data/spec/integration/vendor_copy_transient_io_retry_spec.rb +178 -0
  525. data/spec/manual/stress_test.rb +1 -1
  526. data/spec/support/config_yaml_helper.rb +17 -0
  527. data/spec/support/fixtures/sanitizer_reports/clang_asan_heap.txt +45 -0
  528. data/spec/support/fixtures/sanitizer_reports/clang_ubsan_shift.txt +5 -0
  529. data/spec/support/fixtures/sanitizer_reports/gcc_heap.txt +47 -0
  530. data/spec/support/fixtures/sanitizer_reports/gcc_leak.txt +10 -0
  531. data/spec/support/fixtures/sanitizer_reports/gcc_segv.txt +6 -0
  532. data/spec/support/fixtures/sanitizer_reports/gcc_ubsan_shift.txt +6 -0
  533. data/spec/support/fixtures/templates/bullseye__all_pass.txt +6 -0
  534. data/spec/support/fixtures/templates/bullseye__coverage_branches_only.txt +6 -0
  535. data/spec/support/fixtures/templates/bullseye__coverage_functions_only.txt +6 -0
  536. data/spec/support/fixtures/templates/bullseye__coverage_none.txt +6 -0
  537. data/spec/support/fixtures/templates/bullseye__empty.txt +6 -0
  538. data/spec/support/fixtures/templates/bullseye__gcov_context.txt +6 -0
  539. data/spec/support/fixtures/templates/bullseye__mixed_all.txt +6 -0
  540. data/spec/support/fixtures/templates/bullseye__one_failure_matching.txt +6 -0
  541. data/spec/support/fixtures/templates/bullseye__one_failure_multiline.txt +6 -0
  542. data/spec/support/fixtures/templates/bullseye__one_failure_no_message.txt +6 -0
  543. data/spec/support/fixtures/templates/bullseye__one_failure_nonmatching.txt +6 -0
  544. data/spec/support/fixtures/templates/bullseye__one_ignore_no_message.txt +6 -0
  545. data/spec/support/fixtures/templates/bullseye__one_ignore_with_message.txt +6 -0
  546. data/spec/support/fixtures/templates/bullseye__stdout_only.txt +6 -0
  547. data/spec/support/fixtures/templates/ide__all_pass.txt +10 -0
  548. data/spec/support/fixtures/templates/ide__coverage_branches_only.txt +10 -0
  549. data/spec/support/fixtures/templates/ide__coverage_functions_only.txt +10 -0
  550. data/spec/support/fixtures/templates/ide__coverage_none.txt +10 -0
  551. data/spec/support/fixtures/templates/ide__empty.txt +8 -0
  552. data/spec/support/fixtures/templates/ide__gcov_context.txt +28 -0
  553. data/spec/support/fixtures/templates/ide__mixed_all.txt +29 -0
  554. data/spec/support/fixtures/templates/ide__one_failure_matching.txt +15 -0
  555. data/spec/support/fixtures/templates/ide__one_failure_multiline.txt +17 -0
  556. data/spec/support/fixtures/templates/ide__one_failure_no_message.txt +15 -0
  557. data/spec/support/fixtures/templates/ide__one_failure_nonmatching.txt +15 -0
  558. data/spec/support/fixtures/templates/ide__one_ignore_no_message.txt +15 -0
  559. data/spec/support/fixtures/templates/ide__one_ignore_with_message.txt +15 -0
  560. data/spec/support/fixtures/templates/ide__stdout_only.txt +16 -0
  561. data/spec/support/fixtures/templates/pretty__all_pass.txt +8 -0
  562. data/spec/support/fixtures/templates/pretty__coverage_branches_only.txt +8 -0
  563. data/spec/support/fixtures/templates/pretty__coverage_functions_only.txt +8 -0
  564. data/spec/support/fixtures/templates/pretty__coverage_none.txt +8 -0
  565. data/spec/support/fixtures/templates/pretty__empty.txt +6 -0
  566. data/spec/support/fixtures/templates/pretty__gcov_context.txt +31 -0
  567. data/spec/support/fixtures/templates/pretty__mixed_all.txt +35 -0
  568. data/spec/support/fixtures/templates/pretty__one_failure_matching.txt +15 -0
  569. data/spec/support/fixtures/templates/pretty__one_failure_multiline.txt +17 -0
  570. data/spec/support/fixtures/templates/pretty__one_failure_no_message.txt +15 -0
  571. data/spec/support/fixtures/templates/pretty__one_failure_nonmatching.txt +15 -0
  572. data/spec/support/fixtures/templates/pretty__one_ignore_no_message.txt +15 -0
  573. data/spec/support/fixtures/templates/pretty__one_ignore_with_message.txt +15 -0
  574. data/spec/support/fixtures/templates/pretty__stdout_only.txt +15 -0
  575. data/spec/support/fixtures/valgrind_reports/sigsegv.log +51 -0
  576. data/spec/support/fixtures/valgrind_reports/sigsegv.xml +182 -0
  577. data/spec/support/include_guard_helper.rb +20 -0
  578. data/spec/support/integration/configurator_integration_helper.rb +162 -0
  579. data/spec/support/integration/dependency_tracker_integration_helper.rb +136 -0
  580. data/spec/support/integration/partials_generation_integration_helper.rb +726 -0
  581. data/spec/support/integration/spec_integration_helper.rb +285 -0
  582. data/spec/support/integration/test_includes_harness.rb +259 -0
  583. data/spec/support/integration/tool_executor_integration_helper.rb +55 -0
  584. data/spec/support/spec_helper.rb +41 -0
  585. data/spec/support/system/sanitizers/asan_ubsan.yml +82 -0
  586. data/spec/support/system/sanitizers/asan_ubsan_leaks.yml +57 -0
  587. data/spec/support/system/simplecov_boot.rb +66 -0
  588. data/spec/support/system/spec_system_helper.rb +376 -16
  589. data/spec/support/system/system_context.rb +181 -59
  590. data/spec/support/template_render_cases.rb +166 -0
  591. data/spec/system/bracket_path_handling_spec.rb +175 -0
  592. data/spec/system/build_output_mirroring_spec.rb +89 -0
  593. data/spec/system/build_recovery_spec.rb +382 -0
  594. data/spec/system/bullseye_deployment_spec.rb +102 -0
  595. data/spec/system/cli_surface_spec.rb +245 -0
  596. data/spec/system/command_hooks_spec.rb +117 -0
  597. data/spec/system/conditional_include_macro_visibility_spec.rb +32 -124
  598. data/spec/system/conditional_mock_includes_spec.rb +181 -0
  599. data/spec/system/cppcheck_deployment_spec.rb +26 -8
  600. data/spec/system/delta_builds_spec.rb +751 -0
  601. data/spec/system/deployment_as_gem_spec.rb +7 -0
  602. data/spec/system/deployment_as_vendor_spec.rb +29 -145
  603. data/spec/system/dumpconfig_spec.rb +137 -0
  604. data/spec/system/encoding_stress_spec.rb +7 -4
  605. data/spec/system/example_cipher_quest_spec.rb +25 -100
  606. data/spec/system/example_temp_sensor_spec.rb +30 -172
  607. data/spec/system/example_wondrous_forest_spec.rb +25 -62
  608. data/spec/system/extension_multiple_values_spec.rb +75 -0
  609. data/spec/system/files_paths_reporting_spec.rb +154 -0
  610. data/spec/system/gcov_deployment_spec.rb +72 -3
  611. data/spec/system/header_include_path_validation_spec.rb +222 -0
  612. data/spec/system/implicit_source_header_correspondence_disambiguation_spec.rb +100 -0
  613. data/spec/system/include_path_reconciliation_spec.rb +64 -0
  614. data/spec/system/mixin_ordering_spec.rb +30 -415
  615. data/spec/system/mocks_partials_configuration_validation_spec.rb +126 -0
  616. data/spec/system/parent_directory_reference_spec.rb +114 -0
  617. data/spec/system/partials_module_disambiguation_spec.rb +143 -0
  618. data/spec/system/pinned_thread_count_spec.rb +102 -0
  619. data/spec/system/plugin_delta_builds_spec.rb +179 -0
  620. data/spec/system/preprocessing_encoding_spec.rb +87 -4
  621. data/spec/system/preprocessing_fallback_conditionals_spec.rb +19 -25
  622. data/spec/system/preprocessing_parameterized_tests_spec.rb +2 -2
  623. data/spec/system/rake_release_task_path_disambiguation_spec.rb +97 -0
  624. data/spec/system/rake_test_task_path_disambiguation_spec.rb +118 -0
  625. data/spec/system/report_and_tooling_plugins_spec.rb +327 -0
  626. data/spec/system/ruby_replacement_spec.rb +1 -1
  627. data/spec/system/same_named_modules_spec.rb +115 -0
  628. data/spec/system/sanitize_deployment_spec.rb +64 -0
  629. data/spec/system/shuffle_tests_spec.rb +139 -0
  630. data/spec/system/sibling_header_collision_spec.rb +620 -0
  631. data/spec/system/subdir_include_preservation_spec.rb +63 -0
  632. data/spec/system/support/bullseye_common_test_cases.rb +369 -0
  633. data/spec/system/support/bullseye_helpers.rb +70 -0
  634. data/spec/system/support/common_test_cases.rb +167 -43
  635. data/spec/system/support/cppcheck_common_test_cases.rb +80 -0
  636. data/spec/system/support/cppcheck_helpers.rb +10 -8
  637. data/spec/system/support/gcov_common_test_cases.rb +173 -37
  638. data/spec/system/support/gcov_helpers.rb +3 -3
  639. data/spec/system/support/gcov_partials_test_cases.rb +48 -2
  640. data/spec/system/support/sanitize_common_test_cases.rb +222 -0
  641. data/spec/system/support/sanitize_helpers.rb +27 -0
  642. data/spec/system/support/valgrind_common_test_cases.rb +116 -16
  643. data/spec/system/support/valgrind_helpers.rb +3 -4
  644. data/spec/system/test_pipeline_stop_points_spec.rb +160 -0
  645. data/spec/system/test_runner_system_include_spec.rb +19 -41
  646. data/spec/system/test_source_file_directive_spec.rb +235 -0
  647. data/spec/system/upgrade_as_vendor_spec.rb +25 -46
  648. data/spec/system/valgrind_deployment_spec.rb +41 -0
  649. data/spec/units/batchinator_spec.rb +314 -0
  650. data/spec/units/bin/actionator_spec.rb +412 -0
  651. data/spec/units/bin/app_cfg_spec.rb +100 -0
  652. data/spec/units/bin/cli_handler_spec.rb +205 -0
  653. data/spec/units/bin/cli_helper_spec.rb +248 -10
  654. data/spec/units/bin/cli_options_transform_spec.rb +49 -0
  655. data/spec/units/bin/composinator_spec.rb +236 -0
  656. data/spec/units/bin/{projectinator_mixin_spec.rb → mixin_resolvinator_spec.rb} +122 -83
  657. data/spec/units/bin/mixin_standardizer_spec.rb +4 -3
  658. data/spec/units/bin/mixinator_spec.rb +58 -22
  659. data/spec/units/bin/path_validator_spec.rb +112 -0
  660. data/spec/units/bin/projectinator_spec.rb +223 -0
  661. data/spec/units/bin/rake_patches_spec.rb +52 -0
  662. data/spec/units/bin/recursive_merger_spec.rb +22 -0
  663. data/spec/units/bin/versionator_spec.rb +104 -0
  664. data/spec/units/c_extractor/c_extractor_code_text_spec.rb +4 -4
  665. data/spec/units/c_extractor/c_extractor_declarations_spec.rb +70 -0
  666. data/spec/units/c_extractor/c_extractor_functions_spec.rb +75 -1
  667. data/spec/units/c_extractor/c_extractor_preprocessing_spec.rb +158 -0
  668. data/spec/units/c_extractor/c_extractor_spec.rb +236 -6
  669. data/spec/units/ceedling/templateinator_golden_spec.rb +84 -0
  670. data/spec/units/ceedling/templateinator_spec.rb +188 -0
  671. data/spec/units/config/configurator_builder_spec.rb +444 -0
  672. data/spec/units/config/configurator_plugins_spec.rb +160 -0
  673. data/spec/units/config/configurator_setup_spec.rb +724 -6
  674. data/spec/units/config/configurator_spec.rb +961 -0
  675. data/spec/units/config/configurator_validator_spec.rb +259 -0
  676. data/spec/units/config/line_marker_suppressors_spec.rb +89 -0
  677. data/spec/units/config_matchinator_spec.rb +103 -0
  678. data/spec/units/defineinator_spec.rb +158 -0
  679. data/spec/units/dependencies/dependency_cache_store_spec.rb +364 -0
  680. data/spec/units/dependencies/dependency_debug_tree_spec.rb +189 -0
  681. data/spec/units/dependencies/dependency_differ_spec.rb +139 -0
  682. data/spec/units/dependencies/dependency_hasher_spec.rb +141 -0
  683. data/spec/units/dependencies/dependency_path_normalizer_spec.rb +111 -0
  684. data/spec/units/dependencies/dependency_tracker_spec.rb +905 -0
  685. data/spec/units/dependencies/dependinator_spec.rb +99 -0
  686. data/spec/units/dependencies/gcc_dependency_parser_spec.rb +152 -0
  687. data/spec/units/encodinator_spec.rb +92 -0
  688. data/spec/units/file_finder_helper_spec.rb +99 -15
  689. data/spec/units/file_finder_spec.rb +495 -0
  690. data/spec/units/file_path_collection_utils_spec.rb +9 -0
  691. data/spec/units/file_path_utils_spec.rb +736 -0
  692. data/spec/units/file_wrapper_spec.rb +486 -0
  693. data/spec/units/filename_extension_spec.rb +120 -0
  694. data/spec/units/flaginator_spec.rb +114 -0
  695. data/spec/units/generators/generator_helper_spec.rb +113 -0
  696. data/spec/units/generators/generator_mocks_spec.rb +131 -0
  697. data/spec/units/generators/generator_partials_spec.rb +336 -160
  698. data/spec/units/generators/generator_spec.rb +317 -0
  699. data/spec/units/generators/generator_test_results_backtrace_spec.rb +169 -9
  700. data/spec/units/generators/generator_test_results_sanity_checker_spec.rb +14 -6
  701. data/spec/units/generators/generator_test_results_spec.rb +65 -8
  702. data/spec/units/generators/generator_test_runner_spec.rb +1 -1
  703. data/spec/units/includes/include_factory_spec.rb +53 -0
  704. data/spec/units/includes/include_pathinator_spec.rb +269 -0
  705. data/spec/units/includes/include_spec.rb +8 -4
  706. data/spec/units/includes/includes_spec.rb +326 -18
  707. data/spec/units/mock_locator_spec.rb +74 -0
  708. data/spec/units/parsing_parcels_spec.rb +65 -0
  709. data/spec/units/partials/partializer_config_spec.rb +284 -18
  710. data/spec/units/partials/partializer_helper_spec.rb +122 -0
  711. data/spec/units/partials/partializer_spec.rb +346 -71
  712. data/spec/units/partials/partializer_utils_spec.rb +4 -4
  713. data/spec/units/partials_manager_spec.rb +539 -0
  714. data/spec/units/path_matcher_spec.rb +193 -0
  715. data/spec/units/path_mirror_spec.rb +103 -0
  716. data/spec/units/plugin_manager_spec.rb +77 -0
  717. data/spec/units/plugin_reportinator_spec.rb +78 -3
  718. data/spec/units/plugins/bullseye_spec.rb +1068 -0
  719. data/spec/units/plugins/command_hooks_spec.rb +157 -0
  720. data/spec/units/plugins/compile_commands_json_db_spec.rb +145 -0
  721. data/spec/units/plugins/console_reportinator_spec.rb +370 -0
  722. data/spec/units/plugins/cppcheck_spec.rb +330 -4
  723. data/spec/units/plugins/cppunit_tests_reporter_spec.rb +118 -0
  724. data/spec/units/plugins/dependencies_spec.rb +295 -0
  725. data/spec/units/plugins/dependency_commands_spec.rb +83 -0
  726. data/spec/units/plugins/dependency_environment_spec.rb +64 -0
  727. data/spec/units/plugins/dependency_spec_spec.rb +170 -0
  728. data/spec/units/plugins/gcov_reportinator_spec.rb +272 -0
  729. data/spec/units/plugins/gcov_spec.rb +521 -0
  730. data/spec/units/plugins/gcovr_reportinator_spec.rb +795 -0
  731. data/spec/units/plugins/gtestlike_report_spec.rb +363 -0
  732. data/spec/units/plugins/html_tests_reporter_spec.rb +158 -0
  733. data/spec/units/plugins/ide_report_lines_spec.rb +229 -0
  734. data/spec/units/plugins/json_tests_reporter_spec.rb +87 -0
  735. data/spec/units/plugins/junit_tests_reporter_spec.rb +237 -0
  736. data/spec/units/plugins/module_generator_options_spec.rb +185 -0
  737. data/spec/units/plugins/module_generator_project_spec.rb +55 -0
  738. data/spec/units/plugins/module_generator_request_spec.rb +107 -0
  739. data/spec/units/plugins/module_generator_spec.rb +214 -0
  740. data/spec/units/plugins/module_generator_test_file_spec.rb +102 -0
  741. data/spec/units/plugins/module_generator_unity_spec.rb +37 -0
  742. data/spec/units/plugins/report_build_warnings_log_spec.rb +199 -0
  743. data/spec/units/plugins/report_log_writer_plugin_spec.rb +94 -0
  744. data/spec/units/plugins/report_tests_gtestlike_stdout_spec.rb +274 -0
  745. data/spec/units/plugins/report_tests_ide_stdout_spec.rb +140 -0
  746. data/spec/units/plugins/report_tests_log_factory_spec.rb +210 -0
  747. data/spec/units/plugins/report_tests_pretty_stdout_spec.rb +83 -0
  748. data/spec/units/plugins/report_tests_raw_output_log_spec.rb +98 -0
  749. data/spec/units/plugins/report_tests_stdout_plugin_spec.rb +145 -0
  750. data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +121 -0
  751. data/spec/units/plugins/reportgenerator_reportinator_spec.rb +410 -0
  752. data/spec/units/plugins/sanitize_config_spec.rb +119 -0
  753. data/spec/units/plugins/sanitize_findings_spec.rb +69 -0
  754. data/spec/units/plugins/sanitize_records_spec.rb +114 -0
  755. data/spec/units/plugins/sanitize_reports_spec.rb +84 -0
  756. data/spec/units/plugins/sanitize_spec.rb +300 -0
  757. data/spec/units/plugins/tests_reporter_spec.rb +89 -0
  758. data/spec/units/plugins/valgrind_spec.rb +560 -0
  759. data/spec/units/plugins/warning_collector_spec.rb +185 -0
  760. data/spec/units/plugins/warning_reports_spec.rb +150 -0
  761. data/spec/units/preprocess/c_comment_scanner_spec.rb +17 -17
  762. data/spec/units/preprocess/c_preprocessor_conditionals_spec.rb +94 -0
  763. data/spec/units/preprocess/preprocessinator_bare_includes_extractor_spec.rb +73 -0
  764. data/spec/units/preprocess/preprocessinator_code_finder_spec.rb +35 -16
  765. data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +129 -48
  766. data/spec/units/preprocess/preprocessinator_file_assembler_spec.rb +292 -9
  767. data/spec/units/preprocess/preprocessinator_includes_handler_spec.rb +294 -16
  768. data/spec/units/preprocess/preprocessinator_line_marker_includes_extractor_spec.rb +356 -6
  769. data/spec/units/preprocess/preprocessinator_reconstructor_spec.rb +58 -4
  770. data/spec/units/preprocess/preprocessinator_spec.rb +693 -5
  771. data/spec/units/quote_include_isolator_spec.rb +176 -0
  772. data/spec/units/rake_app/rake_invocation_tracker_spec.rb +94 -0
  773. data/spec/units/rake_app/rake_task_registry_spec.rb +263 -0
  774. data/spec/units/rake_app/rake_utils_spec.rb +54 -0
  775. data/spec/units/rake_app/rake_wrapper_spec.rb +64 -0
  776. data/spec/units/rake_app/rakefile_component_resolver_spec.rb +182 -0
  777. data/spec/units/rake_app/test_task_name_spec.rb +47 -0
  778. data/spec/units/release_build_executor_spec.rb +404 -0
  779. data/spec/units/release_build_planner_spec.rb +144 -0
  780. data/spec/units/release_invoker_spec.rb +127 -0
  781. data/spec/units/reportinator_spec.rb +35 -0
  782. data/spec/units/ruby_expandinator_spec.rb +36 -0
  783. data/spec/units/standin_headerinator_spec.rb +168 -0
  784. data/spec/units/system_wrapper_spec.rb +16 -0
  785. data/spec/units/test_build_executor_spec.rb +1693 -8
  786. data/spec/units/test_build_planner_spec.rb +878 -0
  787. data/spec/units/test_build_setup_spec.rb +583 -0
  788. data/spec/units/test_context_extractor_spec.rb +51 -3
  789. data/spec/units/test_file_preprocessinator_spec.rb +206 -0
  790. data/spec/units/test_includes_extractinator_spec.rb +764 -0
  791. data/spec/units/test_invoker/objects_wiring_spec.rb +31 -0
  792. data/spec/units/test_invoker_spec.rb +147 -0
  793. data/spec/units/test_invoker_types_spec.rb +182 -0
  794. data/spec/units/test_pipeline_helpers_spec.rb +100 -0
  795. data/spec/units/test_pipeline_manager_spec.rb +415 -0
  796. data/spec/units/test_runner_generatinator_spec.rb +215 -0
  797. data/spec/units/test_runner_manager_spec.rb +70 -0
  798. data/spec/units/test_search_paths_spec.rb +84 -0
  799. data/spec/units/test_source_file_directive_resolver_spec.rb +239 -0
  800. data/spec/units/tool_executor_helper_spec.rb +1 -1
  801. data/spec/units/tool_executor_spec.rb +571 -2
  802. data/spec/units/tool_validator_spec.rb +303 -24
  803. data/spec/units/version_spec.rb +74 -0
  804. data/spec/units/yaml_wrapper_spec.rb +4 -1
  805. data/vendor/cmock/docs/CMock_Summary.md +11 -0
  806. data/vendor/cmock/lib/cmock_config.rb +1 -0
  807. data/vendor/cmock/lib/cmock_generator.rb +5 -1
  808. data/vendor/cmock/test/unit/cmock_generator_main_test.rb +31 -0
  809. data/vendor/cmock/vendor/unity/auto/generate_module.rb +4 -4
  810. data/vendor/cmock/vendor/unity/auto/generate_test_runner.rb +8 -2
  811. data/vendor/cmock/vendor/unity/auto/unity_test_summary.rb +2 -2
  812. data/vendor/cmock/vendor/unity/docs/UnityChangeLog.md +7 -0
  813. data/vendor/cmock/vendor/unity/docs/UnityConfigurationGuide.md +4 -0
  814. data/vendor/cmock/vendor/unity/docs/UnityHelperScriptsGuide.md +9 -0
  815. data/vendor/cmock/vendor/unity/src/unity_internals.h +21 -7
  816. data/vendor/cmock/vendor/unity/test/Makefile +9 -2
  817. data/vendor/cmock/vendor/unity/test/rakefile_helper.rb +1 -0
  818. data/vendor/cmock/vendor/unity/test/spec/generate_module_naming_spec.rb +38 -0
  819. data/vendor/cmock/vendor/unity/test/testdata/spi/MockConfig.h +19 -0
  820. data/vendor/cmock/vendor/unity/test/testdata/testRunnerGeneratorWithSameNamedMocks.c +42 -0
  821. data/vendor/cmock/vendor/unity/test/testdata/uart/MockConfig.h +19 -0
  822. data/vendor/cmock/vendor/unity/test/tests/test_generate_test_runner.rb +78 -0
  823. data/vendor/cmock/vendor/unity/test/tests/test_unity_test_summary.rb +58 -0
  824. data/vendor/diy/lib/diy/factory.rb +5 -4
  825. data/vendor/diy/lib/diy.rb +5 -4
  826. data/vendor/diy/sample_code/car.rb +5 -4
  827. data/vendor/diy/sample_code/chassis.rb +5 -4
  828. data/vendor/diy/sample_code/diy_example.rb +5 -4
  829. data/vendor/diy/sample_code/engine.rb +5 -4
  830. data/vendor/diy/sample_code/objects.yml +5 -4
  831. data/vendor/diy/test/constructor.rb +5 -4
  832. data/vendor/diy/test/diy_test.rb +5 -4
  833. data/vendor/diy/test/factory_test.rb +5 -4
  834. data/vendor/diy/test/files/broken_construction.yml +5 -4
  835. data/vendor/diy/test/files/cat/cat.rb +5 -4
  836. data/vendor/diy/test/files/cat/extra_conflict.yml +5 -4
  837. data/vendor/diy/test/files/cat/heritage.rb +5 -4
  838. data/vendor/diy/test/files/cat/needs_input.yml +5 -4
  839. data/vendor/diy/test/files/cat/the_cat_lineage.rb +5 -4
  840. data/vendor/diy/test/files/dog/dog_model.rb +5 -4
  841. data/vendor/diy/test/files/dog/dog_presenter.rb +5 -4
  842. data/vendor/diy/test/files/dog/dog_view.rb +5 -4
  843. data/vendor/diy/test/files/dog/file_resolver.rb +5 -4
  844. data/vendor/diy/test/files/dog/other_thing.rb +5 -4
  845. data/vendor/diy/test/files/dog/simple.yml +5 -4
  846. data/vendor/diy/test/files/donkey/foo/bar/qux.rb +5 -4
  847. data/vendor/diy/test/files/donkey/foo.rb +5 -4
  848. data/vendor/diy/test/files/factory/beef.rb +5 -4
  849. data/vendor/diy/test/files/factory/dog.rb +5 -4
  850. data/vendor/diy/test/files/factory/factory.yml +5 -4
  851. data/vendor/diy/test/files/factory/farm/llama.rb +5 -4
  852. data/vendor/diy/test/files/factory/farm/pork.rb +5 -4
  853. data/vendor/diy/test/files/factory/kitten.rb +5 -4
  854. data/vendor/diy/test/files/fud/objects.yml +5 -4
  855. data/vendor/diy/test/files/fud/toy.rb +5 -4
  856. data/vendor/diy/test/files/functions/attached_things_builder.rb +5 -4
  857. data/vendor/diy/test/files/functions/invalid_method.yml +5 -4
  858. data/vendor/diy/test/files/functions/method_extractor.rb +5 -4
  859. data/vendor/diy/test/files/functions/nonsingleton_objects.yml +5 -4
  860. data/vendor/diy/test/files/functions/objects.yml +5 -4
  861. data/vendor/diy/test/files/functions/thing.rb +5 -4
  862. data/vendor/diy/test/files/functions/thing_builder.rb +5 -4
  863. data/vendor/diy/test/files/functions/things_builder.rb +5 -4
  864. data/vendor/diy/test/files/gnu/objects.yml +5 -4
  865. data/vendor/diy/test/files/gnu/thinger.rb +5 -4
  866. data/vendor/diy/test/files/goat/base.rb +5 -4
  867. data/vendor/diy/test/files/goat/can.rb +5 -4
  868. data/vendor/diy/test/files/goat/goat.rb +5 -4
  869. data/vendor/diy/test/files/goat/objects.yml +5 -4
  870. data/vendor/diy/test/files/goat/paper.rb +5 -4
  871. data/vendor/diy/test/files/goat/plane.rb +5 -4
  872. data/vendor/diy/test/files/goat/shirt.rb +5 -4
  873. data/vendor/diy/test/files/goat/wings.rb +5 -4
  874. data/vendor/diy/test/files/horse/holder_thing.rb +5 -4
  875. data/vendor/diy/test/files/horse/objects.yml +5 -4
  876. data/vendor/diy/test/files/namespace/animal/bird.rb +5 -4
  877. data/vendor/diy/test/files/namespace/animal/cat.rb +5 -4
  878. data/vendor/diy/test/files/namespace/animal/reptile/hardshell/turtle.rb +5 -4
  879. data/vendor/diy/test/files/namespace/animal/reptile/lizard.rb +5 -4
  880. data/vendor/diy/test/files/namespace/bad_module_specified.yml +5 -4
  881. data/vendor/diy/test/files/namespace/class_name_combine.yml +5 -4
  882. data/vendor/diy/test/files/namespace/no_module_specified.yml +5 -4
  883. data/vendor/diy/test/files/namespace/objects.yml +5 -4
  884. data/vendor/diy/test/files/namespace/road.rb +5 -4
  885. data/vendor/diy/test/files/namespace/sky.rb +5 -4
  886. data/vendor/diy/test/files/namespace/subcontext.yml +5 -4
  887. data/vendor/diy/test/files/non_singleton/air.rb +5 -4
  888. data/vendor/diy/test/files/non_singleton/fat_cat.rb +5 -4
  889. data/vendor/diy/test/files/non_singleton/objects.yml +5 -4
  890. data/vendor/diy/test/files/non_singleton/pig.rb +5 -4
  891. data/vendor/diy/test/files/non_singleton/thread_spinner.rb +5 -4
  892. data/vendor/diy/test/files/non_singleton/tick.rb +5 -4
  893. data/vendor/diy/test/files/non_singleton/yard.rb +5 -4
  894. data/vendor/diy/test/files/yak/core_model.rb +5 -4
  895. data/vendor/diy/test/files/yak/core_presenter.rb +5 -4
  896. data/vendor/diy/test/files/yak/core_view.rb +5 -4
  897. data/vendor/diy/test/files/yak/data_source.rb +5 -4
  898. data/vendor/diy/test/files/yak/fringe_model.rb +5 -4
  899. data/vendor/diy/test/files/yak/fringe_presenter.rb +5 -4
  900. data/vendor/diy/test/files/yak/fringe_view.rb +5 -4
  901. data/vendor/diy/test/files/yak/giant_squid.rb +5 -4
  902. data/vendor/diy/test/files/yak/krill.rb +5 -4
  903. data/vendor/diy/test/files/yak/my_objects.yml +5 -4
  904. data/vendor/diy/test/files/yak/sub_sub_context_test.yml +5 -4
  905. data/vendor/diy/test/test_helper.rb +5 -4
  906. data/vendor/unity/auto/generate_module.rb +4 -4
  907. data/vendor/unity/auto/generate_test_runner.rb +5 -1
  908. data/vendor/unity/docs/UnityHelperScriptsGuide.md +9 -0
  909. data/vendor/unity/test/spec/generate_module_naming_spec.rb +38 -0
  910. data/vendor/unity/test/testdata/spi/MockConfig.h +19 -0
  911. data/vendor/unity/test/testdata/testRunnerGeneratorWithSameNamedMocks.c +42 -0
  912. data/vendor/unity/test/testdata/uart/MockConfig.h +19 -0
  913. data/vendor/unity/test/tests/test_generate_test_runner.rb +29 -0
  914. metadata +783 -295
  915. data/assets/tests_with_fallback_conditionals/src/conditional_module.c +0 -18
  916. data/bin/actions_wrapper.rb +0 -51
  917. data/docs/mkdocs/assets/images/ceedling-logo-circle.png +0 -0
  918. data/docs/mkdocs/assets/images/ceedling.svg +0 -90
  919. data/docs/mkdocs/assets/images/favicon.png +0 -0
  920. data/docs/mkdocs/assets/stylesheets/admonitions.css +0 -152
  921. data/docs/mkdocs/assets/stylesheets/fixes-local.css +0 -15
  922. data/docs/mkdocs/assets/stylesheets/styling.css +0 -102
  923. data/docs/mkdocs/configuration/environment-vars.md +0 -14
  924. data/docs/mkdocs/configuration/global-collections.md +0 -156
  925. data/docs/mkdocs/configuration/index.md +0 -75
  926. data/docs/mkdocs/configuration/loading.md +0 -89
  927. data/docs/mkdocs/configuration/mixins.md +0 -607
  928. data/docs/mkdocs/configuration/parallel-builds.md +0 -97
  929. data/docs/mkdocs/configuration/project-file.md +0 -216
  930. data/docs/mkdocs/configuration/reference/cexception.md +0 -35
  931. data/docs/mkdocs/configuration/reference/cmock.md +0 -106
  932. data/docs/mkdocs/configuration/reference/defines.md +0 -352
  933. data/docs/mkdocs/configuration/reference/environment.md +0 -55
  934. data/docs/mkdocs/configuration/reference/extension.md +0 -63
  935. data/docs/mkdocs/configuration/reference/files.md +0 -154
  936. data/docs/mkdocs/configuration/reference/flags.md +0 -296
  937. data/docs/mkdocs/configuration/reference/index.md +0 -176
  938. data/docs/mkdocs/configuration/reference/libraries.md +0 -82
  939. data/docs/mkdocs/configuration/reference/mixins.md +0 -24
  940. data/docs/mkdocs/configuration/reference/partials.md +0 -38
  941. data/docs/mkdocs/configuration/reference/paths.md +0 -276
  942. data/docs/mkdocs/configuration/reference/plugins.md +0 -60
  943. data/docs/mkdocs/configuration/reference/project.md +0 -333
  944. data/docs/mkdocs/configuration/reference/release-build.md +0 -62
  945. data/docs/mkdocs/configuration/reference/test-build.md +0 -55
  946. data/docs/mkdocs/configuration/reference/test-runner.md +0 -61
  947. data/docs/mkdocs/configuration/reference/tools.md +0 -457
  948. data/docs/mkdocs/configuration/reference/unity.md +0 -49
  949. data/docs/mkdocs/configuration/which-ceedling.md +0 -77
  950. data/docs/mkdocs/development/index.md +0 -61
  951. data/docs/mkdocs/development/plugins/configuration.md +0 -164
  952. data/docs/mkdocs/development/plugins/index.md +0 -84
  953. data/docs/mkdocs/development/plugins/plugin-subclass.md +0 -513
  954. data/docs/mkdocs/development/plugins/rake-tasks.md +0 -54
  955. data/docs/mkdocs/development/workflow.md +0 -284
  956. data/docs/mkdocs/getting-started/command-line.md +0 -477
  957. data/docs/mkdocs/getting-started/example-projects/cipher-quest.md +0 -65
  958. data/docs/mkdocs/getting-started/example-projects/index.md +0 -49
  959. data/docs/mkdocs/getting-started/example-projects/temp-sensor.md +0 -60
  960. data/docs/mkdocs/getting-started/example-projects/wondrous-forest.md +0 -45
  961. data/docs/mkdocs/getting-started/index.md +0 -41
  962. data/docs/mkdocs/getting-started/installation.md +0 -179
  963. data/docs/mkdocs/getting-started/quick-start.md +0 -86
  964. data/docs/mkdocs/help.md +0 -49
  965. data/docs/mkdocs/index.md +0 -222
  966. data/docs/mkdocs/overview/build-system.md +0 -115
  967. data/docs/mkdocs/overview/index.md +0 -29
  968. data/docs/mkdocs/overview/test-environments.md +0 -33
  969. data/docs/mkdocs/overview/tools-and-frameworks.md +0 -115
  970. data/docs/mkdocs/plugins/beep.md +0 -134
  971. data/docs/mkdocs/plugins/bullseye.md +0 -83
  972. data/docs/mkdocs/plugins/command-hooks.md +0 -268
  973. data/docs/mkdocs/plugins/compile-commands-json-db.md +0 -42
  974. data/docs/mkdocs/plugins/cppcheck.md +0 -377
  975. data/docs/mkdocs/plugins/dependencies.md +0 -310
  976. data/docs/mkdocs/plugins/fff.md +0 -247
  977. data/docs/mkdocs/plugins/gcov/examples.md +0 -92
  978. data/docs/mkdocs/plugins/gcov/gcovr.md +0 -526
  979. data/docs/mkdocs/plugins/gcov/index.md +0 -74
  980. data/docs/mkdocs/plugins/gcov/overview.md +0 -145
  981. data/docs/mkdocs/plugins/gcov/reportgenerator.md +0 -246
  982. data/docs/mkdocs/plugins/gcov/reporting.md +0 -147
  983. data/docs/mkdocs/plugins/gcov/setup.md +0 -232
  984. data/docs/mkdocs/plugins/gcov/tool-versions.md +0 -60
  985. data/docs/mkdocs/plugins/gcov/troubleshooting.md +0 -78
  986. data/docs/mkdocs/plugins/index.md +0 -261
  987. data/docs/mkdocs/plugins/module-generator.md +0 -267
  988. data/docs/mkdocs/plugins/report-build-warnings-log.md +0 -42
  989. data/docs/mkdocs/plugins/report-tests-gtestlike-stdout.md +0 -98
  990. data/docs/mkdocs/plugins/report-tests-ide-stdout.md +0 -63
  991. data/docs/mkdocs/plugins/report-tests-log-factory.md +0 -454
  992. data/docs/mkdocs/plugins/report-tests-pretty-stdout.md +0 -56
  993. data/docs/mkdocs/plugins/report-tests-raw-output-log.md +0 -52
  994. data/docs/mkdocs/plugins/report-tests-teamcity-stdout.md +0 -96
  995. data/docs/mkdocs/plugins/sample_html_report.png +0 -0
  996. data/docs/mkdocs/plugins/valgrind.md +0 -198
  997. data/docs/mkdocs/project/release-history.md +0 -61
  998. data/docs/mkdocs/project/upgrade.md +0 -85
  999. data/docs/mkdocs/reference/build-directives.md +0 -37
  1000. data/docs/mkdocs/reference/command-line.md +0 -323
  1001. data/docs/mkdocs/reference/environment-vars.md +0 -60
  1002. data/docs/mkdocs/reference/gcov-plugin.md +0 -600
  1003. data/docs/mkdocs/reference/global-collections.md +0 -160
  1004. data/docs/mkdocs/reference/index.md +0 -65
  1005. data/docs/mkdocs/reference/partials-macros.md +0 -79
  1006. data/docs/mkdocs/reference/project-configuration.md +0 -46
  1007. data/docs/mkdocs/snapshot/examples/cipher_quest/README.md +0 -210
  1008. data/docs/mkdocs/snapshot/examples/temp_sensor/README.md +0 -283
  1009. data/docs/mkdocs/snapshot/examples/wondrous_forest/README.md +0 -92
  1010. data/docs/mkdocs/snapshot/plugins/gcov/config/defaults.yml +0 -32
  1011. data/docs/mkdocs/snapshot/plugins/gcov/config/defaults_gcov.rb +0 -136
  1012. data/docs/mkdocs/snapshot.yml +0 -20
  1013. data/docs/mkdocs/testing-guide/build-directives.md +0 -153
  1014. data/docs/mkdocs/testing-guide/conventions.md +0 -616
  1015. data/docs/mkdocs/testing-guide/frameworks.md +0 -192
  1016. data/docs/mkdocs/testing-guide/index.md +0 -80
  1017. data/docs/mkdocs/testing-guide/partials/configuration.md +0 -67
  1018. data/docs/mkdocs/testing-guide/partials/conventions.md +0 -68
  1019. data/docs/mkdocs/testing-guide/partials/directives.md +0 -212
  1020. data/docs/mkdocs/testing-guide/partials/example.md +0 -149
  1021. data/docs/mkdocs/testing-guide/partials/index.md +0 -88
  1022. data/docs/mkdocs/testing-guide/partials/overview.md +0 -81
  1023. data/docs/mkdocs/testing-guide/partials/variables.md +0 -244
  1024. data/docs/mkdocs/testing-guide/test-cases.md +0 -194
  1025. data/docs/mkdocs/testing-guide/test-sample.md +0 -94
  1026. data/docs/mkdocs/testing-guide/test-suite-anatomy.md +0 -58
  1027. data/lib/ceedling/cacheinator.rb +0 -53
  1028. data/lib/ceedling/cacheinator_helper.rb +0 -60
  1029. data/lib/ceedling/dependinator.rb +0 -31
  1030. data/lib/ceedling/makefile.rb +0 -52
  1031. data/lib/ceedling/release_invoker.rb +0 -112
  1032. data/lib/ceedling/rules_release.rake +0 -109
  1033. data/lib/ceedling/tasks_release.rake +0 -36
  1034. data/plugins/fff/vendor/fff/Makefile +0 -10
  1035. data/plugins/fff/vendor/fff/buildandtest +0 -15
  1036. data/plugins/fff/vendor/fff/examples/Makefile +0 -7
  1037. data/plugins/fff/vendor/fff/examples/driver_testing/Makefile +0 -64
  1038. data/plugins/fff/vendor/fff/examples/driver_testing/driver.c +0 -32
  1039. data/plugins/fff/vendor/fff/examples/driver_testing/driver.h +0 -21
  1040. data/plugins/fff/vendor/fff/examples/driver_testing/driver.test.cpp +0 -58
  1041. data/plugins/fff/vendor/fff/examples/driver_testing/driver.test.fff.cpp +0 -70
  1042. data/plugins/fff/vendor/fff/examples/driver_testing/hardware_abstraction.h +0 -25
  1043. data/plugins/fff/vendor/fff/examples/driver_testing/registers.h +0 -23
  1044. data/plugins/fff/vendor/fff/examples/embedded_ui/DISPLAY.h +0 -27
  1045. data/plugins/fff/vendor/fff/examples/embedded_ui/Kata.txt +0 -25
  1046. data/plugins/fff/vendor/fff/examples/embedded_ui/Makefile +0 -67
  1047. data/plugins/fff/vendor/fff/examples/embedded_ui/SYSTEM.h +0 -31
  1048. data/plugins/fff/vendor/fff/examples/embedded_ui/UI.c +0 -56
  1049. data/plugins/fff/vendor/fff/examples/embedded_ui/UI.h +0 -22
  1050. data/plugins/fff/vendor/fff/examples/embedded_ui/UI_test_ansic.c +0 -191
  1051. data/plugins/fff/vendor/fff/examples/embedded_ui/UI_test_cpp.cpp +0 -144
  1052. data/plugins/fff/vendor/fff/examples/embedded_ui/test_suite_template.c +0 -42
  1053. data/plugins/fff/vendor/fff/gtest/Makefile +0 -22
  1054. data/plugins/fff/vendor/fff/gtest/gtest-all.cc +0 -9118
  1055. data/plugins/fff/vendor/fff/gtest/gtest-main.cc +0 -6
  1056. data/plugins/fff/vendor/fff/gtest/gtest.h +0 -19547
  1057. data/plugins/fff/vendor/fff/test/Makefile +0 -81
  1058. data/plugins/fff/vendor/fff/test/c_test_framework.h +0 -25
  1059. data/plugins/fff/vendor/fff/test/fff_test_c.c +0 -116
  1060. data/plugins/fff/vendor/fff/test/fff_test_cpp.cpp +0 -53
  1061. data/plugins/fff/vendor/fff/test/fff_test_global_c.c +0 -84
  1062. data/plugins/fff/vendor/fff/test/fff_test_global_cpp.cpp +0 -31
  1063. data/plugins/fff/vendor/fff/test/global_fakes.c +0 -21
  1064. data/plugins/fff/vendor/fff/test/global_fakes.h +0 -47
  1065. data/plugins/fff/vendor/fff/test/test_cases.include +0 -276
  1066. data/plugins/report_tests_gtestlike_stdout/assets/template.erb +0 -83
  1067. data/site-local/assets/stylesheets/main.ec1eaa64.min.css +0 -1
  1068. data/site-local/assets/stylesheets/main.ec1eaa64.min.css.map +0 -1
  1069. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css +0 -1
  1070. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css.map +0 -1
  1071. data/site-local/snapshot/assets/project.yml +0 -404
  1072. data/spec/system/partials_types_header_spec.rb +0 -166
  1073. data/spec/units/configurator_spec.rb +0 -232
  1074. /data/assets/{ceedling → features/ceedling} +0 -0
  1075. /data/assets/{ceedling.cmd → features/ceedling.cmd} +0 -0
  1076. /data/assets/{default_gitignore → features/default_gitignore} +0 -0
  1077. /data/assets/{broken_uncovered_file.c → fixtures/broken_uncovered_file.c} +0 -0
  1078. /data/assets/{example_file.c → fixtures/example_file.c} +0 -0
  1079. /data/assets/{example_file.h → fixtures/example_file.h} +0 -0
  1080. /data/assets/{example_file_call.c → fixtures/example_file_call.c} +0 -0
  1081. /data/assets/{example_file_call.h → fixtures/example_file_call.h} +0 -0
  1082. /data/assets/{example_file_with_statics.c → fixtures/example_file_with_statics.c} +0 -0
  1083. /data/assets/{example_file_with_stdio.c → fixtures/example_file_with_stdio.c} +0 -0
  1084. /data/assets/{example_file_with_stdio.h → fixtures/example_file_with_stdio.h} +0 -0
  1085. /data/assets/{fake_crash_test_fixture.rb → fixtures/fake_crash_test_fixture.rb} +0 -0
  1086. /data/assets/{partial_all_module.h → fixtures/partial_all_module.h} +0 -0
  1087. /data/assets/{run_with_ubsan.rb → fixtures/run_with_ubsan.rb} +0 -0
  1088. /data/assets/{same_dir_pairing_module.c → fixtures/same_dir_pairing_module.c} +0 -0
  1089. /data/assets/{same_dir_pairing_module.h → fixtures/same_dir_pairing_module.h} +0 -0
  1090. /data/assets/{same_dir_pairing_module_func.h → fixtures/same_dir_pairing_module_func.h} +0 -0
  1091. /data/assets/{same_dir_pairing_other.c → fixtures/same_dir_pairing_other.c} +0 -0
  1092. /data/assets/{same_dir_pairing_other.h → fixtures/same_dir_pairing_other.h} +0 -0
  1093. /data/assets/{test_example_file.c → fixtures/test_example_file.c} +0 -0
  1094. /data/assets/{test_example_file_2.c → fixtures/test_example_file_2.c} +0 -0
  1095. /data/assets/{test_example_file_source_include.c → fixtures/test_example_file_source_include.c} +0 -0
  1096. /data/assets/{test_example_file_success.c → fixtures/test_example_file_success.c} +0 -0
  1097. /data/assets/{test_example_file_unity_printf.c → fixtures/test_example_file_unity_printf.c} +0 -0
  1098. /data/assets/{test_example_file_verbose.c → fixtures/test_example_file_verbose.c} +0 -0
  1099. /data/assets/{test_example_file_with_mock.c → fixtures/test_example_file_with_mock.c} +0 -0
  1100. /data/assets/{test_example_file_with_stdio.c → fixtures/test_example_file_with_stdio.c} +0 -0
  1101. /data/assets/{test_example_with_parameterized_tests.c → fixtures/test_example_with_parameterized_tests.c} +0 -0
  1102. /data/assets/{test_partial_all_module.c → fixtures/test_partial_all_module.c} +0 -0
  1103. /data/assets/{test_same_dir_pairing.c → fixtures/test_same_dir_pairing.c} +0 -0
  1104. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/feature_config.h +0 -0
  1105. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/feature_extra.h +0 -0
  1106. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/local_flag_extra.h +0 -0
  1107. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/nested_extra.h +0 -0
  1108. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/nested_wrapper.h +0 -0
  1109. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/project_flag_extra.h +0 -0
  1110. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget_feature.h +0 -0
  1111. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware.c +0 -0
  1112. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware.h +0 -0
  1113. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware_configurator.c +0 -0
  1114. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware_configurator.h +0 -0
  1115. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/test/test_adc_hardware.c +0 -0
  1116. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/test/test_adc_hardware_special.c +0 -0
  1117. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/src/unicoder.c +0 -0
  1118. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/src/unicoder.h +0 -0
  1119. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/test/test_unicoder.c +0 -0
  1120. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/test/test_unicoder_partial.c +0 -0
  1121. /data/assets/{tests_with_fallback_conditionals → fixtures/tests_with_fallback_conditionals}/src/conditional_module.h +0 -0
  1122. /data/assets/{tests_with_fallback_conditionals → fixtures/tests_with_fallback_conditionals}/src/optional_dep.h +0 -0
  1123. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/blanks.c +0 -0
  1124. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/blanks.h +0 -0
  1125. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/counter.c +0 -0
  1126. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/counter.h +0 -0
  1127. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/decorators.c +0 -0
  1128. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/decorators.h +0 -0
  1129. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/test/test_blanks.c +0 -0
  1130. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/test/test_counter.c +0 -0
  1131. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/test/test_decorators.c +0 -0
  1132. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareA.c +0 -0
  1133. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareA.h +0 -0
  1134. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareB.c +0 -0
  1135. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareB.h +0 -0
  1136. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareC.c +0 -0
  1137. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareC.h +0 -0
  1138. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardware_configuratorA.h +0 -0
  1139. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardware_configuratorB.h +0 -0
  1140. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardware_configuratorC.h +0 -0
  1141. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/test/test_adc_hardwareA.c +0 -0
  1142. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/test/test_adc_hardwareB.c +0 -0
  1143. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/test/test_adc_hardwareC.c +0 -0
  1144. /data/assets/{uncovered_example_file.c → fixtures/uncovered_example_file.c} +0 -0
  1145. /data/plugins/bullseye/assets/{template.erb → coverage.template} +0 -0
@@ -8,10 +8,12 @@
8
8
  require 'ceedling/constants'
9
9
  require 'ceedling/exceptions'
10
10
  require 'ceedling/test_invoker/test_invoker_types'
11
+ require 'ceedling/test_invoker/test_pipeline_helpers'
11
12
 
12
13
  class TestBuildExecutor
13
14
 
14
15
  include TestInvokerTypes
16
+ include TestPipelineHelpers
15
17
 
16
18
  constructor(
17
19
  :configurator,
@@ -19,284 +21,80 @@ class TestBuildExecutor
19
21
  :reportinator,
20
22
  :batchinator,
21
23
  :preprocessinator,
22
- :partializer,
23
24
  :generator,
24
- :test_context_extractor,
25
25
  :plugin_manager,
26
26
  :file_path_utils,
27
27
  :file_finder,
28
- :file_wrapper
28
+ :file_wrapper,
29
+ :dependinator,
30
+ :gcc_dependency_parser,
31
+ :quote_include_isolator,
32
+ :generator_helper
29
33
  )
30
34
 
31
- def setup()
32
- @context_extractor = @test_context_extractor
33
- end
34
-
35
- # Stage 6: Preprocess partial header files for extract-and-generate pass.
36
- def stage_preprocess_partial_headers(state)
37
- directives_only = @configurator.test_build_preprocess_directives_only_available
38
-
39
- # Generate directive-only preprocessor output if available
40
- @batchinator.exec(workload: :compile, things: state.partials_headers) do |details|
41
- config = details[:config]
42
- testable = details[:testable]
43
- name = testable.name
44
-
45
- arg_hash = {
46
- filepath: config.filepath,
47
- test: name,
48
- flags: testable.preprocess_flags,
49
- include_paths: testable.search_paths,
50
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
51
- defines: testable.preprocess_defines
52
- }
53
-
54
- details[:directives_only_filepath] = @preprocessinator.generate_directives_only_output( **arg_hash )
55
- end if directives_only
56
-
57
- # Preprocess and assemble header files
58
- @batchinator.exec(workload: :compile, things: state.partials_headers) do |details|
59
- config = details[:config]
60
- testable = details[:testable]
61
- name = testable.name
62
- directives_only_filepath = details[:directives_only_filepath]
63
-
64
- arg_hash = {
65
- test: name,
66
- filepath: config.filepath,
67
- directives_only_filepath: directives_only_filepath,
68
- fallback: (!directives_only or directives_only_filepath.nil?),
69
- flags: testable.preprocess_flags,
70
- include_paths: testable.search_paths,
71
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
72
- defines: testable.preprocess_defines
73
- }
74
-
75
- config.directives_only_filepath, config.includes = @preprocessinator.preprocess_partial_header_file_preserve_macros( **arg_hash )
76
- end
77
-
78
- # Full-preprocess partial header files for expanded signature extraction.
79
- @batchinator.exec(workload: :compile, things: state.partials_headers) do |details|
80
- config = details[:config]
81
- testable = details[:testable]
82
- name = testable.name
83
-
84
- arg_hash = {
85
- filepath: config.filepath,
86
- test: name,
87
- flags: testable.preprocess_flags,
88
- include_paths: testable.search_paths,
89
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
90
- defines: testable.preprocess_defines
91
- }
92
-
93
- config.full_expansion_filepath = @preprocessinator.preprocess_partial_header_expand_macros( **arg_hash )
94
- end
95
- end
96
-
97
- # Stage 7: Preprocess partial source files for extract-and-generate pass.
98
- def stage_preprocess_partial_sources(state)
99
- directives_only = @configurator.test_build_preprocess_directives_only_available
100
-
101
- # Generate directive-only preprocessor output if available
102
- @batchinator.exec(workload: :compile, things: state.partials_sources) do |details|
103
- config = details[:config]
104
- testable = details[:testable]
105
- name = testable.name
106
-
107
- arg_hash = {
108
- filepath: config.filepath,
109
- test: name,
110
- flags: testable.preprocess_flags,
111
- include_paths: testable.search_paths,
112
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
113
- defines: testable.preprocess_defines
114
- }
115
-
116
- details[:directives_only_filepath] = @preprocessinator.generate_directives_only_output( **arg_hash )
117
- end if directives_only
118
-
119
- # Preprocess and assemble source files
120
- @batchinator.exec(workload: :compile, things: state.partials_sources) do |details|
121
- config = details[:config]
122
- testable = details[:testable]
123
- name = testable.name
124
- directives_only_filepath = details[:directives_only_filepath]
125
-
126
- arg_hash = {
127
- test: name,
128
- filepath: config.filepath,
129
- directives_only_filepath: directives_only_filepath,
130
- fallback: (!directives_only or directives_only_filepath.nil?),
131
- flags: testable.preprocess_flags,
132
- include_paths: testable.search_paths,
133
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
134
- defines: testable.preprocess_defines
135
- }
136
-
137
- config.directives_only_filepath, config.includes = @preprocessinator.preprocess_partial_source_file_preserve_macros( **arg_hash )
138
- end
139
-
140
- # Full-preprocess partial source files for expanded signature extraction.
141
- @batchinator.exec(workload: :compile, things: state.partials_sources) do |details|
142
- config = details[:config]
143
- testable = details[:testable]
144
- name = testable.name
145
-
146
- arg_hash = {
147
- filepath: config.filepath,
148
- test: name,
149
- flags: testable.preprocess_flags,
150
- include_paths: testable.search_paths,
151
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
152
- defines: testable.preprocess_defines
153
- }
154
-
155
- config.full_expansion_filepath = @preprocessinator.preprocess_partial_source_expand_macros( **arg_hash )
156
- end
157
- end
158
-
159
- # Stage 8: Extract and generate partial implementation and interface files.
160
- def stage_generate_partials(state)
35
+ # Stage 9: Preprocess header files to be mocked.
36
+ def stage_preprocess_mocks(state)
161
37
  directives_only = @configurator.test_build_preprocess_directives_only_available
162
-
163
- partials = []
164
- state.testables.each do |_, testable|
165
- next if testable.partials.configs.empty?
166
- testable.partials.configs.each do |_, config|
167
- partials << { config: config, testable: testable }
168
- end
169
- end
170
-
171
- @batchinator.exec(workload: :compile, things: partials) do |partial|
172
- config = partial[:config]
173
- testable = partial[:testable]
174
- name = testable.name
175
-
176
- module_contents = @partializer.extract_module_contents(
177
- name,
178
- config,
179
- !directives_only
180
- )
181
-
182
- @partializer.validate_config( c_module: module_contents, config: config, name: name )
183
-
184
- @partializer.sanitize( module_contents )
185
-
186
- # The real header's guard is spoofed deliberately in every generated file, and the types
187
- # header carries the dependencies its extracted types name.
188
- module_include_guard = @partializer.extract_module_include_guard( config.header.filepath )
189
- types_header_includes = @partializer.remap_types_header_includes(
190
- name: config.module,
191
- includes: (config.source.includes + config.header.includes),
192
- partials: testable.partials.configs,
193
- test: name
194
- )
195
-
196
- # Generated once and shared by the implementation and interface headers below (via
197
- # their own includes lists), so a module tested and mocked in the same test file gets
198
- # exactly one C definition of each of its typedefs and aggregate types.
199
- types_header = @generator.generate_partial_types(
200
- name: config.module, # Module name, not test name -- two modules Partialed
201
- # in the same test file must not collide on one
202
- # shared types header filename
203
- c_module: module_contents,
204
- output_path: testable.paths[:partials],
205
- includes: types_header_includes,
206
- include_guard: module_include_guard
38
+ skipped = 0
39
+
40
+ # Register every mock's preprocessed-header target and settle its staleness
41
+ # up front (sequentially -- cheap, no subprocess work), since it gates both
42
+ # of the parallel batches below.
43
+ state.mocks_list.each do |mock|
44
+ details = mock.details
45
+ testable = mock.testable
46
+
47
+ # A Partial mock's own generated header is already free of inline function
48
+ # bodies, so it never needs this extra pass regardless of what the project
49
+ # configures for CMock's own mocks of real headers elsewhere.
50
+ extras = !details.partial && (@configurator.cmock_treat_inlines == :include)
51
+
52
+ target = @file_path_utils.form_preprocessed_file_filepath( details.source, testable.name )
53
+
54
+ @dependinator.register(
55
+ target,
56
+ files: [details.source],
57
+ meta: {
58
+ flags: testable.preprocess_flags,
59
+ defines: testable.preprocess_defines,
60
+ search_paths: testable.search_paths,
61
+ extras: extras,
62
+ tools: [@configurator.tools_test_bare_includes_preprocessor, @configurator.tools_test_file_directives_only_preprocessor],
63
+ preprocess_force_fallback: @configurator.test_build_preprocess_force_fallback
64
+ }
207
65
  )
208
66
 
209
- implementation = @partializer.extract_implementation_functions(
210
- test: name,
211
- partial: config.module,
212
- definitions: module_contents.function_definitions,
213
- config: config
214
- )
67
+ mock.preprocessed_target = target
68
+ mock.stale = @dependinator.stale?( target )
215
69
 
216
- interface = @partializer.extract_interface_functions(
217
- test: name,
218
- partial: config.module,
219
- definitions: module_contents.function_definitions,
220
- declarations: module_contents.function_declarations,
221
- config: config
222
- )
70
+ next if mock.stale
223
71
 
224
- @partializer.validate_extracted_functions(
225
- name: name,
226
- partial: config.module,
227
- impl: implementation,
228
- interface: interface
72
+ msg = @reportinator.generate_module_progress(
73
+ operation: 'Skipping mock preprocessing for',
74
+ module_name: testable.name,
75
+ filename: File.basename( details.source )
229
76
  )
230
-
231
- arg_hash = {
232
- test: name,
233
- partial: config.module,
234
- function_definitions: implementation,
235
- c_module: module_contents,
236
- header_includes: @partializer.remap_implementation_header_includes(
237
- name: config.module,
238
- includes: (config.source.includes + config.header.includes),
239
- partials: testable.partials.configs,
240
- types_header: types_header,
241
- test: name
242
- ),
243
- source_includes: @partializer.remap_implementation_source_includes(
244
- name: config.module,
245
- includes: (config.source.includes + config.header.includes),
246
- partials: testable.partials.configs,
247
- test: name
248
- ),
249
- input_filepath: config.source.filepath,
250
- output_path: testable.paths[:partials],
251
- include_guard: module_include_guard
252
- }
253
-
254
- unless implementation.nil?
255
- @generator.generate_partial_implementation( **arg_hash )
256
- state.lock.synchronize { testable.partials.tests << config.module }
257
- end
258
-
259
- arg_hash = {
260
- test: name,
261
- partial: config.module,
262
- function_declarations: interface,
263
- includes: @partializer.remap_interface_header_includes(
264
- name: config.module,
265
- includes: (config.source.includes + config.header.includes),
266
- partials: testable.partials.configs,
267
- types_header: types_header,
268
- test: name
269
- ),
270
- c_module: module_contents,
271
- input_filepath: config.header.filepath,
272
- output_path: testable.paths[:partials],
273
- include_guard: module_include_guard
274
- }
275
-
276
- unless interface.nil?
277
- @generator.generate_partial_interface( **arg_hash )
278
- state.lock.synchronize { testable.partials.mocks << config.module }
279
- end
77
+ @loginator.log( msg, Verbosity::OBNOXIOUS )
78
+ skipped += 1
280
79
  end
281
- end
282
80
 
283
- # Stage 9: Preprocess header files to be mocked.
284
- def stage_preprocess_mocks(state)
285
- directives_only = @configurator.test_build_preprocess_directives_only_available
81
+ log_skip_summary( task: "mock preprocessing", count: skipped, noun: "mocks" )
286
82
 
287
83
  # Generate directive-only preprocessor output if available
288
84
  @batchinator.exec(workload: :compile, things: state.mocks_list) do |mock|
289
- details = mock[:details]
290
- testable = mock[:testable]
85
+ next unless mock.stale
86
+
87
+ details = mock.details
88
+ testable = mock.testable
291
89
  name = testable.name
292
- filepath = details[:source]
90
+ filepath = details.source
293
91
 
294
92
  arg_hash = {
295
93
  filepath: filepath,
296
94
  test: name,
297
95
  flags: testable.preprocess_flags,
298
96
  include_paths: testable.search_paths,
299
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
97
+ vendor_paths: vendor_search_paths(),
300
98
  defines: testable.preprocess_defines
301
99
  }
302
100
 
@@ -307,199 +105,388 @@ class TestBuildExecutor
307
105
  @loginator.log( msg, Verbosity::COMPLAIN )
308
106
  end
309
107
 
310
- mock[:directives_only_filepath] = _filepath
108
+ mock.directives_only_filepath = _filepath
311
109
  end if directives_only
312
110
 
313
111
  # Preprocess and assemble header files to be mocked
314
112
  @batchinator.exec(workload: :compile, things: state.mocks_list) do |mock|
315
- details = mock[:details]
316
- testable = mock[:testable]
317
- directives_only_filepath = mock[:directives_only_filepath]
113
+ next unless mock.stale
318
114
 
319
- extras = (@configurator.cmock_treat_inlines == :include)
115
+ details = mock.details
116
+ testable = mock.testable
117
+ directives_only_filepath = mock.directives_only_filepath
118
+ extras = !details.partial && (@configurator.cmock_treat_inlines == :include)
320
119
 
321
120
  arg_hash = {
322
121
  test: testable.name,
323
- filepath: details[:source],
122
+ filepath: details.source,
324
123
  directives_only_filepath: directives_only_filepath,
325
- fallback: (!directives_only or directives_only_filepath.nil?),
124
+ fallback: directives_only_fallback?( directives_only, directives_only_filepath ),
326
125
  flags: testable.preprocess_flags,
327
126
  include_paths: testable.search_paths,
328
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
127
+ vendor_paths: vendor_search_paths(),
329
128
  defines: testable.preprocess_defines,
330
129
  extras: extras
331
130
  }
332
131
 
333
132
  @preprocessinator.preprocess_mockable_header_file( **arg_hash )
133
+
134
+ @dependinator.mark_fresh( mock.preprocessed_target )
334
135
  end
335
136
  end
336
137
 
337
138
  # Stage 10: Generate mocks for all tests.
338
139
  def stage_generate_mocks(state)
140
+ # get_cmock_config, not project_config_hash[:cmock]: project_config_hash is
141
+ # flattened -- CMock's own settings live there as individual top-level keys
142
+ # like :cmock_mock_prefix, not as a :cmock section -- so this is the only
143
+ # place that still holds CMock's configuration as a single value to compare.
144
+ cmock_meta = @configurator.get_cmock_config
145
+ skipped = 0
146
+
339
147
  @batchinator.exec(workload: :compile, things: state.mocks_list) do |mock|
340
- details = mock[:details]
341
- testable = mock[:testable]
148
+ details = mock.details
149
+ testable = mock.testable
342
150
 
343
- output_path = File.join( testable.paths[:mocks], details[:path] )
151
+ output_path = @file_path_utils.form_mock_output_path( testable.paths[:mocks], details.path )
152
+ folder, output_path = mock_folder_and_path( testable.paths[:mocks], output_path, details.include_path )
344
153
  @file_wrapper.mkdir( output_path )
345
154
 
155
+ # `details.input` -- not the stage 9 preprocessed target -- is the
156
+ # correct antecedent here: it's exactly what CMock reads, whether or not
157
+ # mock preprocessing is enabled for this project (see stage_determine_files).
158
+ #
159
+ # `details.name` (a String), not `mock.name` (the Symbol key T2 carried
160
+ # the same value in for hash lookups) -- needed here as a real filename.
161
+ target = File.join( output_path, details.name + EXTENSION_CORE_SOURCE )
162
+ mock_header = File.join( output_path, details.name + EXTENSION_CORE_HEADER )
163
+
164
+ # CMock writes `mock_header` in the same call as `target`, so the mock vouches for
165
+ # it as an output. Stage 4 places a stand-in at this exact path when no file is
166
+ # there or an earlier stand-in is out of date (StandinHeaderinator), independent of
167
+ # this mock's antecedents. The recorded hash catches a stand-in in the mock's place
168
+ # and regenerates the mock.
169
+ @dependinator.register( target, files: [details.input], meta: { cmock: cmock_meta }, outputs: [mock_header] )
170
+
171
+ unless @dependinator.stale?( target )
172
+ msg = @reportinator.generate_module_progress(
173
+ operation: 'Skipping mock generation for',
174
+ module_name: testable.name,
175
+ filename: details.name
176
+ )
177
+ @loginator.log( msg, Verbosity::OBNOXIOUS )
178
+ state.lock.synchronize { skipped += 1 }
179
+ next
180
+ end
181
+
182
+ # A Partial mock's own generated header is already free of inline function
183
+ # bodies -- CMock's own inline handling has nothing to do on it and is
184
+ # skipped for this one mock, independent of whatever the project configures
185
+ # for CMock's own mocks of real headers elsewhere in the same test suite.
186
+ overrides = details.partial ? { treat_inlines: :exclude } : {}
187
+
346
188
  arg_hash = {
347
189
  context: state.context,
348
- mock: mock[:name],
190
+ mock: mock.name,
349
191
  test: testable.name,
350
- input_filepath: details[:input],
351
- output_path: output_path
192
+ input_filepath: details.input,
193
+ output_path: output_path,
194
+ folder: folder,
195
+ overrides: overrides
352
196
  }
353
197
 
354
198
  @generator.generate_mock( **arg_hash )
355
- end
356
- end
357
-
358
- # Stage 11: Preprocess test files and extract source build directives.
359
- def stage_preprocess_test_files(state)
360
- directives_only = @configurator.test_build_preprocess_directives_only_available
361
-
362
- @batchinator.exec(workload: :compile, things: state.testables) do |_, testable|
363
- filepath = testable.filepath
364
- filename = File.basename( filepath )
365
- name = testable.name
366
- directives_only_filepath = testable.preprocess[:directives_only][:filepath]
367
-
368
- fallback = (!directives_only or directives_only_filepath.nil?)
369
-
370
- arg_hash = {
371
- test: name,
372
- filepath: filepath,
373
- directives_only_filepath: directives_only_filepath,
374
- fallback: fallback,
375
- includes: @context_extractor.lookup_all_header_includes_list( testable.filepath ),
376
- flags: testable.preprocess_flags,
377
- include_paths: testable.search_paths,
378
- vendor_paths: [@configurator.project_build_vendor_ceedling_path],
379
- defines: testable.preprocess_defines
380
- }
381
-
382
- _filepath = @preprocessinator.preprocess_test_file( **arg_hash )
383
-
384
- state.lock.synchronize { testable.runner[:input_filepath] = _filepath }
385
199
 
386
- msg = @reportinator.generate_progress( "Parsing #{filename} for test source directive macros" )
387
- @loginator.log( msg )
200
+ @dependinator.mark_fresh( target )
201
+ end
388
202
 
389
- if fallback
390
- _filepath = filepath
391
- else
392
- _filepath = @file_path_utils.form_preprocessed_file_compacted_directives_only_filepath( filepath, name )
393
- end
203
+ log_skip_summary( task: "mock generation", count: skipped, noun: "mocks" )
204
+ end
394
205
 
395
- @context_extractor.collect_simple_context_from_file(
396
- _filepath,
397
- filepath,
398
- TestContextExtractor::Context::BUILD_DIRECTIVE_SOURCE_FILES
399
- )
206
+ # Stage 15: Compile all test build objects in parallel.
207
+ #
208
+ # An unchanged object skips its compile-execute plugin hooks entirely (see
209
+ # compile_test_component), so plugins that accumulate per-run state from
210
+ # pre_compile_execute/post_compile_execute -- compile_commands_json_db,
211
+ # report_build_warnings_log, bullseye, command_hooks -- only see objects
212
+ # actually recompiled this run, not the full set. Same for stage 16's link
213
+ # hooks. Contrast with stage 17, where Generator#generate_test_results
214
+ # reports a skipped executable's cached result through both fixture-execute
215
+ # hooks regardless, so consumers of *that* pair always see every test.
216
+ #
217
+ # Compiles in two sequential batches -- every test's own file first, in a batch
218
+ # fully completed before any other object starts. compile_test_component's own
219
+ # sibling-header isolation (run only against a test's own file) may correct that
220
+ # testable's search paths; every other object in the same test needs to compile
221
+ # against the corrected paths, never the original ones, and a real barrier
222
+ # between the two groups is the only way parallel compilation can guarantee that.
223
+ #
224
+ # BARRIER INVARIANT (see also apply_sibling_isolation's own note): each pair below
225
+ # runs through @batchinator.exec -- real worker threads via Parallel.map -- and
226
+ # `compile_pass.call( test_file_pairs )` fully drains (Parallel.map blocks until
227
+ # every thread in that call is done) before `compile_pass.call( other_pairs )`
228
+ # even starts. That's what makes apply_sibling_isolation's unguarded writes to
229
+ # testable.search_paths/isolated_headers_path safe: the only thread that ever
230
+ # writes them is the one compiling that test's own file, in the first batch, and
231
+ # every thread reading them afterward starts only once that write has already
232
+ # happened. Merging or reordering these two calls -- e.g. to parallelize them
233
+ # together for speed -- would reintroduce a real, unguarded data race on those
234
+ # fields, confirmed experimentally (see concurrency-file-presence-factfinding
235
+ # memory, Finding 4): a merged single-pass variant of this exact shape saw
236
+ # violations on 97%+ of reads once the barrier was removed.
237
+ def stage_build_objects(state)
238
+ skipped = 0
400
239
 
401
- state.testables.each do |_, t|
402
- validate_build_directive_source_files( test: name, filepath: t.filepath )
403
- end
240
+ resolved = state.objects_list.map do |obj|
241
+ src = @file_finder.find_build_input_file( filepath: obj.obj, context: state.context, test: obj.test )
242
+ [obj, src]
404
243
  end
405
- end
406
244
 
407
- # Stage 12: Collect test runner details (test case names) from preprocessed test files.
408
- def stage_collect_runner_details(state)
409
- @batchinator.exec(workload: :compile, things: state.testables) do |_, testable|
410
- msg = @reportinator.generate_module_progress(
411
- operation: 'Parsing test case names',
412
- module_name: testable.name,
413
- filename: File.basename( testable.filepath )
414
- )
415
- @loginator.log( msg )
245
+ test_file_pairs, other_pairs = resolved.partition do |obj, src|
246
+ testable = state.testables[obj.test.to_sym]
247
+ !testable.nil? && src == testable.filepath
248
+ end
416
249
 
417
- @context_extractor.collect_test_runner_details( testable.filepath, testable.runner[:input_filepath] )
250
+ compile_pass = lambda do |pairs|
251
+ @batchinator.exec(workload: :compile, things: pairs) do |obj, src|
252
+ compiled = compile_test_component(
253
+ context: state.context,
254
+ test: obj.test,
255
+ source: src,
256
+ object: obj.obj,
257
+ state: state
258
+ )
259
+ state.lock.synchronize { skipped += 1 } unless compiled
260
+ end
418
261
  end
419
- end
420
262
 
421
- # Stage 13: Generate test runner files.
422
- def stage_generate_runners(state)
423
- @batchinator.exec(workload: :compile, things: state.testables) do |_, testable|
424
- arg_hash = {
425
- context: state.context,
426
- mocks: @context_extractor.lookup_mock_header_includes_list( testable.filepath ),
427
- includes: @context_extractor.lookup_nonmock_header_includes_list( testable.filepath ),
428
- test_filepath: testable.filepath,
429
- input_filepath: testable.runner[:input_filepath],
430
- runner_filepath: testable.runner[:output_filepath]
431
- }
263
+ compile_pass.call( test_file_pairs )
264
+ compile_pass.call( other_pairs )
432
265
 
433
- @generator.generate_test_runner( **arg_hash )
266
+ # Any isolated sibling-header copy staged for a testable during either batch
267
+ # above was scoped to this one build and never registered as a tracked
268
+ # dependency in its own right (see isolate_sibling_headers) -- nothing past
269
+ # this point still needs it to exist.
270
+ state.testables.each_value do |testable|
271
+ next if testable.isolated_headers_path.nil?
272
+ @quote_include_isolator.release( testable.isolated_headers_path )
434
273
  end
435
- end
436
274
 
437
- # Stage 15: Compile all test build objects in parallel.
438
- def stage_build_objects(state)
439
- @batchinator.exec(workload: :compile, things: state.objects_list) do |obj|
440
- src = @file_finder.find_build_input_file( filepath: obj[:obj], context: state.context )
441
- compile_test_component(
442
- context: state.context,
443
- test: obj[:test],
444
- source: src,
445
- object: obj[:obj],
446
- state: state
447
- )
448
- end
275
+ log_skip_summary( task: "compilation", count: skipped, noun: "objects" )
449
276
  end
450
277
 
451
278
  # Stage 16: Link test executables.
452
279
  def stage_build_executables(state)
453
280
  lib_args = convert_libraries_to_arguments()
454
281
  lib_paths = get_library_paths_to_arguments()
282
+ skipped = 0
455
283
 
456
284
  @batchinator.exec(workload: :compile, things: state.testables) do |_, testable|
457
285
  remove_partials_source_objects( testable.objects, testable.partials.configs )
458
286
 
459
- arg_hash = {
460
- context: state.context,
461
- build_path: testable.paths[:build],
462
- executable: testable.executable,
463
- objects: testable.objects,
464
- flags: testable.link_flags,
465
- lib_args: lib_args,
466
- lib_paths: lib_paths,
467
- options: state.options
468
- }
287
+ link_flags = testable.link_flags
288
+ tool, link_flags = resolve_link_tool( context: state.context, tool: @configurator.tools_test_linker, flags: link_flags, executable: testable.executable )
289
+
290
+ @dependinator.register(
291
+ testable.executable,
292
+ files: testable.objects,
293
+ meta: { flags: link_flags, lib_args: lib_args, lib_paths: lib_paths, tools: [tool] }
294
+ )
295
+ stale = @dependinator.stale?( testable.executable )
296
+
297
+ if stale
298
+ arg_hash = {
299
+ context: state.context,
300
+ build_path: testable.paths[:build],
301
+ executable: testable.executable,
302
+ objects: testable.objects,
303
+ flags: link_flags,
304
+ lib_args: lib_args,
305
+ lib_paths: lib_paths,
306
+ tool: tool
307
+ }
308
+
309
+ generate_executable( **arg_hash )
469
310
 
470
- generate_executable_now( **arg_hash )
311
+ @dependinator.mark_fresh( testable.executable )
312
+ else
313
+ msg = @reportinator.generate_module_progress(
314
+ operation: 'Skipping linking for',
315
+ module_name: testable.name,
316
+ filename: File.basename( testable.executable )
317
+ )
318
+ @loginator.log( msg, Verbosity::OBNOXIOUS )
319
+ state.lock.synchronize { skipped += 1 }
320
+ end
321
+
322
+ @generator.generate_test_executable_manifest( executable: testable.executable, test_filepath: testable.filepath )
323
+
324
+ # Stage 17 relies on this rather than a second `stale?` call -- by the
325
+ # time it runs, `mark_fresh` above (when `stale` was true) has already
326
+ # updated the cache entry to match the executable's current state, so a
327
+ # fresh `stale?` query would always answer false.
328
+ state.lock.synchronize { testable.executable_rebuilt = stale }
471
329
  end
330
+
331
+ log_skip_summary( task: "linking", count: skipped, noun: "executables" )
472
332
  end
473
333
 
474
334
  # Stage 17: Execute test fixtures and collect results.
335
+ #
336
+ # An executable that didn't need relinking (see stage 16) still has valid
337
+ # cached results on disk from whenever it was last built -- Generator#generate_test_results
338
+ # reports those instead of actually (re)running it, per `skipped:` below.
339
+ #
340
+ # `:force_test_rerun` and `:unity ↳ :shuffle_tests` both override that skip:
341
+ # shuffled test-case order is decided at runtime inside the executable itself
342
+ # (Unity's generated `main()` reshuffles on every invocation), not at compile
343
+ # or link time, so an executable that's otherwise unchanged still needs to
344
+ # actually run again for shuffling to have any effect at all.
345
+ #
346
+ # The dependency tracker gives a third reason to rerun, alongside those two:
347
+ # `testable.executable` unchanged says nothing about whether the *tool* that
348
+ # actually runs it -- :tools ↳ :test_fixture -- changed since the last run.
349
+ # This target is registered separately from stage 16's own executable target
350
+ # (not reusing it) so a tool-only change reruns the fixture without also
351
+ # marking the executable itself stale and forcing an unnecessary relink.
352
+ #
353
+ # The command line test case filters (--test-case, --exclude_test_case) are a fourth.
354
+ # When :test_runner ↳ :cmdline_args is on, as any :use_backtrace other than :none makes
355
+ # it, a filtered and an unfiltered executable are identical, and only the filter tells
356
+ # one run's results from another's. See fixture_meta.
357
+ #
358
+ # The target itself is a dedicated marker file, not either outcome-dependent
359
+ # results file (.pass/.fail) -- which of those two actually gets written
360
+ # depends on whether the test passes, so neither is guaranteed to exist after
361
+ # every run, and a target `mark_fresh` can't hash is a crash on a failing
362
+ # test, while a target `stale?` can't find is permanent, unwanted staleness
363
+ # for a test that keeps failing the same way. The marker's own content is
364
+ # irrelevant and never changes -- only its existence (written after every
365
+ # real run, pass or fail alike) and the registered files/meta drive staleness.
475
366
  def stage_execute(state)
367
+ skipped = 0
368
+ force_rerun = @configurator.force_test_rerun || @configurator.unity_shuffle_tests
369
+
370
+ overridden = state.testables.values.count { |t| !t.executable_rebuilt }
371
+
372
+ if @configurator.unity_shuffle_tests && overridden > 0
373
+ noun = overridden == 1 ? 'test executable' : 'test executables'
374
+ @loginator.log(
375
+ "Test shuffling is enabled -- rerunning #{overridden} already up-to-date #{noun} to randomize test case order.",
376
+ Verbosity::NORMAL,
377
+ LogLabels::NOTICE
378
+ )
379
+ end
380
+
476
381
  @batchinator.exec(workload: :test, things: state.testables) do |_, testable|
477
382
  begin
383
+ # `paths[:results]` is only per-test-unique for a test mirrored into its own
384
+ # subdirectory -- a test with no mirrored subdir shares that directory with
385
+ # every other such test, so the marker's own filename (not just its directory)
386
+ # must be test-specific too, matching clean_test_results' own `test + '.*'`
387
+ # naming below.
388
+ fixture_target = File.join( testable.paths[:results], "#{File.basename( testable.name )}.fixture_run" )
389
+
390
+ fixture_tool = resolve_fixture_tool( context: state.context, tool: @configurator.tools_test_fixture, test_name: testable.name, target: fixture_target )
391
+
392
+ # :use_backtrace doesn't swap the fixture tool itself (unlike Valgrind/Gcov's own
393
+ # pre_test_fixture_register hooks) -- it only selects what happens *after*
394
+ # run_fixture detects a crash (generator.rb's own case on :project_use_backtrace:
395
+ # :gdb runs tools_test_backtrace_gdb, :simple runs tools_test_fixture_simple_backtrace,
396
+ # :none does neither). Without capturing that selector (and the tool config(s) it
397
+ # actually drives) as meta here, toggling :use_backtrace -- or editing a backtrace
398
+ # tool's own executable/args -- would never invalidate this fixture_target, so a
399
+ # delta build would keep reusing a stale crash-diagnosis result on the next crash.
400
+ #
401
+ # tools_test_backtrace_gdb only exists at all when :use_backtrace is :gdb --
402
+ # Configurator only merges its defaults (DEFAULT_TOOLS_TEST_GDB_BACKTRACE) in that
403
+ # case (configurator.rb) -- so it's only read here when actually relevant.
404
+ # tools_test_fixture_simple_backtrace has no such gate (DEFAULT_TOOLS_TEST always
405
+ # includes it) and is always safe to read.
406
+ use_backtrace = @configurator.project_config_hash[:project_use_backtrace]
407
+ backtrace_tools = [@configurator.tools_test_fixture_simple_backtrace]
408
+ backtrace_tools << @configurator.tools_test_backtrace_gdb if use_backtrace == :gdb
409
+
410
+ @dependinator.register(
411
+ fixture_target, files: [testable.executable],
412
+ meta: fixture_meta( fixture_tool: fixture_tool, use_backtrace: use_backtrace, backtrace_tools: backtrace_tools )
413
+ )
414
+
415
+ run_now = testable.executable_rebuilt || force_rerun || @dependinator.stale?( fixture_target )
416
+
417
+ # Clear out any stale prior result (e.g. a lingering `.fail` from a test
418
+ # that now passes) immediately before an actual (re)run -- not upfront
419
+ # for every test regardless of whether it's about to run, which would
420
+ # destroy the still-valid cached result of a test left unchanged.
421
+ clean_test_results( testable.paths[:results], File.basename( testable.name ) ) if run_now
422
+
423
+ unless run_now
424
+ msg = @reportinator.generate_module_progress(
425
+ operation: 'Skipping test execution for',
426
+ module_name: testable.name,
427
+ filename: File.basename( testable.executable )
428
+ )
429
+ @loginator.log( msg, Verbosity::OBNOXIOUS )
430
+ state.lock.synchronize { skipped += 1 }
431
+ end
432
+
478
433
  arg_hash = {
479
434
  context: state.context,
480
435
  test_name: testable.name,
481
436
  test_filepath: testable.filepath,
482
437
  executable: testable.executable,
483
438
  result: testable.results_pass,
484
- options: state.options
439
+ skipped: !run_now,
440
+ tool: fixture_tool
485
441
  }
486
442
 
487
- run_fixture_now( **arg_hash )
443
+ run_fixture( **arg_hash )
444
+
445
+ if run_now
446
+ @file_wrapper.touch( fixture_target )
447
+
448
+ # A later skipped run reuses the result this run wrote, so the fixture target
449
+ # vouches for it. Only whichever of the two exists is recorded.
450
+ @dependinator.register(
451
+ fixture_target,
452
+ outputs: [testable.results_pass, testable.results_pass.ext( @configurator.extension_testfail.primary )]
453
+ )
454
+ @dependinator.mark_fresh( fixture_target )
455
+ end
488
456
 
489
457
  ensure
490
458
  @plugin_manager.post_test( testable.filepath )
491
459
  end
492
460
  end
461
+
462
+ # `@batchinator.exec` above fully drains before returning -- every test executable
463
+ # in this run has finished executing, so this is the one correct point to flush the
464
+ # whole-suite gdb health summary, once, before final results reporting.
465
+ @generator.report_gdb_attach_health()
466
+
467
+ log_skip_summary( task: "test execution", count: skipped, noun: "tests", reason: "reusing cached results" )
493
468
  end
494
469
 
495
470
  # -----------------------------------------------------------------------
496
471
  # Helper methods
497
472
  # -----------------------------------------------------------------------
498
473
 
499
- def generate_executable_now(context:, build_path:, executable:, objects:, flags:, lib_args:, lib_paths:, options:)
474
+ # What a test fixture's run depends on besides its executable. An unset filter, nil or
475
+ # empty, is one value, so an unfiltered run keeps a stable key.
476
+ def fixture_meta(fixture_tool:, use_backtrace:, backtrace_tools:)
477
+ return {
478
+ tools: [fixture_tool],
479
+ use_backtrace: use_backtrace,
480
+ backtrace_tools: backtrace_tools,
481
+ include_test_case: @configurator.include_test_case.to_s,
482
+ exclude_test_case: @configurator.exclude_test_case.to_s
483
+ }
484
+ end
485
+
486
+ def generate_executable(context:, build_path:, executable:, objects:, flags:, lib_args:, lib_paths:, tool:)
500
487
  begin
501
488
  @generator.generate_executable_file(
502
- options[:test_linker],
489
+ tool,
503
490
  context,
504
491
  objects.map { |v| "\"#{v}\"" },
505
492
  flags,
@@ -509,7 +496,7 @@ class TestBuildExecutor
509
496
  lib_paths
510
497
  )
511
498
  rescue ShellException => ex
512
- if ex.shell_result[:output] =~ /symbol/i
499
+ if ex.shell_result[:output].match?(/symbol/i)
513
500
  notice = "If the linker reports missing symbols, the following may be to blame:\n" +
514
501
  " 1. This test lacks #include statements corresponding to needed source files (see note below).\n" +
515
502
  " 2. Project file paths omit source files corresponding to #include statements in this test.\n" +
@@ -520,7 +507,7 @@ class TestBuildExecutor
520
507
  end
521
508
 
522
509
  notice += "\n"
523
- notice += "NOTE: A test file directs the build of a test executable with #include statemetns:\n" +
510
+ notice += "NOTE: A test file directs the build of a test executable with #include statements:\n" +
524
511
  " * By convention, Ceedling assumes header filenames correspond to source filenames.\n" +
525
512
  " * Which code files to compile and link are determined by #include statements.\n"
526
513
  if @configurator.project_use_mocks
@@ -532,7 +519,7 @@ class TestBuildExecutor
532
519
  " 1. Doublecheck this test's #include statements.\n" +
533
520
  " 2. Simplify complex macros or fully specify symbols for this test in :project ↳ :defines.\n" +
534
521
  " 3. If no header file corresponds to the needed source file, use the TEST_SOURCE_FILE()\n" +
535
- " build diective macro in this test to inject a source file into the build.\n\n" +
522
+ " build directive macro in this test to inject a source file into the build.\n\n" +
536
523
  "See the docs on conventions, paths, preprocessing, compilation symbols, and build directive macros.\n\n"
537
524
 
538
525
  @loginator.log( notice, Verbosity::COMPLAIN, LogLabels::NOTICE )
@@ -542,14 +529,19 @@ class TestBuildExecutor
542
529
  end
543
530
  end
544
531
 
545
- def run_fixture_now(context:, test_name:, test_filepath:, executable:, result:, options:)
532
+ def clean_test_results(path, test)
533
+ @file_wrapper.rm_f( Dir.glob( File.join( path, test + '.*' ) ) )
534
+ end
535
+
536
+ def run_fixture(context:, test_name:, test_filepath:, executable:, result:, tool:, skipped: false)
546
537
  @generator.generate_test_results(
547
- tool: options[:test_fixture],
538
+ tool: tool,
548
539
  context: context,
549
540
  test_name: test_name,
550
541
  test_filepath: test_filepath,
551
542
  executable: executable,
552
- result: result
543
+ result: result,
544
+ skipped: skipped
553
545
  )
554
546
  end
555
547
 
@@ -571,17 +563,78 @@ class TestBuildExecutor
571
563
 
572
564
  private
573
565
 
574
- # Compile a single C or assembly source file into an object file.
566
+ # Finds the folder a mock's #include names and the directory the mock is written to.
567
+ #
568
+ # CMock names a mock's guard and lifecycle functions by that folder, and the runner names
569
+ # its calls by the same #include. Two same-named mocks stay distinct only if the folder
570
+ # reaches CMock. CMock writes below its own root at that folder, so the folder must end the
571
+ # mock's directory. A folder trailing the mirrored location keeps that location. An #include
572
+ # spelling more path than the mirror holds moves its mock below the per-test root at the
573
+ # written path, which the root search path still reaches. A bare #include has no folder.
574
+ # Without :mock_name_include_folder no folder is passed, and CMock names by filename alone.
575
+ def mock_folder_and_path(mocks_root, output_path, include_path)
576
+ return [nil, output_path] unless @configurator.cmock_mock_name_include_folder
577
+
578
+ folder = File.dirname( include_path.to_s ).sub( %r{\A(?:\./)+}, '' )
579
+
580
+ return [nil, output_path] if folder.empty? || folder == '.'
581
+ return [folder, output_path] if output_path.end_with?( File.join( '', folder ) )
582
+
583
+ return [folder, File.join( mocks_root, folder )]
584
+ end
585
+
586
+ # Compile a single C or assembly source file into an object file. Returns
587
+ # whether a real compile actually happened, so the caller can report how
588
+ # many objects across the whole build needed nothing done.
589
+ #
590
+ # A test file's own C compile (only) gets one extra check: isolate_sibling_headers
591
+ # inspects its freshly-written .d file for a real header sharing a directory with
592
+ # one this test mocks or Partializes, and retries with corrected search paths if
593
+ # it finds one. A failure that's still standing afterward -- nothing to isolate,
594
+ # or an isolated retry that failed too -- gets one last look from generator_helper
595
+ # before it's raised, in case it's explainable as this same class of collision.
596
+ #
597
+ # Any other source sharing a directory with a header mocked under inline shadowing
598
+ # compiles from an isolated copy instead (compile_isolated_source).
575
599
  def compile_test_component(context:, test:, source:, object:, state:)
576
600
  testable = state.testables[test.to_sym]
577
601
  defines = testable.compile_defines
578
602
  search_paths = tailor_search_paths( search_paths: testable.search_paths, filepath: source )
603
+ dependencies = @file_path_utils.form_test_dependencies_filepath( object, name: test, context: context )
579
604
 
580
- if @file_wrapper.extname( source ) != @configurator.extension_assembly
605
+ if !@configurator.extension_assembly.match?( source )
581
606
  flags = testable.compile_flags
607
+ tool, flags, defines = resolve_compile_tool(
608
+ context: context, operation: OPERATION_COMPILE_SYM, tool: @configurator.tools_test_compiler,
609
+ flags: flags, defines: defines, module_name: test, source: source, object: object
610
+ )
611
+ stale = register_and_check_object_staleness( object: object, source: source, dependencies: dependencies, flags: flags, defines: defines, search_paths: search_paths, tool: tool )
612
+
613
+ unless stale
614
+ # A skipped compile still needs this test's search paths corrected the same
615
+ # way a real compile would have left them -- otherwise every other object in
616
+ # this test's build (compiled or skipped) would compute its own staleness
617
+ # against paths that silently drift from whatever the last real compile
618
+ # actually cached, forcing a recompile on every subsequent build regardless
619
+ # of whether anything actually changed. The existing .d file already on disk
620
+ # (from whichever run last actually compiled this file) is what a skip has
621
+ # to go on -- there's no fresh one to write this run.
622
+ if source == testable.filepath && @file_wrapper.exist_with_retry?( dependencies )
623
+ apply_sibling_isolation( testable: testable, dependencies_filepath: dependencies )
624
+ end
625
+
626
+ return log_compile_skip( test: test, source: source )
627
+ end
628
+
629
+ # A module-under-test or support source mirrored into its own subdirectory needs that
630
+ # subdirectory (and its dependencies-file counterpart) to actually exist before the
631
+ # compiler can write there -- the test's own per-test directories are pre-created
632
+ # upfront, but a mirrored subdirectory beneath one is not.
633
+ @file_wrapper.mkdir( File.dirname( object ) )
634
+ @file_wrapper.mkdir( File.dirname( dependencies ) )
582
635
 
583
636
  arg_hash = {
584
- tool: @configurator.tools_test_compiler,
637
+ tool: tool,
585
638
  module_name: test,
586
639
  context: context,
587
640
  source: source,
@@ -590,16 +643,82 @@ class TestBuildExecutor
590
643
  flags: flags,
591
644
  defines: defines,
592
645
  list: @file_path_utils.form_test_build_list_filepath( object ),
593
- dependencies: @file_path_utils.form_test_dependencies_filepath( object, name: test, context: context )
646
+ dependencies: dependencies
594
647
  }
595
648
 
596
- @generator.generate_object_file_c( **arg_hash )
649
+ compile_failure = nil
650
+ shadowed_header = inline_mocked_sibling_header( testable, source )
651
+
652
+ if shadowed_header
653
+ compile_failure = compile_isolated_source( arg_hash: arg_hash, testable: testable, header: shadowed_header )
654
+ else
655
+ begin
656
+ @generator.generate_object_file_c( **arg_hash )
657
+ rescue ShellException => ex
658
+ compile_failure = ex
659
+ end
660
+ end
661
+
662
+ # gcc's dependency output is a side effect of preprocessing -- already written to
663
+ # disk by the time a later parse/type-check phase can still fail -- so this
664
+ # attempt's own .d file is worth registering whether or not it went on to fail.
665
+ # exist_with_retry? rides out the file briefly not yet being visible right after
666
+ # the shell-out exits (a raw miss here silently drops this compile's discovered
667
+ # header dependencies -- self-correcting into one extra recompile next run, but
668
+ # worth riding out directly).
669
+ @dependinator.register_gcc_deps_file( dependencies ) if @file_wrapper.exist_with_retry?( dependencies )
670
+
671
+ # Only the test file's own compile is ever checked here directly -- every other
672
+ # object in the same test's build already sees whatever search paths that check
673
+ # settled on (see stage_build_objects's own two-pass split).
674
+ if source == testable.filepath && @file_wrapper.exist_with_retry?( dependencies )
675
+ isolation = apply_sibling_isolation( testable: testable, dependencies_filepath: dependencies )
676
+
677
+ if isolation
678
+ # A throwaway retry: its own .d file is never registered, so the attempt
679
+ # registered just above -- real headers, real paths -- remains the lasting
680
+ # record of this object's antecedents. The isolated copy is always freshly,
681
+ # fully derived from those same tracked files, so it can never itself go
682
+ # stale independently and needs no tracking of its own.
683
+ retry_arg_hash = arg_hash.merge(
684
+ search_paths: tailor_search_paths( search_paths: isolation[:search_paths], filepath: source ),
685
+ dependencies: dependencies + '.isolated_retry'
686
+ )
687
+
688
+ begin
689
+ @generator.generate_object_file_c( **retry_arg_hash )
690
+ compile_failure = nil
691
+ rescue ShellException => ex
692
+ compile_failure = ex
693
+ end
694
+ end
695
+ end
696
+
697
+ if compile_failure
698
+ notice = @generator_helper.explain_possible_mock_partial_collision(
699
+ output: compile_failure.shell_result[:output],
700
+ mocked_headers: mocked_and_partialized_headers( testable )
701
+ )
702
+ @loginator.log( notice, Verbosity::ERRORS, LogLabels::NOTICE ) if notice
703
+
704
+ raise compile_failure
705
+ end
597
706
 
598
707
  elsif @configurator.test_build_use_assembly
599
708
  flags = testable.assembler_flags
709
+ tool, flags, defines = resolve_compile_tool(
710
+ context: context, operation: OPERATION_ASSEMBLE_SYM, tool: @configurator.tools_test_assembler,
711
+ flags: flags, defines: defines, module_name: test, source: source, object: object
712
+ )
713
+ stale = register_and_check_object_staleness( object: object, source: source, dependencies: dependencies, flags: flags, defines: defines, search_paths: search_paths, tool: tool )
714
+
715
+ return log_compile_skip( test: test, source: source ) unless stale
716
+
717
+ @file_wrapper.mkdir( File.dirname( object ) )
718
+ @file_wrapper.mkdir( File.dirname( dependencies ) )
600
719
 
601
720
  arg_hash = {
602
- tool: @configurator.tools_test_assembler,
721
+ tool: tool,
603
722
  module_name: test,
604
723
  context: context,
605
724
  source: source,
@@ -608,80 +727,332 @@ class TestBuildExecutor
608
727
  flags: flags,
609
728
  defines: defines,
610
729
  list: @file_path_utils.form_test_build_list_filepath( object ),
611
- dependencies: @file_path_utils.form_test_dependencies_filepath( object, name: test, context: context )
730
+ dependencies: dependencies
612
731
  }
613
732
 
614
733
  @generator.generate_object_file_asm( **arg_hash )
734
+
735
+ # register_gcc_deps_file again to pick up the freshly-written `.d` file's current
736
+ # header set (a no-op call here regardless, since the assembler tool has no
737
+ # -MMD/-MF of its own) before recording this target's new baseline.
738
+ @dependinator.register_gcc_deps_file( dependencies ) if @file_wrapper.exist_with_retry?( dependencies )
739
+ else
740
+ return false
615
741
  end
742
+
743
+ @dependinator.mark_fresh( object )
744
+
745
+ true
616
746
  end
617
747
 
618
- def tailor_search_paths(filepath:, search_paths:)
619
- _search_paths = []
620
-
621
- if filepath == File.join( PROJECT_BUILD_VENDOR_UNITY_PATH, UNITY_C_FILE )
622
- _search_paths += @configurator.collection_paths_support
623
- _search_paths << PROJECT_BUILD_VENDOR_UNITY_PATH
624
-
625
- elsif @configurator.project_use_mocks and
626
- (filepath == File.join( PROJECT_BUILD_VENDOR_CMOCK_PATH, CMOCK_C_FILE ))
627
- _search_paths += @configurator.collection_paths_support
628
- _search_paths << PROJECT_BUILD_VENDOR_UNITY_PATH
629
- _search_paths << PROJECT_BUILD_VENDOR_CMOCK_PATH
630
- _search_paths << PROJECT_BUILD_VENDOR_CEXCEPTION_PATH if @configurator.project_use_exceptions
631
-
632
- elsif @configurator.project_use_exceptions and
633
- (filepath == File.join( PROJECT_BUILD_VENDOR_CEXCEPTION_PATH, CEXCEPTION_C_FILE ))
634
- _search_paths += @configurator.collection_paths_support
635
- _search_paths << PROJECT_BUILD_VENDOR_CEXCEPTION_PATH
636
-
637
- elsif @configurator.collection_all_support.include?( filepath )
638
- _search_paths = search_paths
639
- _search_paths += @configurator.collection_paths_support
640
- _search_paths << PROJECT_BUILD_VENDOR_UNITY_PATH
641
- _search_paths << PROJECT_BUILD_VENDOR_CMOCK_PATH if @configurator.project_use_mocks
642
- _search_paths << PROJECT_BUILD_VENDOR_CEXCEPTION_PATH if @configurator.project_use_exceptions
748
+ # The mocked header `source` would reach directly in place of its mock, or nil.
749
+ #
750
+ # With :treat_inlines set to :include, CMock writes an inline-stripped copy of a mocked
751
+ # header into the mocks directory, first on the search path. A source sharing a directory
752
+ # with the real header and quote-including it finds the real one first. Its inline bodies
753
+ # then run in place of the mock. A Partial mock writes no such copy, and a test file
754
+ # reaches its mocks by their own names.
755
+ def inline_mocked_sibling_header(testable, source)
756
+ return nil unless @configurator.project_use_mocks
757
+ return nil unless @configurator.cmock_treat_inlines == :include
758
+ return nil if source == testable.filepath
759
+
760
+ directory = File.expand_path( File.dirname( source ) )
761
+
762
+ (testable.mocks || {}).each_value do |details|
763
+ next if details.partial || details.source.nil?
764
+ next unless File.expand_path( File.dirname( details.source ) ) == directory
765
+
766
+ header = File.basename( details.source )
767
+ return details.source if @quote_include_isolator.includes_by_name?( source, header )
643
768
  end
644
769
 
645
- return search_paths if _search_paths.empty?
770
+ return nil
771
+ end
646
772
 
647
- return _search_paths.uniq
773
+ # Compiles a source from a copy staged alone, returning any compile failure.
774
+ #
775
+ # With no real header beside the copy, its quoted #include of `header` reaches CMock's
776
+ # inline-stripped copy on the search path. A #line directive keeps every report naming
777
+ # the original. The original's directory follows all other search paths so its other
778
+ # includes still resolve. The dependency file is restored before the copy is released,
779
+ # so tracking never names a file that no longer exists.
780
+ def compile_isolated_source(arg_hash:, testable:, header:)
781
+ source = arg_hash[:source]
782
+
783
+ msg = "Compiling an isolated copy of '#{source}' for this test because it shares a directory with " \
784
+ "mocked header '#{header}', whose inline functions it would otherwise call instead of the mock."
785
+ @loginator.log( msg, Verbosity::NORMAL, LogLabels::NOTICE )
786
+
787
+ @quote_include_isolator.within( parent: testable.paths[:build], files: [source], preserve_location: true ) do |isolation|
788
+ begin
789
+ @generator.generate_object_file_c(
790
+ **arg_hash.merge(
791
+ compile_source: isolation.copy_of( source ),
792
+ search_paths: arg_hash[:search_paths] + [File.dirname( source )]
793
+ )
794
+ )
795
+ nil
796
+ rescue ShellException => ex
797
+ ex
798
+ ensure
799
+ @quote_include_isolator.restore_dependencies( isolation, arg_hash[:dependencies] )
800
+ end
801
+ end
648
802
  end
649
803
 
650
- def validate_build_directive_source_files(test:, filepath:)
651
- sources = @test_context_extractor.lookup_build_directive_sources_list( filepath )
804
+ def log_compile_skip(test:, source:)
805
+ msg = @reportinator.generate_module_progress(
806
+ operation: 'Skipping compilation for',
807
+ module_name: test,
808
+ filename: File.basename( source )
809
+ )
810
+ @loginator.log( msg, Verbosity::OBNOXIOUS )
811
+ false
812
+ end
652
813
 
653
- ext_message = @configurator.extension_source
654
- if @configurator.test_build_use_assembly
655
- ext_message += " or #{@configurator.extension_assembly}"
656
- end
814
+ # Lets a plugin swap in its own compiler tool (and adjust flags/defines) for a
815
+ # particular build context -- e.g. Gcov/Bullseye's instrumented compilers -- via
816
+ # pre_test_compile_register, *before* dependency-tracker meta is computed below, so a
817
+ # plugin's own tool config is what actually drives that target's staleness rather
818
+ # than the plain test compiler it's about to be swapped out for. The resolved
819
+ # values are also what the real compile itself uses (see the two call sites
820
+ # above), so the two can never disagree about which tool actually ran.
821
+ def resolve_compile_tool(context:, operation:, tool:, flags:, defines:, module_name:, source:, object:)
822
+ arg_hash = {
823
+ context: context, operation: operation, tool: tool, flags: flags, defines: defines,
824
+ module_name: module_name, source: source, object: object
825
+ }
826
+ @plugin_manager.pre_test_compile_register( arg_hash )
827
+ return arg_hash[:tool], arg_hash[:flags], arg_hash[:defines]
828
+ end
657
829
 
658
- sources.each do |source|
659
- valid_extension = true
830
+ # As resolve_compile_tool above, for the link step's own tool swap (pre_test_link_register),
831
+ # e.g. Gcov/Bullseye's instrumented linkers.
832
+ def resolve_link_tool(context:, tool:, flags:, executable:)
833
+ arg_hash = { context: context, tool: tool, flags: flags, executable: executable }
834
+ @plugin_manager.pre_test_link_register( arg_hash )
835
+ return arg_hash[:tool], arg_hash[:flags]
836
+ end
660
837
 
661
- if not @configurator.test_build_use_assembly
662
- valid_extension = false if @file_wrapper.extname( source ) != @configurator.extension_source
663
- else
664
- ext = @file_wrapper.extname( source )
665
- valid_extension = false if (ext != @configurator.extension_assembly) and (ext != @configurator.extension_source)
666
- end
838
+ # As resolve_compile_tool/resolve_link_tool above, for the test-fixture step's own
839
+ # tool swap (pre_test_fixture_register), e.g. Valgrind wrapping the executable.
840
+ # `target` (the fixture-run marker target -- see stage_execute) is included so a
841
+ # plugin can register additional meta of its own against the same target, merging
842
+ # with what this stage registers immediately after -- Dependinator#register is
843
+ # additive across multiple calls for one target regardless of call order.
844
+ def resolve_fixture_tool(context:, tool:, test_name:, target:)
845
+ arg_hash = { context: context, tool: tool, test_name: test_name, target: target }
846
+ @plugin_manager.pre_test_fixture_register( arg_hash )
847
+ return arg_hash[:tool]
848
+ end
667
849
 
668
- if not valid_extension
669
- error = "File '#{source}' specified with TEST_SOURCE_FILE() in #{test} is not a #{ext_message} source file"
670
- raise CeedlingException.new( error )
850
+ # Checks `dependencies_filepath` (this test's own most recent `.d` file, whether
851
+ # freshly written by a real compile just now or left over from whichever run
852
+ # last actually compiled it) for a sibling-header risk, and mutates `testable`
853
+ # in place to apply whatever it finds -- the one path both a real compile and a
854
+ # skipped one share, so search_paths reads the same way regardless of which one
855
+ # happened this run. Returns whatever isolate_sibling_headers itself returned.
856
+ # BARRIER INVARIANT (see also stage_build_objects's own note): the writes below to
857
+ # testable.search_paths/isolated_headers_path are completely unguarded -- no mutex --
858
+ # which is only safe because this method is only ever called while compiling a
859
+ # test's own file, and stage_build_objects's two-pass split guarantees every other
860
+ # object belonging to that same test compiles in a later, separate batch that starts
861
+ # only after this one has fully finished. That ordering, not anything visible at
862
+ # these two lines, is the entire safety argument -- do not call this from, or read
863
+ # these fields during, a batch that could run concurrently with a test's own-file
864
+ # compile.
865
+ def apply_sibling_isolation(testable:, dependencies_filepath:)
866
+ isolation = isolate_sibling_headers( testable: testable, dependencies_filepath: dependencies_filepath )
867
+ return nil if isolation.nil?
868
+
869
+ testable.search_paths = isolation[:search_paths]
870
+ testable.isolated_headers_path = isolation[:isolation_dir]
871
+
872
+ isolation
873
+ end
874
+
875
+ # A mock or Partial substitutes a header only by way of search-path order -- a
876
+ # module reaching the same real header a second way, unmocked, can slip past the
877
+ # substitution entirely, silently, because C's own quote-include rule checks a
878
+ # file's own directory before ever consulting a search path. A test file's own
879
+ # freshly-compiled `.d` file already reveals every real header reachable from
880
+ # it, mocked/Partialized or not, which is enough to know where that risk exists
881
+ # even though it says nothing about whether any given occurrence actually won.
882
+ #
883
+ # For each header this test mocks or Partializes, any other file sharing its real
884
+ # directory in that dependency list, that itself actually #includes the real
885
+ # header by name, is staged, alone, into an isolated directory -- with nothing
886
+ # else there for its own #include of the real header to find, that #include is
887
+ # forced through the search paths that list the mock/Partial first. Actually
888
+ # #including the real header is the deciding signal, not mere co-residency: most
889
+ # real projects keep every header in one shared directory as a matter of
890
+ # ordinary convention, so "shares a directory" alone would flag nearly every
891
+ # file in the project. Only one level deep: a directory elsewhere in the same
892
+ # dependency list that shares no header with any of this test's own mocks or
893
+ # Partials, but itself holds more than one candidate, is shaped the same way
894
+ # and reported, but nothing designates which of its occupants should win, so
895
+ # nothing there is acted on.
896
+ #
897
+ # Returns nil when nothing needs isolating; otherwise a hash of the search
898
+ # paths to compile with (isolation directory listed first) and that directory's
899
+ # own path, for the caller to track and eventually clean up.
900
+ def isolate_sibling_headers(testable:, dependencies_filepath:)
901
+ mocked_headers = mocked_and_partialized_headers( testable )
902
+ return nil if mocked_headers.empty?
903
+
904
+ parsed = @gcc_dependency_parser.parse( @file_wrapper.read( dependencies_filepath ) )
905
+ dependencies = parsed.values.flatten.uniq
906
+ by_directory = dependencies.group_by { |dep| File.dirname( dep ) }
907
+
908
+ isolated = []
909
+ mocked_dirs = mocked_headers.values.map { |real_path| File.dirname( real_path ) }.uniq
910
+
911
+ mocked_headers.each_value do |real_path|
912
+ next unless dependencies.include?( real_path )
913
+
914
+ basename = File.basename( real_path )
915
+ siblings = (by_directory[File.dirname( real_path )] || []) - [real_path]
916
+ # A same-directory file is only a genuine risk if it actually #includes the
917
+ # real header by name -- most real projects keep every header in one shared
918
+ # directory, so "shares a directory" alone would flag nearly everything.
919
+ siblings = siblings.select { |sibling| @quote_include_isolator.includes_by_name?( sibling, basename ) }
920
+ next if siblings.empty?
921
+
922
+ siblings.each do |sibling|
923
+ isolated << sibling
924
+
925
+ msg = "Isolated '#{sibling}' into its own directory for this test's build because it shares a " \
926
+ "directory with '#{real_path}' and C conventions could bypass mock substitution leading to " \
927
+ "false negative test failures or even test fixture crashes."
928
+ @loginator.log( msg, Verbosity::NORMAL, LogLabels::NOTICE )
671
929
  end
930
+ end
672
931
 
673
- if @file_finder.find_build_input_file( filepath: source, complain: :ignore, context: TEST_SYM ).nil?
674
- error = "File '#{source}' specified with TEST_SOURCE_FILE() in #{test} cannot be found in the source file collection"
675
- raise CeedlingException.new( error )
932
+ # Any other directory in this same reachable set holding more than one file is
933
+ # shaped the same way a mocked header's own directory is -- but with no
934
+ # designated substitute among its occupants, there's nothing to safely isolate.
935
+ # Ceedling's own generated/vendor directories are exempt: a mocks output
936
+ # directory or a vendor framework's own source directory routinely holds
937
+ # several co-resident files as a matter of course, never a same-directory
938
+ # quote-include shortcut risk the way a real project header directory is.
939
+ generated_dirs = generated_content_dirs( testable )
940
+
941
+ by_directory.each do |dir, files|
942
+ next if mocked_dirs.include?( dir )
943
+ next if generated_dirs.any? { |gd| dir.start_with?( gd ) }
944
+
945
+ files.uniq.combination( 2 ).each do |a, b|
946
+ msg = "'#{a}' sits alongside '#{b}' at a nesting depth beyond what automated sibling-header " \
947
+ "isolation provides. If this test's build fails with a redeclaration or conflicting types " \
948
+ "error, the include ordering and path structure leading to '#{a}' or '#{b}' is worth investigating."
949
+ @loginator.log( msg, Verbosity::COMPLAIN, LogLabels::NOTICE )
676
950
  end
677
951
  end
952
+
953
+ return nil if isolated.empty?
954
+
955
+ isolation = @quote_include_isolator.isolate( parent: testable.paths[:build], files: isolated.uniq )
956
+
957
+ { search_paths: [isolation.dir] + testable.search_paths, isolation_dir: isolation.dir }
678
958
  end
679
959
 
680
- def remove_partials_source_objects(objects, configs)
681
- modules = configs.keys
682
- objects.delete_if do |filepath|
683
- modules.include?( File.basename( filepath ).ext() )
960
+ # `{ basename => real path }` for every real header this test substitutes -- CMock
961
+ # mocks of a real header, and Partials -- cross-referenced elsewhere against
962
+ # whatever a test's own compile actually reached. A mock Partial's own `source` is
963
+ # its own generated interface header, not a real project header, and is excluded.
964
+ def mocked_and_partialized_headers(testable)
965
+ headers = {}
966
+
967
+ (testable.mocks || {}).each_value do |details|
968
+ next if details.partial
969
+ headers[File.basename( details.source )] = details.source if details.source
970
+ end
971
+
972
+ testable.partials.configs.each_value do |config|
973
+ filepath = config.header.filepath
974
+ headers[File.basename( filepath )] = filepath if filepath
684
975
  end
976
+
977
+ headers
978
+ end
979
+
980
+ # Directory roots holding only Ceedling's own generated or vendored content for this
981
+ # test -- never real project headers, so co-residency there is routine, not a
982
+ # same-directory quote-include risk. A test's own Partials output directory
983
+ # routinely holds several generated headers side by side (a types header, an
984
+ # interface header, and more, one set per Partialized module), exactly the same
985
+ # shape as the mocks output directory.
986
+ def generated_content_dirs(testable)
987
+ [
988
+ testable.paths[:mocks],
989
+ testable.paths[:partials],
990
+ PROJECT_BUILD_VENDOR_UNITY_PATH,
991
+ PROJECT_BUILD_VENDOR_CMOCK_PATH,
992
+ PROJECT_BUILD_VENDOR_CEXCEPTION_PATH,
993
+ @configurator.project_build_vendor_ceedling_path
994
+ ].compact
995
+ end
996
+
997
+ # Registers `object`'s antecedents (its source file, plus whatever headers
998
+ # gcc's `-MMD -MF` discovered on the *previous* successful compile, if any)
999
+ # and reports whether it needs (re)building. The previous run's `.d` file is
1000
+ # the only header list available before this run's compile has happened --
1001
+ # if headers changed, that's exactly what makes this stale. Nothing has just
1002
+ # written that file, so one look suffices: a clean build has none, and a missed
1003
+ # one leaves the object stale, forcing a recompile.
1004
+ def register_and_check_object_staleness(object:, source:, dependencies:, flags:, defines:, search_paths:, tool:)
1005
+ @dependinator.register( object, files: [source], meta: dependency_meta( flags: flags, defines: defines, search_paths: search_paths, tools: [tool] ) )
1006
+ @dependinator.register_gcc_deps_file( dependencies ) if @file_wrapper.exist?( dependencies )
1007
+ @dependinator.stale?( object )
1008
+ end
1009
+
1010
+ # Each framework/support source needs its own vendor path (and, for CMock and a
1011
+ # support file, other frameworks' vendor paths too, when those frameworks are also in
1012
+ # play) spliced in ahead of a test's ordinary search paths -- the vendor sources
1013
+ # themselves live outside any configured :test/:source/:support/:include root, so
1014
+ # without this they'd never resolve. An ordinary test source matches none of the
1015
+ # cases below and falls through to `search_paths` unchanged.
1016
+ def tailor_search_paths(filepath:, search_paths:)
1017
+ _search_paths =
1018
+ if filepath == File.join( PROJECT_BUILD_VENDOR_UNITY_PATH, UNITY_C_FILE )
1019
+ unity_search_paths()
1020
+ elsif @configurator.project_use_mocks and
1021
+ (filepath == File.join( PROJECT_BUILD_VENDOR_CMOCK_PATH, CMOCK_C_FILE ))
1022
+ cmock_search_paths()
1023
+ elsif @configurator.project_use_exceptions and
1024
+ (filepath == File.join( PROJECT_BUILD_VENDOR_CEXCEPTION_PATH, CEXCEPTION_C_FILE ))
1025
+ cexception_search_paths()
1026
+ elsif @configurator.collection_all_support.include?( filepath )
1027
+ support_file_search_paths( search_paths )
1028
+ else
1029
+ []
1030
+ end
1031
+
1032
+ return search_paths if _search_paths.empty?
1033
+
1034
+ return _search_paths.uniq
1035
+ end
1036
+
1037
+ def unity_search_paths()
1038
+ @configurator.collection_paths_support + [PROJECT_BUILD_VENDOR_UNITY_PATH]
1039
+ end
1040
+
1041
+ def cmock_search_paths()
1042
+ paths = @configurator.collection_paths_support + [PROJECT_BUILD_VENDOR_UNITY_PATH, PROJECT_BUILD_VENDOR_CMOCK_PATH]
1043
+ paths << PROJECT_BUILD_VENDOR_CEXCEPTION_PATH if @configurator.project_use_exceptions
1044
+ paths
1045
+ end
1046
+
1047
+ def cexception_search_paths()
1048
+ @configurator.collection_paths_support + [PROJECT_BUILD_VENDOR_CEXCEPTION_PATH]
1049
+ end
1050
+
1051
+ def support_file_search_paths(search_paths)
1052
+ paths = search_paths + @configurator.collection_paths_support + [PROJECT_BUILD_VENDOR_UNITY_PATH]
1053
+ paths << PROJECT_BUILD_VENDOR_CMOCK_PATH if @configurator.project_use_mocks
1054
+ paths << PROJECT_BUILD_VENDOR_CEXCEPTION_PATH if @configurator.project_use_exceptions
1055
+ paths
685
1056
  end
686
1057
 
687
1058
  end