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
@@ -6,8 +6,13 @@
6
6
  # =========================================================================
7
7
 
8
8
  require 'spec_helper'
9
+ require 'ceedling/filename_extension'
10
+ require 'rake'
9
11
  require 'ceedling/test_invoker/test_build_executor'
10
12
  require 'ceedling/test_invoker/test_invoker_types'
13
+ require 'ceedling/partials/partials'
14
+ require 'ceedling/test_context_extractor'
15
+ require 'ceedling/quote_include_isolator'
11
16
 
12
17
  PROJECT_BUILD_VENDOR_UNITY_PATH = 'build/vendor/unity' unless defined?(PROJECT_BUILD_VENDOR_UNITY_PATH)
13
18
  UNITY_C_FILE = 'unity.c' unless defined?(UNITY_C_FILE)
@@ -19,26 +24,89 @@ describe TestBuildExecutor do
19
24
  @reportinator = double( "Reportinator" )
20
25
  @batchinator = double( "Batchinator" )
21
26
  @preprocessinator = double( "Preprocessinator" )
22
- @partializer = double( "Partializer" )
23
27
  @generator = double( "Generator" )
24
28
  @test_context_extractor = double( "TestContextExtractor" )
25
29
  @plugin_manager = double( "PluginManager" )
26
30
  @file_path_utils = double( "FilePathUtils" )
27
31
  @file_finder = double( "FileFinder" )
28
32
  @file_wrapper = double( "FileWrapper" )
33
+ @dependinator = double( "Dependinator" )
34
+ @test_source_file_directive_resolver = double( "TestSourceFileDirectiveResolver" )
35
+ @gcc_dependency_parser = double( "GccDependencyParser" )
36
+ @quote_include_isolator = double( "QuoteIncludeIsolator" )
37
+ @generator_helper = double( "GeneratorHelper" )
29
38
 
30
- @tools_test_compiler = { name: 'fake compiler' }
31
- @tools_test_assembler = { name: 'fake assembler' }
39
+ @tools_test_compiler = { name: 'fake compiler' }
40
+ @tools_test_assembler = { name: 'fake assembler' }
41
+ @tools_test_linker = { name: 'fake linker' }
42
+ @tools_test_fixture = { name: 'fake fixture' }
43
+ @tools_test_bare_includes_preprocessor = { name: 'fake bare includes preprocessor' }
44
+ @tools_test_file_directives_only_preprocessor = { name: 'fake directives-only preprocessor' }
45
+ @tools_test_backtrace_gdb = { name: 'fake gdb backtrace' }
46
+ @tools_test_fixture_simple_backtrace = { name: 'fake simple backtrace' }
32
47
 
33
- allow(@configurator).to receive(:extension_assembly).and_return( '.asm' )
48
+ allow(@configurator).to receive(:extension_assembly).and_return( FilenameExtension.new('.asm') )
49
+ allow(@configurator).to receive(:extension_testfail).and_return( FilenameExtension.new('.fail') )
34
50
  allow(@configurator).to receive(:tools_test_compiler).and_return( @tools_test_compiler )
35
51
  allow(@configurator).to receive(:tools_test_assembler).and_return( @tools_test_assembler )
52
+ allow(@configurator).to receive(:tools_test_linker).and_return( @tools_test_linker )
53
+ allow(@configurator).to receive(:tools_test_fixture).and_return( @tools_test_fixture )
54
+ allow(@configurator).to receive(:tools_test_bare_includes_preprocessor).and_return( @tools_test_bare_includes_preprocessor )
55
+ allow(@configurator).to receive(:tools_test_file_directives_only_preprocessor).and_return( @tools_test_file_directives_only_preprocessor )
56
+ # tools_test_backtrace_gdb is deliberately NOT stubbed here -- the real Configurator
57
+ # only defines it at all when :use_backtrace is :gdb (see test_build_executor.rb's
58
+ # own comment at its one call site), so leaving it unstubbed here means any example
59
+ # that calls it without :gdb mode explicitly set up fails loudly, the same way the
60
+ # real Configurator would raise NoMethodError.
61
+ allow(@configurator).to receive(:tools_test_fixture_simple_backtrace).and_return( @tools_test_fixture_simple_backtrace )
62
+ allow(@configurator).to receive(:project_config_hash).and_return( { project_use_backtrace: :simple } )
63
+ allow(@configurator).to receive(:include_test_case).and_return( '' )
64
+ allow(@configurator).to receive(:exclude_test_case).and_return( '' )
65
+ allow(@configurator).to receive(:test_build_preprocess_force_fallback).and_return( false )
36
66
  allow(@configurator).to receive(:project_use_mocks).and_return( false )
37
67
  allow(@configurator).to receive(:project_use_exceptions).and_return( false )
38
68
  allow(@configurator).to receive(:collection_all_support).and_return( [] )
69
+ allow(@configurator).to receive(:force_test_rerun).and_return( false )
70
+ allow(@configurator).to receive(:unity_shuffle_tests).and_return( false )
71
+ allow(@configurator).to receive(:project_build_vendor_ceedling_path).and_return( 'build/vendor/ceedling' )
39
72
 
40
73
  allow(@file_path_utils).to receive(:form_test_build_list_filepath).and_return( 'build/list' )
41
74
  allow(@file_path_utils).to receive(:form_test_dependencies_filepath).and_return( 'build/deps' )
75
+ allow(@file_path_utils).to receive(:form_preprocessed_source_files_cache_filepath).and_return( 'build/preprocess/build_directives/a_test/TestFoo.c_source_files.yml' )
76
+
77
+ allow(@file_wrapper).to receive(:mkdir)
78
+ allow(@quote_include_isolator).to receive(:release)
79
+ # The real literal scan over the doubled file layer, so each example's read stubs decide it
80
+ real_isolator = QuoteIncludeIsolator.new( { :file_wrapper => @file_wrapper, :loginator => @loginator } )
81
+ allow(@quote_include_isolator).to receive(:includes_by_name?) { |file, name| real_isolator.includes_by_name?( file, name ) }
82
+ allow(@generator_helper).to receive(:explain_possible_mock_partial_collision).and_return( nil )
83
+
84
+ allow(@reportinator).to receive(:generate_module_progress).and_return( '' )
85
+ allow(@reportinator).to receive(:generate_progress).and_return( '' )
86
+ allow(@reportinator).to receive(:generate_skip_summary).and_return( nil )
87
+ allow(@loginator).to receive(:log)
88
+ allow(@loginator).to receive(:log_list)
89
+ allow(@test_context_extractor).to receive(:store_build_directives_cache)
90
+ allow(@test_context_extractor).to receive(:load_build_directives_cache)
91
+
92
+ # Default: no prior `.d` file on disk, and the tracker reports every target
93
+ # stale -- i.e. every real build in this spec proceeds as an unconditional
94
+ # fresh compile unless a test overrides `stale?` to exercise the skip path.
95
+ # A prior run's .d file is looked for with exist? before a compile, and a freshly
96
+ # written one with exist_with_retry? after it. The sibling-header check calls exist?.
97
+ allow(@file_wrapper).to receive(:exist?).and_return( false )
98
+ allow(@file_wrapper).to receive(:exist_with_retry?).and_return( false )
99
+ # Default: no plugin implements the new pre-*-register hooks -- each is a
100
+ # no-op that leaves the arg_hash it's handed untouched.
101
+ allow(@plugin_manager).to receive(:pre_test_compile_register)
102
+ allow(@plugin_manager).to receive(:pre_test_link_register)
103
+ allow(@plugin_manager).to receive(:pre_test_fixture_register)
104
+
105
+ allow(@dependinator).to receive(:register)
106
+ allow(@dependinator).to receive(:register_gcc_deps_file)
107
+ allow(@dependinator).to receive(:stale?).and_return( true )
108
+ allow(@dependinator).to receive(:mark_fresh)
109
+ allow(@test_source_file_directive_resolver).to receive(:validate!)
42
110
 
43
111
  @executor = described_class.new(
44
112
  {
@@ -47,13 +115,15 @@ describe TestBuildExecutor do
47
115
  :reportinator => @reportinator,
48
116
  :batchinator => @batchinator,
49
117
  :preprocessinator => @preprocessinator,
50
- :partializer => @partializer,
51
118
  :generator => @generator,
52
- :test_context_extractor => @test_context_extractor,
53
119
  :plugin_manager => @plugin_manager,
54
120
  :file_path_utils => @file_path_utils,
55
121
  :file_finder => @file_finder,
56
- :file_wrapper => @file_wrapper
122
+ :file_wrapper => @file_wrapper,
123
+ :dependinator => @dependinator,
124
+ :gcc_dependency_parser => @gcc_dependency_parser,
125
+ :quote_include_isolator => @quote_include_isolator,
126
+ :generator_helper => @generator_helper
57
127
  }
58
128
  )
59
129
 
@@ -64,7 +134,21 @@ describe TestBuildExecutor do
64
134
  :assembler_flags => []
65
135
  )
66
136
 
67
- @state = TestInvokerTypes::PipelineState.new( :testables => { :a_test => testable } )
137
+ @state = TestInvokerTypes::PipelineState.new( :testables => { :a_test => testable }, :lock => Mutex.new )
138
+ end
139
+
140
+ # An isolation staged into `dir`, as QuoteIncludeIsolator#isolate returns one
141
+ def isolation_in(dir)
142
+ QuoteIncludeIsolator::Isolation.new( dir, {} )
143
+ end
144
+
145
+ # `@batchinator.exec` is a real collaborator only in production; here it's
146
+ # stubbed to synchronously yield every `things` entry to the given block,
147
+ # matching its real per-item iteration contract without pulling in Parallel.
148
+ def stub_batchinator_exec
149
+ allow(@batchinator).to receive(:exec) do |workload:, things:, &block|
150
+ things.each { |k, v| block.call(k, v) }
151
+ end
68
152
  end
69
153
 
70
154
  context "#compile_test_component" do
@@ -110,5 +194,1606 @@ describe TestBuildExecutor do
110
194
  :context => :test, :test => :a_test, :source => 'src/foo.asm', :object => 'build/foo.o', :state => @state
111
195
  )
112
196
  end
197
+
198
+ it "skips compiling and does not mark the object fresh when the dependency tracker reports it unchanged" do
199
+ allow(@file_wrapper).to receive(:extname).with( 'src/foo.c' ).and_return( '.c' )
200
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
201
+ allow(@dependinator).to receive(:stale?).and_return( false )
202
+
203
+ expect(@generator).to_not receive(:generate_object_file_c)
204
+ expect(@dependinator).to_not receive(:mark_fresh)
205
+
206
+ @executor.send(
207
+ :compile_test_component,
208
+ :context => :test, :test => :a_test, :source => 'src/foo.c', :object => 'build/foo.o', :state => @state
209
+ )
210
+ end
211
+
212
+ it "registers the object's source before checking staleness, and its freshly-written gcc deps file after a real compile" do
213
+ allow(@file_wrapper).to receive(:extname).with( 'src/foo.c' ).and_return( '.c' )
214
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
215
+ allow(@file_wrapper).to receive(:exist?).with('build/deps').and_return( true )
216
+ allow(@file_wrapper).to receive(:exist_with_retry?).with('build/deps').and_return( true )
217
+
218
+ expect(@dependinator).to receive(:register).with( 'build/foo.o', files: ['src/foo.c'], meta: anything ).ordered
219
+ expect(@dependinator).to receive(:register_gcc_deps_file).with('build/deps').ordered # pre-compile: prior .d file, if any
220
+ expect(@dependinator).to receive(:stale?).with('build/foo.o').and_return(true).ordered
221
+ expect(@generator).to receive(:generate_object_file_c).ordered
222
+ expect(@dependinator).to receive(:register_gcc_deps_file).with('build/deps').ordered # post-compile: freshly-written .d file
223
+ expect(@dependinator).to receive(:mark_fresh).with('build/foo.o').ordered
224
+
225
+ @executor.send(
226
+ :compile_test_component,
227
+ :context => :test, :test => :a_test, :source => 'src/foo.c', :object => 'build/foo.o', :state => @state
228
+ )
229
+ end
230
+
231
+ # A clean build has no .d file before a compile, and nothing has just written one,
232
+ # so a single look settles it. Waiting out a transient miss there would cost every
233
+ # object in a clean build the whole retry schedule.
234
+ it "looks once for a prior .d file before compiling, without waiting for one" do
235
+ allow(@file_wrapper).to receive(:extname).with( 'src/foo.c' ).and_return( '.c' )
236
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
237
+ allow(@dependinator).to receive(:stale?).and_return( false )
238
+
239
+ expect(@file_wrapper).to receive(:exist?).with('build/deps').and_return( false )
240
+ expect(@file_wrapper).to_not receive(:exist_with_retry?)
241
+ expect(@dependinator).to_not receive(:register_gcc_deps_file)
242
+
243
+ @executor.send(
244
+ :compile_test_component,
245
+ :context => :test, :test => :a_test, :source => 'src/foo.c', :object => 'build/foo.o', :state => @state
246
+ )
247
+ end
248
+
249
+ # The .d file a compile just wrote can briefly read as absent once the compiler exits.
250
+ # exist_with_retry? waits that out, so its headers are registered this run rather than
251
+ # on the next. Its retry mechanism is proven in file_wrapper_spec.rb.
252
+ it "registers the .d file a compile just wrote through exist_with_retry?, though none was there before" do
253
+ allow(@file_wrapper).to receive(:extname).with( 'src/foo.c' ).and_return( '.c' )
254
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
255
+ allow(@file_wrapper).to receive(:exist?).with('build/deps').and_return( false )
256
+ allow(@file_wrapper).to receive(:exist_with_retry?).with('build/deps').and_return( true )
257
+
258
+ expect(@generator).to receive(:generate_object_file_c)
259
+ expect(@dependinator).to receive(:register_gcc_deps_file).with('build/deps').once
260
+
261
+ @executor.send(
262
+ :compile_test_component,
263
+ :context => :test, :test => :a_test, :source => 'src/foo.c', :object => 'build/foo.o', :state => @state
264
+ )
265
+ end
266
+
267
+ it "resolves the compile tool/flags/defines through pre_test_compile_register before registering staleness meta, and uses the resolved values for the real compile" do
268
+ allow(@file_wrapper).to receive(:extname).with( 'src/foo.c' ).and_return( '.c' )
269
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
270
+
271
+ swapped_tool = { name: 'fake gcov compiler' }
272
+ allow(@plugin_manager).to receive(:pre_test_compile_register) do |arg_hash|
273
+ arg_hash[:tool] = swapped_tool
274
+ arg_hash[:flags] += ['-fcondition-coverage']
275
+ arg_hash[:defines] += ['CODE_COVERAGE']
276
+ end
277
+
278
+ expect(@dependinator).to receive(:register).with(
279
+ 'build/foo.o',
280
+ files: ['src/foo.c'],
281
+ meta: hash_including(
282
+ tools: [swapped_tool],
283
+ flags: array_including('-fcondition-coverage'),
284
+ defines: array_including('CODE_COVERAGE')
285
+ )
286
+ )
287
+ expect(@generator).to receive(:generate_object_file_c) do |**args|
288
+ expect( args[:tool] ).to eq( swapped_tool )
289
+ expect( args[:flags] ).to include('-fcondition-coverage')
290
+ expect( args[:defines] ).to include('CODE_COVERAGE')
291
+ end
292
+
293
+ @executor.send(
294
+ :compile_test_component,
295
+ :context => :test, :test => :a_test, :source => 'src/foo.c', :object => 'build/foo.o', :state => @state
296
+ )
297
+ end
298
+
299
+ it "registers the configured compiler tool as meta for a C source, and the configured assembler tool for an assembly source" do
300
+ allow(@file_wrapper).to receive(:extname).with( 'src/foo.c' ).and_return( '.c' )
301
+ allow(@file_wrapper).to receive(:extname).with( 'src/foo.asm' ).and_return( '.asm' )
302
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( true )
303
+ allow(@generator).to receive(:generate_object_file_c)
304
+ allow(@generator).to receive(:generate_object_file_asm)
305
+
306
+ expect(@dependinator).to receive(:register).with( 'build/foo.o', files: ['src/foo.c'], meta: hash_including( tools: [@tools_test_compiler] ) )
307
+ @executor.send(
308
+ :compile_test_component,
309
+ :context => :test, :test => :a_test, :source => 'src/foo.c', :object => 'build/foo.o', :state => @state
310
+ )
311
+
312
+ expect(@dependinator).to receive(:register).with( 'build/foo.o', files: ['src/foo.asm'], meta: hash_including( tools: [@tools_test_assembler] ) )
313
+ @executor.send(
314
+ :compile_test_component,
315
+ :context => :test, :test => :a_test, :source => 'src/foo.asm', :object => 'build/foo.o', :state => @state
316
+ )
317
+ end
318
+
319
+ # A test's own file compile is the one point where its full, transitive dependency
320
+ # closure is freshly known -- reached headers a mock or Partial never sees directly,
321
+ # since substitution only ever looks at what the test file itself #includes. When
322
+ # that closure reveals a real header sharing a directory with one this test mocks or
323
+ # Partializes, quote-include's own same-directory-first rule could let that real
324
+ # content slip past the substitution entirely; isolating the sibling and retrying
325
+ # with corrected search paths closes that gap without ever touching the original
326
+ # compile's own registered dependencies.
327
+ # A source beside a header mocked under :treat_inlines :include would find the real
328
+ # header first and run its inline bodies. It compiles from an isolated copy instead.
329
+ context "a source sharing a directory with a header mocked with inline shadowing" do
330
+ let(:isolation) do
331
+ QuoteIncludeIsolator::Isolation.new( 'build/test/out/a_test/tmp1', { 'src/gpio.c' => 'build/test/out/a_test/tmp1/gpio.c' } )
332
+ end
333
+
334
+ before(:each) do
335
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
336
+ allow(@configurator).to receive(:project_use_mocks).and_return( true )
337
+ allow(@configurator).to receive(:cmock_treat_inlines).and_return( :include )
338
+ allow(@file_wrapper).to receive(:exist_with_retry?).and_return( false )
339
+
340
+ @testable = @state.testables[:a_test]
341
+ @testable.filepath = 'test/test_gpio.c'
342
+ @testable.paths = { :build => 'build/test/out/a_test' }
343
+ @testable.search_paths = ['build/test/mocks/a_test', 'src']
344
+ @testable.mocks = {
345
+ :mock_board => TestInvokerTypes::MockDetails.new( name: 'mock_board', source: 'src/board.h', partial: false )
346
+ }
347
+
348
+ allow(@file_wrapper).to receive(:exist?).with( 'src/gpio.c' ).and_return( true )
349
+ allow(@file_wrapper).to receive(:read).with( 'src/gpio.c' ).and_return( %(#include "board.h"\n) )
350
+
351
+ # A real scoped isolation hands back whatever its block returns
352
+ allow(@quote_include_isolator).to receive(:within) { |**_, &block| block.call( isolation ) }
353
+ allow(@quote_include_isolator).to receive(:restore_dependencies)
354
+ allow(@generator).to receive(:generate_object_file_c)
355
+ end
356
+
357
+ def compile(source: 'src/gpio.c')
358
+ @executor.send(
359
+ :compile_test_component,
360
+ :context => :test, :test => :a_test, :source => source, :object => 'build/gpio.o', :state => @state
361
+ )
362
+ end
363
+
364
+ it "compiles a location-preserving copy, with the original's directory searched last" do
365
+ compile()
366
+
367
+ expect(@quote_include_isolator).to have_received(:within)
368
+ .with( parent: 'build/test/out/a_test', files: ['src/gpio.c'], preserve_location: true )
369
+ expect(@generator).to have_received(:generate_object_file_c).with( hash_including(
370
+ source: 'src/gpio.c',
371
+ compile_source: 'build/test/out/a_test/tmp1/gpio.c',
372
+ search_paths: ['build/test/mocks/a_test', 'src', 'src']
373
+ ) )
374
+ end
375
+
376
+ it "restores the dependency file before registering it" do
377
+ allow(@file_wrapper).to receive(:exist_with_retry?).with( 'build/deps' ).and_return( true )
378
+
379
+ expect(@quote_include_isolator).to receive(:restore_dependencies).with( isolation, 'build/deps' ).ordered
380
+ expect(@dependinator).to receive(:register_gcc_deps_file).with( 'build/deps' ).ordered
381
+
382
+ compile()
383
+ end
384
+
385
+ it "restores the dependency file and raises when the compile fails" do
386
+ ex = ShellException.new( shell_result: { output: 'error' }, name: 'compiler' )
387
+ allow(@generator).to receive(:generate_object_file_c).and_raise( ex )
388
+
389
+ expect { compile() }.to raise_error( ShellException )
390
+ expect(@quote_include_isolator).to have_received(:restore_dependencies).with( isolation, 'build/deps' )
391
+ end
392
+
393
+ it "logs the isolation at NORMAL verbosity, decorated as a notice" do
394
+ compile()
395
+
396
+ expect(@loginator).to have_received(:log).with( a_string_including( 'src/gpio.c', 'src/board.h' ), Verbosity::NORMAL, LogLabels::NOTICE )
397
+ end
398
+
399
+ # Isolation is an implementation detail of how a source compiles. Its staleness must
400
+ # read the same either way, or toggling isolation would force a rebuild.
401
+ it "registers the same staleness meta as an ordinary compile" do
402
+ metas = []
403
+ allow(@dependinator).to receive(:register) { |_, **kwargs| metas << kwargs[:meta] }
404
+
405
+ compile()
406
+ allow(@configurator).to receive(:cmock_treat_inlines).and_return( :exclude )
407
+ compile()
408
+
409
+ expect( metas.uniq.length ).to eq( 1 )
410
+ end
411
+
412
+ shared_examples "an ordinary compile" do
413
+ it "compiles the original in place" do
414
+ compile( source: source )
415
+
416
+ expect(@quote_include_isolator).to_not have_received(:within)
417
+ expect(@generator).to have_received(:generate_object_file_c).with( hash_excluding( :compile_source ) )
418
+ end
419
+ end
420
+
421
+ context "when inline functions are excluded from mocking" do
422
+ before(:each) { allow(@configurator).to receive(:cmock_treat_inlines).and_return( :exclude ) }
423
+ let(:source) { 'src/gpio.c' }
424
+ include_examples "an ordinary compile"
425
+ end
426
+
427
+ context "when mocks are disabled" do
428
+ before(:each) { allow(@configurator).to receive(:project_use_mocks).and_return( false ) }
429
+ let(:source) { 'src/gpio.c' }
430
+ include_examples "an ordinary compile"
431
+ end
432
+
433
+ context "when the mock is a Partial mock" do
434
+ before(:each) { @testable.mocks[:mock_board].partial = true }
435
+ let(:source) { 'src/gpio.c' }
436
+ include_examples "an ordinary compile"
437
+ end
438
+
439
+ context "when the mocked header lives in another directory" do
440
+ before(:each) { @testable.mocks[:mock_board].source = 'inc/board.h' }
441
+ let(:source) { 'src/gpio.c' }
442
+ include_examples "an ordinary compile"
443
+ end
444
+
445
+ context "when the source does not include the mocked header" do
446
+ before(:each) { allow(@file_wrapper).to receive(:read).with( 'src/gpio.c' ).and_return( %(#include "gpio.h"\n) ) }
447
+ let(:source) { 'src/gpio.c' }
448
+ include_examples "an ordinary compile"
449
+ end
450
+
451
+ context "when the source is the test file itself" do
452
+ before(:each) { @testable.filepath = 'src/gpio.c' }
453
+ let(:source) { 'src/gpio.c' }
454
+ include_examples "an ordinary compile"
455
+ end
456
+ end
457
+
458
+ context "sibling-header isolation retry" do
459
+ before(:each) do
460
+ allow(@file_wrapper).to receive(:extname).with( 'test/a_test.c' ).and_return( '.c' )
461
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
462
+ allow(@file_wrapper).to receive(:exist_with_retry?).with( 'build/deps' ).and_return( true )
463
+ allow(@file_wrapper).to receive(:read).and_return( '' )
464
+
465
+ @state.testables[:a_test].filepath = 'test/a_test.c'
466
+ @state.testables[:a_test].paths = { build: 'build/test/out/a_test' }
467
+ @state.testables[:a_test].mocks = {
468
+ gpio: TestInvokerTypes::MockDetails.new(
469
+ name: 'gpio', filepath: '/project/library/gpio.h', path: 'library',
470
+ source: '/project/library/gpio.h', input: '/project/library/gpio.h', partial: false
471
+ )
472
+ }
473
+
474
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
475
+ { 'build/foo.o' => ['test/a_test.c', '/project/library/gpio.h', '/project/library/driverlib.h'] }
476
+ )
477
+
478
+ # driverlib.h is the sibling under test throughout this context -- it
479
+ # genuinely #includes gpio.h, the signal that distinguishes a real risk
480
+ # from merely sharing a directory.
481
+ allow(@file_wrapper).to receive(:exist?).with( '/project/library/driverlib.h' ).and_return( true )
482
+ allow(@file_wrapper).to receive(:read).with( '/project/library/driverlib.h' ).and_return( "#include \"gpio.h\"\n" )
483
+ end
484
+
485
+ it "retries the compile with corrected search paths when a sibling risk is found, and clears an initial failure" do
486
+ allow(@quote_include_isolator).to receive(:isolate)
487
+ .with( parent: 'build/test/out/a_test', files: ['/project/library/driverlib.h'] )
488
+ .and_return( isolation_in( 'build/test/out/a_test/isolated_headers/xyz' ) )
489
+
490
+ ex = ShellException.new( shell_result: { output: 'redeclaration of struct gpio' }, name: 'compiler' )
491
+ call_count = 0
492
+ allow(@generator).to receive(:generate_object_file_c) do
493
+ call_count += 1
494
+ raise ex if call_count == 1
495
+ end
496
+
497
+ expect {
498
+ @executor.send(
499
+ :compile_test_component,
500
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
501
+ )
502
+ }.to_not raise_error
503
+
504
+ expect( @generator ).to have_received( :generate_object_file_c ).twice
505
+ expect( @state.testables[:a_test].search_paths ).to include( 'build/test/out/a_test/isolated_headers/xyz' )
506
+ expect( @state.testables[:a_test].isolated_headers_path ).to eq( 'build/test/out/a_test/isolated_headers/xyz' )
507
+ end
508
+
509
+ it "retries against a separate, throwaway dependencies path, and registers only the original .d file" do
510
+ allow(@quote_include_isolator).to receive(:isolate).and_return( isolation_in( 'build/test/out/a_test/isolated_headers/xyz' ) )
511
+ allow(@generator).to receive(:generate_object_file_c)
512
+
513
+ expect(@generator).to receive(:generate_object_file_c).with( hash_including( dependencies: 'build/deps' ) ).ordered
514
+ expect(@generator).to receive(:generate_object_file_c).with( hash_including( dependencies: a_string_matching(/\Abuild\/deps\..+/) ) ).ordered
515
+
516
+ expect(@dependinator).to receive(:register_gcc_deps_file).with( 'build/deps' ).at_least(:once)
517
+ expect(@dependinator).to_not receive(:register_gcc_deps_file).with( a_string_matching(/\Abuild\/deps\..+/) )
518
+
519
+ @executor.send(
520
+ :compile_test_component,
521
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
522
+ )
523
+ end
524
+
525
+ it "still raises when the retry itself also fails" do
526
+ allow(@quote_include_isolator).to receive(:isolate).and_return( isolation_in( 'build/test/out/a_test/isolated_headers/xyz' ) )
527
+
528
+ ex = ShellException.new( shell_result: { output: 'redeclaration of struct gpio' }, name: 'compiler' )
529
+ allow(@generator).to receive(:generate_object_file_c).and_raise( ex )
530
+
531
+ expect {
532
+ @executor.send(
533
+ :compile_test_component,
534
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
535
+ )
536
+ }.to raise_error( ShellException )
537
+ end
538
+
539
+ it "does not retry, and still raises, when no sibling risk is found" do
540
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
541
+ { 'build/foo.o' => ['test/a_test.c', '/project/library/gpio.h'] }
542
+ )
543
+
544
+ ex = ShellException.new( shell_result: { output: 'some unrelated failure' }, name: 'compiler' )
545
+ allow(@generator).to receive(:generate_object_file_c).and_raise( ex )
546
+
547
+ expect {
548
+ @executor.send(
549
+ :compile_test_component,
550
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
551
+ )
552
+ }.to raise_error( ShellException )
553
+
554
+ expect( @generator ).to have_received( :generate_object_file_c ).once
555
+ end
556
+
557
+ it "still registers the original compile's own .d file when the first attempt fails and nothing is isolated" do
558
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
559
+ { 'build/foo.o' => ['test/a_test.c', '/project/library/gpio.h'] }
560
+ )
561
+ allow(@generator).to receive(:generate_object_file_c).and_raise(
562
+ ShellException.new( shell_result: { output: 'some unrelated failure' }, name: 'compiler' )
563
+ )
564
+
565
+ # Once pre-compile for the previous run's .d file, and once again for the .d file the
566
+ # failed attempt wrote. A failed compile is still a real attempt whose dependency
567
+ # output is worth keeping.
568
+ allow(@file_wrapper).to receive(:exist?).with( 'build/deps' ).and_return( true )
569
+ expect(@dependinator).to receive(:register_gcc_deps_file).with( 'build/deps' ).twice
570
+
571
+ expect {
572
+ @executor.send(
573
+ :compile_test_component,
574
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
575
+ )
576
+ }.to raise_error( ShellException )
577
+ end
578
+
579
+ it "does not attempt isolation for an object other than the test's own file" do
580
+ allow(@file_wrapper).to receive(:extname).with( 'src/other.c' ).and_return( '.c' )
581
+ allow(@generator).to receive(:generate_object_file_c)
582
+
583
+ expect(@gcc_dependency_parser).to_not receive(:parse)
584
+
585
+ @executor.send(
586
+ :compile_test_component,
587
+ :context => :test, :test => :a_test, :source => 'src/other.c', :object => 'build/other.o', :state => @state
588
+ )
589
+ end
590
+
591
+ # A delta build's own whole point is that an unchanged object never recompiles --
592
+ # but isolation's own correction to search_paths only ever happens as a side
593
+ # effect of a real compile. Without also applying it here, every other object in
594
+ # this same test's build would compute its own staleness against paths that
595
+ # silently drift from what actually got cached the last time isolation *did* run,
596
+ # forcing them to recompile on every single subsequent build, forever, even
597
+ # though nothing about the project actually changed.
598
+ it "applies whatever isolation the existing .d file already reveals even when this object is not stale" do
599
+ allow(@dependinator).to receive(:stale?).with( 'build/foo.o' ).and_return( false )
600
+ allow(@quote_include_isolator).to receive(:isolate)
601
+ .with( parent: 'build/test/out/a_test', files: ['/project/library/driverlib.h'] )
602
+ .and_return( isolation_in( 'build/test/out/a_test/isolated_headers/xyz' ) )
603
+
604
+ expect(@generator).to_not receive(:generate_object_file_c)
605
+
606
+ @executor.send(
607
+ :compile_test_component,
608
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
609
+ )
610
+
611
+ expect( @state.testables[:a_test].search_paths ).to include( 'build/test/out/a_test/isolated_headers/xyz' )
612
+ expect( @state.testables[:a_test].isolated_headers_path ).to eq( 'build/test/out/a_test/isolated_headers/xyz' )
613
+ end
614
+
615
+ it "does not attempt isolation on a skip when there is no existing .d file yet" do
616
+ allow(@dependinator).to receive(:stale?).with( 'build/foo.o' ).and_return( false )
617
+ allow(@file_wrapper).to receive(:exist_with_retry?).with( 'build/deps' ).and_return( false )
618
+
619
+ expect(@gcc_dependency_parser).to_not receive(:parse)
620
+ expect(@generator).to_not receive(:generate_object_file_c)
621
+
622
+ @executor.send(
623
+ :compile_test_component,
624
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
625
+ )
626
+ end
627
+
628
+ # A Partial's own generated content never gives isolation an alternative same-named
629
+ # file for a search path to fall through to, so a redeclaration/conflicting-types
630
+ # failure can survive every attempt here. Logging the likely cause alongside the raw
631
+ # compiler error, rather than raising it bare, is the deliberate fallback for exactly
632
+ # that case -- and for any other collision isolation doesn't resolve.
633
+ it "logs the guidance from generator_helper and still raises, when the compile fails with no isolation to try" do
634
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
635
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h'] }
636
+ )
637
+
638
+ ex = ShellException.new( shell_result: { output: 'redeclaration of struct gpio' }, name: 'compiler' )
639
+ allow(@generator).to receive(:generate_object_file_c).and_raise( ex )
640
+
641
+ allow(@generator_helper).to receive(:explain_possible_mock_partial_collision)
642
+ .with( output: 'redeclaration of struct gpio', mocked_headers: { 'gpio.h' => '/project/library/gpio.h' } )
643
+ .and_return( 'explanatory notice text' )
644
+
645
+ expect(@loginator).to receive(:log).with( 'explanatory notice text', Verbosity::ERRORS, LogLabels::NOTICE )
646
+
647
+ expect {
648
+ @executor.send(
649
+ :compile_test_component,
650
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
651
+ )
652
+ }.to raise_error( ShellException )
653
+ end
654
+
655
+ it "logs the guidance after a retry that also fails" do
656
+ allow(@quote_include_isolator).to receive(:isolate).and_return( isolation_in( 'build/test/out/a_test/isolated_headers/xyz' ) )
657
+
658
+ ex = ShellException.new( shell_result: { output: 'redeclaration of struct gpio' }, name: 'compiler' )
659
+ allow(@generator).to receive(:generate_object_file_c).and_raise( ex )
660
+ allow(@generator_helper).to receive(:explain_possible_mock_partial_collision).and_return( 'explanatory notice text' )
661
+
662
+ expect(@loginator).to receive(:log).with( 'explanatory notice text', Verbosity::ERRORS, LogLabels::NOTICE )
663
+
664
+ expect {
665
+ @executor.send(
666
+ :compile_test_component,
667
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
668
+ )
669
+ }.to raise_error( ShellException )
670
+ end
671
+
672
+ it "logs nothing extra when generator_helper finds no explanation" do
673
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
674
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h'] }
675
+ )
676
+ ex = ShellException.new( shell_result: { output: 'totally unrelated failure' }, name: 'compiler' )
677
+ allow(@generator).to receive(:generate_object_file_c).and_raise( ex )
678
+
679
+ expect(@loginator).to_not receive(:log).with( anything, Verbosity::ERRORS, LogLabels::NOTICE )
680
+
681
+ expect {
682
+ @executor.send(
683
+ :compile_test_component,
684
+ :context => :test, :test => :a_test, :source => 'test/a_test.c', :object => 'build/foo.o', :state => @state
685
+ )
686
+ }.to raise_error( ShellException )
687
+ end
688
+ end
689
+ end
690
+
691
+ context "#isolate_sibling_headers" do
692
+ before(:each) do
693
+ @testable = TestInvokerTypes::Testable.new(
694
+ :name => 'a_test', :filepath => 'test/a_test.c',
695
+ :search_paths => ['test/support'],
696
+ :paths => { build: 'build/test/out/a_test' }
697
+ )
698
+
699
+ allow(@file_wrapper).to receive(:read).with( 'build/deps' ).and_return( '' )
700
+ end
701
+
702
+ def call_it
703
+ @executor.send( :isolate_sibling_headers, testable: @testable, dependencies_filepath: 'build/deps' )
704
+ end
705
+
706
+ it "returns nil, and never reads the dependencies file, when the testable mocks or Partializes nothing" do
707
+ expect(@file_wrapper).to_not receive(:read)
708
+ expect( call_it() ).to be_nil
709
+ end
710
+
711
+ context "with a mocked header" do
712
+ before(:each) do
713
+ @testable.mocks = {
714
+ gpio: TestInvokerTypes::MockDetails.new(
715
+ name: 'gpio', filepath: '/project/library/gpio.h', path: 'library',
716
+ source: '/project/library/gpio.h', input: '/project/library/gpio.h', partial: false
717
+ )
718
+ }
719
+
720
+ # driverlib.h is the sibling under test throughout this context -- it
721
+ # genuinely #includes gpio.h, the signal that distinguishes a real risk
722
+ # from merely sharing a directory.
723
+ allow(@file_wrapper).to receive(:exist?).with( '/project/library/driverlib.h' ).and_return( true )
724
+ allow(@file_wrapper).to receive(:read).with( '/project/library/driverlib.h' ).and_return( "#include \"gpio.h\"\n" )
725
+ end
726
+
727
+ it "returns nil when the mocked header itself never appears in the dependency list" do
728
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
729
+ { 'a.o' => ['test/a_test.c', '/project/other/unrelated.h'] }
730
+ )
731
+ expect( call_it() ).to be_nil
732
+ end
733
+
734
+ it "returns nil when the mocked header has no directory-mates in the dependency list" do
735
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
736
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h', '/project/other/unrelated.h'] }
737
+ )
738
+ expect( call_it() ).to be_nil
739
+ end
740
+
741
+ # A same-directory file is a real project header layout, not a special one --
742
+ # most projects keep every header in one shared directory as ordinary
743
+ # convention. A candidate that merely lives beside the mocked header, without
744
+ # itself #including it, is exactly that ordinary case, not a collision risk;
745
+ # isolating it anyway would recompile it every single build for no reason.
746
+ it "does not isolate a same-directory file that does not itself #include the mocked header" do
747
+ allow(@file_wrapper).to receive(:exist?).with( '/project/library/unrelated_neighbor.h' ).and_return( true )
748
+ allow(@file_wrapper).to receive(:read).with( '/project/library/unrelated_neighbor.h' ).and_return( "#include <stdint.h>\n" )
749
+
750
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
751
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h', '/project/library/unrelated_neighbor.h'] }
752
+ )
753
+
754
+ expect(@quote_include_isolator).to_not receive(:isolate)
755
+ expect( call_it() ).to be_nil
756
+ end
757
+
758
+ it "isolates a real header sharing a directory with the mocked header, prepending the isolation directory to search paths" do
759
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
760
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h', '/project/library/driverlib.h'] }
761
+ )
762
+ allow(@quote_include_isolator).to receive(:isolate)
763
+ .with( parent: 'build/test/out/a_test', files: ['/project/library/driverlib.h'] )
764
+ .and_return( isolation_in( 'build/test/out/a_test/isolated_headers/xyz' ) )
765
+
766
+ result = call_it()
767
+
768
+ expect( result ).to eq(
769
+ search_paths: ['build/test/out/a_test/isolated_headers/xyz', 'test/support'],
770
+ isolation_dir: 'build/test/out/a_test/isolated_headers/xyz'
771
+ )
772
+ end
773
+
774
+ it "logs the isolation at NORMAL verbosity, decorated as a notice" do
775
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
776
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h', '/project/library/driverlib.h'] }
777
+ )
778
+ allow(@quote_include_isolator).to receive(:isolate).and_return( isolation_in( 'isolated/dir' ) )
779
+
780
+ expect(@loginator).to receive(:log).with(
781
+ a_string_including( '/project/library/driverlib.h' ).and( a_string_including( '/project/library/gpio.h' ) ),
782
+ Verbosity::NORMAL, LogLabels::NOTICE
783
+ )
784
+
785
+ call_it()
786
+ end
787
+
788
+ it "excludes a mock-Partial's own generated source from consideration entirely" do
789
+ @testable.mocks[:gpio].partial = true
790
+
791
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
792
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h', '/project/library/driverlib.h'] }
793
+ )
794
+
795
+ expect(@quote_include_isolator).to_not receive(:isolate)
796
+ expect( call_it() ).to be_nil
797
+ end
798
+
799
+ it "reports, but does not isolate, another shared directory elsewhere in the dependency list" do
800
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
801
+ {
802
+ 'a.o' => [
803
+ 'test/a_test.c', '/project/library/gpio.h', '/project/library/driverlib.h',
804
+ '/project/other/x.h', '/project/other/y.h'
805
+ ]
806
+ }
807
+ )
808
+ allow(@quote_include_isolator).to receive(:isolate)
809
+ .with( parent: 'build/test/out/a_test', files: ['/project/library/driverlib.h'] )
810
+ .and_return( isolation_in( 'isolated/dir' ) )
811
+
812
+ expect(@loginator).to receive(:log).with(
813
+ a_string_including( '/project/other/x.h' ).and( a_string_including( '/project/other/y.h' ) ),
814
+ Verbosity::COMPLAIN, LogLabels::NOTICE
815
+ )
816
+
817
+ result = call_it()
818
+
819
+ expect( result[:search_paths] ).to_not include( a_string_including( '/project/other' ) )
820
+ end
821
+
822
+ it "logs nothing at all when there is no risk anywhere in the dependency list" do
823
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
824
+ { 'a.o' => ['test/a_test.c', '/project/library/gpio.h'] }
825
+ )
826
+
827
+ expect(@loginator).to_not receive(:log).with( anything, anything, LogLabels::NOTICE )
828
+
829
+ call_it()
830
+ end
831
+
832
+ # This test's own mocks output directory routinely holds several generated files
833
+ # side by side (a mock's own interface header, and -- when :treat_inlines: :include
834
+ # is configured -- a same-basename shadow of the real header too), and Unity's own
835
+ # vendor directory ships more than one header as a matter of course. Neither is a
836
+ # real project header directory a quote-include could ambiguously resolve within,
837
+ # so neither belongs in the "worth investigating" heads-up.
838
+ it "does not report co-resident files inside this test's own mocks output directory or a vendor framework directory" do
839
+ @testable.paths = { build: 'build/test/out/a_test', mocks: 'build/test/mocks/a_test' }
840
+
841
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
842
+ {
843
+ 'a.o' => [
844
+ 'test/a_test.c', '/project/library/gpio.h',
845
+ 'build/test/mocks/a_test/mock_gpio.h', 'build/test/mocks/a_test/gpio.h',
846
+ PROJECT_BUILD_VENDOR_UNITY_PATH + '/unity.h', PROJECT_BUILD_VENDOR_UNITY_PATH + '/unity_internals.h'
847
+ ]
848
+ }
849
+ )
850
+
851
+ expect(@loginator).to_not receive(:log).with( anything, Verbosity::COMPLAIN, anything )
852
+
853
+ call_it()
854
+ end
855
+
856
+ # A test's own Partials output directory is shaped exactly the same way as its
857
+ # mocks output directory -- several generated headers (a types header, an
858
+ # interface header, and more) routinely sit side by side there, one set per
859
+ # Partialized module, none of it a real project header.
860
+ it "does not report co-resident files inside this test's own Partials output directory" do
861
+ @testable.paths = { build: 'build/test/out/a_test', partials: 'build/test/partials/a_test' }
862
+
863
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
864
+ {
865
+ 'a.o' => [
866
+ 'test/a_test.c', '/project/library/gpio.h',
867
+ 'build/test/partials/a_test/ceedling_partial_moduleA_impl.h',
868
+ 'build/test/partials/a_test/ceedling_partial_gpio_interface.h',
869
+ 'build/test/partials/a_test/ceedling_partial_gpio_types.h'
870
+ ]
871
+ }
872
+ )
873
+
874
+ expect(@loginator).to_not receive(:log).with( anything, Verbosity::COMPLAIN, anything )
875
+
876
+ call_it()
877
+ end
878
+ end
879
+
880
+ context "with a Partialized header" do
881
+ it "isolates a real header sharing a directory with the Partial's own header" do
882
+ @testable.partials = TestInvokerTypes::TestablePartials.new(
883
+ configs: { moduleA: double( "PartialConfig", header: double( "HeaderFile", filepath: '/project/library/moduleA.h' ) ) },
884
+ tests: [], mocks: []
885
+ )
886
+
887
+ allow(@gcc_dependency_parser).to receive(:parse).and_return(
888
+ { 'a.o' => ['test/a_test.c', '/project/library/moduleA.h', '/project/library/driverlib.h'] }
889
+ )
890
+ allow(@file_wrapper).to receive(:exist?).with( '/project/library/driverlib.h' ).and_return( true )
891
+ allow(@file_wrapper).to receive(:read).with( '/project/library/driverlib.h' ).and_return( "#include \"moduleA.h\"\n" )
892
+ allow(@quote_include_isolator).to receive(:isolate)
893
+ .with( parent: 'build/test/out/a_test', files: ['/project/library/driverlib.h'] )
894
+ .and_return( isolation_in( 'isolated/dir' ) )
895
+
896
+ expect( call_it() ).to_not be_nil
897
+ end
898
+ end
899
+ end
900
+
901
+ context "#stage_build_objects" do
902
+ before(:each) do
903
+ stub_batchinator_exec()
904
+
905
+ allow(@file_finder).to receive(:find_build_input_file).and_return( 'src/foo.c' )
906
+ allow(@file_wrapper).to receive(:extname).and_return( '.c' )
907
+ allow(@configurator).to receive(:test_build_use_assembly).and_return( false )
908
+
909
+ @testable = TestInvokerTypes::Testable.new(
910
+ :name => 'a_test',
911
+ :compile_defines => [], :search_paths => [], :compile_flags => []
912
+ )
913
+ @state = TestInvokerTypes::PipelineState.new(
914
+ :testables => { :a_test => @testable },
915
+ :objects_list => [ TestInvokerTypes::ObjectWork.new( test: :a_test, obj: 'build/foo.o' ) ],
916
+ :lock => Mutex.new, :context => :test, :options => []
917
+ )
918
+ end
919
+
920
+ it "logs a summary line stating how many objects were recalled from cache" do
921
+ allow(@dependinator).to receive(:stale?).and_return( false )
922
+
923
+ allow(@reportinator).to receive(:generate_skip_summary).and_return( "Skipping compilation for 1 object (nothing changed)..." )
924
+
925
+ expect(@loginator).to receive(:log).with( "Skipping compilation for 1 object (nothing changed)..." )
926
+ @executor.stage_build_objects( @state )
927
+ end
928
+
929
+ it "logs no summary line when every object needed compiling" do
930
+ allow(@dependinator).to receive(:stale?).and_return( true )
931
+ allow(@generator).to receive(:generate_object_file_c)
932
+
933
+ expect(@loginator).to_not receive(:log).with( /Skipping compilation/ )
934
+
935
+ @executor.stage_build_objects( @state )
936
+ end
937
+
938
+ # A test's own file compiles in a batch fully completed before any other object
939
+ # starts -- any search-path fix-up sibling isolation makes during that first
940
+ # compile needs to be visible to every other object in the same test's build,
941
+ # and parallel compilation gives no other guarantee that it lands before them.
942
+ it "compiles the test's own file fully before any other object in the same test begins" do
943
+ @testable.filepath = 'test/a_test.c'
944
+ @testable.paths = { build: 'build/test/out/a_test' }
945
+
946
+ @state.objects_list = [
947
+ TestInvokerTypes::ObjectWork.new( test: :a_test, obj: 'build/other.o' ),
948
+ TestInvokerTypes::ObjectWork.new( test: :a_test, obj: 'build/a_test.o' )
949
+ ]
950
+
951
+ allow(@file_finder).to receive(:find_build_input_file)
952
+ .with( filepath: 'build/other.o', context: :test, test: :a_test ).and_return( 'src/other.c' )
953
+ allow(@file_finder).to receive(:find_build_input_file)
954
+ .with( filepath: 'build/a_test.o', context: :test, test: :a_test ).and_return( 'test/a_test.c' )
955
+
956
+ order = []
957
+ allow(@generator).to receive(:generate_object_file_c) do |**args|
958
+ order << args[:source]
959
+ end
960
+
961
+ @executor.stage_build_objects( @state )
962
+
963
+ expect( order ).to eq( ['test/a_test.c', 'src/other.c'] )
964
+ end
965
+
966
+ it "removes a testable's isolated headers directory once, after both batches complete" do
967
+ @testable.isolated_headers_path = 'build/test/out/a_test/isolated_headers/xyz'
968
+ allow(@dependinator).to receive(:stale?).and_return( false )
969
+
970
+ expect(@quote_include_isolator).to receive(:release).with( 'build/test/out/a_test/isolated_headers/xyz' ).once
971
+
972
+ @executor.stage_build_objects( @state )
973
+ end
974
+
975
+ it "attempts no cleanup for a testable that never isolated anything" do
976
+ allow(@dependinator).to receive(:stale?).and_return( false )
977
+
978
+ expect(@quote_include_isolator).to_not receive(:release)
979
+
980
+ @executor.stage_build_objects( @state )
981
+ end
982
+ end
983
+
984
+ context "#stage_build_executables" do
985
+ before(:each) do
986
+ stub_batchinator_exec()
987
+
988
+ allow(@configurator).to receive(:project_config_hash).and_return( {} )
989
+ allow(@file_path_utils).to receive(:form_test_build_map_filepath).and_return( 'build/map' )
990
+
991
+ allow(@generator).to receive(:generate_test_executable_manifest)
992
+
993
+ @testable = TestInvokerTypes::Testable.new(
994
+ :name => 'a_test',
995
+ :filepath => 'test/a_test.c',
996
+ :objects => ['build/foo.o'],
997
+ :executable => 'build/a_test.out',
998
+ :link_flags => [],
999
+ :paths => { :build => 'build/test' }
1000
+ )
1001
+ @state = TestInvokerTypes::PipelineState.new( :testables => { :a_test => @testable }, :lock => Mutex.new, :context => :test, :options => [] )
1002
+ end
1003
+
1004
+ it "links and marks the executable fresh, and records that it was rebuilt, when the dependency tracker reports it stale" do
1005
+ allow(@dependinator).to receive(:stale?).and_return( true )
1006
+ expect(@generator).to receive(:generate_executable_file)
1007
+ expect(@dependinator).to receive(:mark_fresh).with('build/a_test.out')
1008
+
1009
+ @executor.stage_build_executables( @state )
1010
+
1011
+ expect( @testable.executable_rebuilt ).to be(true)
1012
+ end
1013
+
1014
+ it "skips linking and records that it was not rebuilt when the dependency tracker reports it unchanged" do
1015
+ allow(@dependinator).to receive(:stale?).and_return( false )
1016
+ expect(@generator).to_not receive(:generate_executable_file)
1017
+ expect(@dependinator).to_not receive(:mark_fresh)
1018
+
1019
+ @executor.stage_build_executables( @state )
1020
+
1021
+ expect( @testable.executable_rebuilt ).to be(false)
1022
+ end
1023
+
1024
+ # An executable linked by an earlier build still needs its manifest
1025
+ it "provides each executable its manifest, whether linked or skipped" do
1026
+ allow(@generator).to receive(:generate_executable_file)
1027
+
1028
+ [true, false].each do |stale|
1029
+ allow(@dependinator).to receive(:stale?).and_return( stale )
1030
+ expect(@generator).to receive(:generate_test_executable_manifest).with( executable: 'build/a_test.out', test_filepath: 'test/a_test.c' )
1031
+
1032
+ @executor.stage_build_executables( @state )
1033
+ end
1034
+ end
1035
+
1036
+ it "resolves the link tool/flags through pre_test_link_register before registering staleness meta, and uses the resolved values for the real link" do
1037
+ allow(@dependinator).to receive(:stale?).and_return( true )
1038
+
1039
+ swapped_tool = { name: 'fake bullseye linker' }
1040
+ allow(@plugin_manager).to receive(:pre_test_link_register) do |arg_hash|
1041
+ arg_hash[:tool] = swapped_tool
1042
+ end
1043
+
1044
+ expect(@dependinator).to receive(:register).with(
1045
+ 'build/a_test.out',
1046
+ files: ['build/foo.o'],
1047
+ meta: hash_including( tools: [swapped_tool] )
1048
+ )
1049
+ expect(@generator).to receive(:generate_executable_file) do |tool, *_rest|
1050
+ expect( tool ).to eq( swapped_tool )
1051
+ end
1052
+
1053
+ @executor.stage_build_executables( @state )
1054
+ end
1055
+
1056
+ it "registers the configured test linker tool as meta, alongside link flags and library arguments" do
1057
+ allow(@dependinator).to receive(:stale?).and_return( false )
1058
+
1059
+ expect(@dependinator).to receive(:register).with(
1060
+ 'build/a_test.out',
1061
+ files: ['build/foo.o'],
1062
+ meta: { flags: [], lib_args: [], lib_paths: [], tools: [@tools_test_linker] }
1063
+ )
1064
+
1065
+ @executor.stage_build_executables( @state )
1066
+ end
1067
+
1068
+ it "logs a summary line stating how many executables were recalled from cache" do
1069
+ allow(@dependinator).to receive(:stale?).and_return( false )
1070
+
1071
+ allow(@reportinator).to receive(:generate_skip_summary).and_return( "Skipping linking for 1 executable (nothing changed)..." )
1072
+
1073
+ expect(@loginator).to receive(:log).with( "Skipping linking for 1 executable (nothing changed)..." )
1074
+ @executor.stage_build_executables( @state )
1075
+ end
1076
+ end
1077
+
1078
+ context "#generate_executable" do
1079
+ before(:each) do
1080
+ allow(@file_path_utils).to receive(:form_test_build_map_filepath).and_return( 'build/map' )
1081
+ allow(@configurator).to receive(:project_use_mocks).and_return( false )
1082
+ end
1083
+
1084
+ def build_args
1085
+ {
1086
+ context: :test,
1087
+ build_path: 'build/test',
1088
+ executable: 'build/a_test.out',
1089
+ objects: ['build/foo.o'],
1090
+ flags: [],
1091
+ lib_args: [],
1092
+ lib_paths: [],
1093
+ tool: { name: 'fake linker' }
1094
+ }
1095
+ end
1096
+
1097
+ it "re-raises a ShellException from the linker" do
1098
+ ex = ShellException.new( shell_result: { output: 'some unrelated linker failure' }, name: 'linker' )
1099
+ allow(@generator).to receive(:generate_executable_file).and_raise( ex )
1100
+ allow(@loginator).to receive(:log)
1101
+
1102
+ expect {
1103
+ @executor.generate_executable( **build_args )
1104
+ }.to raise_error( ShellException )
1105
+ end
1106
+
1107
+ it "logs missing-symbols guidance when the shell output mentions a symbol, before re-raising" do
1108
+ ex = ShellException.new( shell_result: { output: 'undefined reference to symbol foo' }, name: 'linker' )
1109
+ allow(@generator).to receive(:generate_executable_file).and_raise( ex )
1110
+
1111
+ expect(@loginator).to receive(:log).with(
1112
+ a_string_matching(/missing symbols/i),
1113
+ Verbosity::COMPLAIN,
1114
+ LogLabels::NOTICE
1115
+ )
1116
+
1117
+ expect {
1118
+ @executor.generate_executable( **build_args )
1119
+ }.to raise_error( ShellException )
1120
+ end
1121
+
1122
+ it "does not log guidance when the shell output does not mention a symbol" do
1123
+ ex = ShellException.new( shell_result: { output: 'some unrelated linker failure' }, name: 'linker' )
1124
+ allow(@generator).to receive(:generate_executable_file).and_raise( ex )
1125
+
1126
+ expect(@loginator).to_not receive(:log)
1127
+
1128
+ expect {
1129
+ @executor.generate_executable( **build_args )
1130
+ }.to raise_error( ShellException )
1131
+ end
1132
+
1133
+ it "includes mock-specific guidance only when the project uses mocks" do
1134
+ ex = ShellException.new( shell_result: { output: 'missing symbol foo' }, name: 'linker' )
1135
+ allow(@generator).to receive(:generate_executable_file).and_raise( ex )
1136
+ allow(@configurator).to receive(:project_use_mocks).and_return( true )
1137
+
1138
+ expect(@loginator).to receive(:log).with(
1139
+ a_string_matching(/needed mocks/i),
1140
+ Verbosity::COMPLAIN,
1141
+ LogLabels::NOTICE
1142
+ )
1143
+
1144
+ expect {
1145
+ @executor.generate_executable( **build_args )
1146
+ }.to raise_error( ShellException )
1147
+ end
1148
+
1149
+ it "does not raise when the linker succeeds" do
1150
+ allow(@generator).to receive(:generate_executable_file)
1151
+
1152
+ expect { @executor.generate_executable( **build_args ) }.to_not raise_error
1153
+ end
1154
+ end
1155
+
1156
+ context "#stage_execute" do
1157
+ before(:each) do
1158
+ stub_batchinator_exec()
1159
+ allow(@plugin_manager).to receive(:post_test)
1160
+ # Flushed once after every testable in this stage has executed -- see
1161
+ # `report_gdb_attach_health`'s own spec for its actual behavior.
1162
+ allow(@generator).to receive(:report_gdb_attach_health)
1163
+
1164
+ # This context's own tests are about executable_rebuilt/force_rerun/shuffle
1165
+ # deciding whether a fixture reruns, so the fixture-target's own staleness
1166
+ # (the tool-config trigger) defaults to fresh here -- see the dedicated
1167
+ # "tool configuration changed" examples below for that case on its own.
1168
+ allow(@dependinator).to receive(:stale?).and_return( false )
1169
+ allow(@file_wrapper).to receive(:touch)
1170
+
1171
+ @testable = TestInvokerTypes::Testable.new(
1172
+ :name => 'a_test',
1173
+ :filepath => 'test/TestFoo.c',
1174
+ :executable => 'build/a_test.out',
1175
+ :results_pass => 'build/a_test.pass',
1176
+ :paths => { :results => 'build/test/results' }
1177
+ )
1178
+ @state = TestInvokerTypes::PipelineState.new( :testables => { :a_test => @testable }, :lock => Mutex.new, :context => :test, :options => [] )
1179
+ @fixture_target = 'build/test/results/a_test.fixture_run'
1180
+ end
1181
+
1182
+ it "runs the test fixture when stage 16 rebuilt the executable, first clearing any stale prior result" do
1183
+ @testable.executable_rebuilt = true
1184
+ allow(@file_wrapper).to receive(:rm_f)
1185
+ expect(@file_wrapper).to receive(:rm_f).with( Dir.glob( File.join( 'build/test/results', 'a_test.*' ) ) )
1186
+ expect(@generator).to receive(:generate_test_results).with( hash_including( skipped: false ) )
1187
+
1188
+ @executor.stage_execute( @state )
1189
+ end
1190
+
1191
+ # A skipped run reuses the result file, so the fixture target vouches for it. Damage
1192
+ # to that file then reads as stale and the test reruns instead of reusing it.
1193
+ it "registers the result files as outputs of the fixture target before marking it fresh after a real run" do
1194
+ @testable.executable_rebuilt = true
1195
+ allow(@file_wrapper).to receive(:rm_f)
1196
+ allow(@generator).to receive(:generate_test_results)
1197
+
1198
+ expect(@dependinator).to receive(:register).with( @fixture_target, outputs: ['build/a_test.pass', 'build/a_test.fail'] ).ordered
1199
+ expect(@dependinator).to receive(:mark_fresh).with( @fixture_target ).ordered
1200
+
1201
+ @executor.stage_execute( @state )
1202
+ end
1203
+
1204
+ it "registers no outputs on a skipped run" do
1205
+ @testable.executable_rebuilt = false
1206
+ allow(@generator).to receive(:generate_test_results)
1207
+
1208
+ expect(@dependinator).to_not receive(:register).with( @fixture_target, hash_including( :outputs ) )
1209
+
1210
+ @executor.stage_execute( @state )
1211
+ end
1212
+
1213
+ it "reports the cached result instead of running the test fixture when stage 16 found the executable unchanged, and does not touch the cached result file" do
1214
+ @testable.executable_rebuilt = false
1215
+ expect(@generator).to receive(:generate_test_results).with( hash_including( skipped: true ) )
1216
+ expect(@file_wrapper).to_not receive(:rm_f)
1217
+
1218
+ @executor.stage_execute( @state )
1219
+ end
1220
+
1221
+ it "runs the test fixture and clears any stale prior result when :force_test_rerun is enabled, even though the executable is unchanged" do
1222
+ @testable.executable_rebuilt = false
1223
+ allow(@configurator).to receive(:force_test_rerun).and_return( true )
1224
+ allow(@file_wrapper).to receive(:rm_f)
1225
+ expect(@file_wrapper).to receive(:rm_f).with( Dir.glob( File.join( 'build/test/results', 'a_test.*' ) ) )
1226
+ expect(@generator).to receive(:generate_test_results).with( hash_including( skipped: false ) )
1227
+
1228
+ @executor.stage_execute( @state )
1229
+ end
1230
+
1231
+ it "runs the test fixture and clears any stale prior result when :unity ↳ :shuffle_tests is enabled, even though the executable is unchanged" do
1232
+ @testable.executable_rebuilt = false
1233
+ allow(@configurator).to receive(:unity_shuffle_tests).and_return( true )
1234
+ allow(@file_wrapper).to receive(:rm_f)
1235
+ expect(@file_wrapper).to receive(:rm_f).with( Dir.glob( File.join( 'build/test/results', 'a_test.*' ) ) )
1236
+ expect(@generator).to receive(:generate_test_results).with( hash_including( skipped: false ) )
1237
+
1238
+ @executor.stage_execute( @state )
1239
+ end
1240
+
1241
+ it "logs a NOTICE that shuffling is overriding a delta-build skip when :unity ↳ :shuffle_tests is enabled and the executable is unchanged" do
1242
+ @testable.executable_rebuilt = false
1243
+ allow(@configurator).to receive(:unity_shuffle_tests).and_return( true )
1244
+ allow(@generator).to receive(:generate_test_results)
1245
+ allow(@file_wrapper).to receive(:rm_f)
1246
+
1247
+ expect(@loginator).to receive(:log)
1248
+ .with( /1 already up-to-date test executable/, Verbosity::NORMAL, LogLabels::NOTICE )
1249
+
1250
+ @executor.stage_execute( @state )
1251
+ end
1252
+
1253
+ it "does not log the shuffling NOTICE when :unity ↳ :shuffle_tests is enabled but the executable was already rebuilt (nothing to override)" do
1254
+ @testable.executable_rebuilt = true
1255
+ allow(@configurator).to receive(:unity_shuffle_tests).and_return( true )
1256
+ allow(@generator).to receive(:generate_test_results)
1257
+ allow(@file_wrapper).to receive(:rm_f)
1258
+
1259
+ expect(@loginator).to_not receive(:log).with( /shuffl/i, any_args )
1260
+
1261
+ @executor.stage_execute( @state )
1262
+ end
1263
+
1264
+ it "does not log the shuffling NOTICE when :force_test_rerun (not shuffling) is what forces the rerun" do
1265
+ @testable.executable_rebuilt = false
1266
+ allow(@configurator).to receive(:force_test_rerun).and_return( true )
1267
+ allow(@generator).to receive(:generate_test_results)
1268
+ allow(@file_wrapper).to receive(:rm_f)
1269
+
1270
+ expect(@loginator).to_not receive(:log).with( /shuffl/i, any_args )
1271
+
1272
+ @executor.stage_execute( @state )
1273
+ end
1274
+
1275
+ it "always fires the post_test plugin hook, rebuilt or not" do
1276
+ @testable.executable_rebuilt = false
1277
+ allow(@generator).to receive(:generate_test_results)
1278
+ expect(@plugin_manager).to receive(:post_test).with('test/TestFoo.c')
1279
+
1280
+ @executor.stage_execute( @state )
1281
+ end
1282
+
1283
+ it "logs a summary line stating how many tests reused a cached result" do
1284
+ @testable.executable_rebuilt = false
1285
+ allow(@generator).to receive(:generate_test_results)
1286
+
1287
+ allow(@reportinator).to receive(:generate_skip_summary).and_return( "Skipping test execution for 1 test (reusing cached results)..." )
1288
+
1289
+ expect(@loginator).to receive(:log).with( "Skipping test execution for 1 test (reusing cached results)..." )
1290
+ @executor.stage_execute( @state )
1291
+ end
1292
+
1293
+ it "resolves the fixture tool through pre_test_fixture_register before registering staleness meta, and uses the resolved value for the real run" do
1294
+ @testable.executable_rebuilt = false
1295
+
1296
+ swapped_tool = { name: 'fake valgrind wrapper' }
1297
+ allow(@plugin_manager).to receive(:pre_test_fixture_register) do |arg_hash|
1298
+ expect( arg_hash[:target] ).to eq( @fixture_target )
1299
+ arg_hash[:tool] = swapped_tool
1300
+ end
1301
+
1302
+ expect(@dependinator).to receive(:register).with(
1303
+ @fixture_target,
1304
+ files: ['build/a_test.out'],
1305
+ meta: hash_including( tools: [swapped_tool] )
1306
+ )
1307
+ expect(@generator).to receive(:generate_test_results) do |**args|
1308
+ expect( args[:tool] ).to eq( swapped_tool )
1309
+ end
1310
+
1311
+ @executor.stage_execute( @state )
1312
+ end
1313
+
1314
+ it "registers a dedicated marker target separate from the executable, with the executable as antecedent and the test fixture tool as meta" do
1315
+ @testable.executable_rebuilt = false
1316
+ allow(@generator).to receive(:generate_test_results)
1317
+
1318
+ expect(@dependinator).to receive(:register).with(
1319
+ @fixture_target,
1320
+ files: ['build/a_test.out'],
1321
+ meta: hash_including( tools: [@tools_test_fixture] )
1322
+ )
1323
+
1324
+ @executor.stage_execute( @state )
1325
+ end
1326
+
1327
+ # :use_backtrace doesn't swap the fixture tool itself -- it only selects what
1328
+ # generator.rb does *after* a crash is detected (see this call site's own comment
1329
+ # in test_build_executor.rb). Without capturing it (and the tool config(s) it
1330
+ # drives) as meta here, toggling it would never invalidate a cached-fresh
1331
+ # fixture_target, so a delta build would keep reusing a stale crash-diagnosis result.
1332
+ it "registers :use_backtrace and the gdb backtrace tool as meta when :use_backtrace is :gdb" do
1333
+ @testable.executable_rebuilt = false
1334
+ allow(@generator).to receive(:generate_test_results)
1335
+ allow(@configurator).to receive(:project_config_hash).and_return( { project_use_backtrace: :gdb } )
1336
+ allow(@configurator).to receive(:tools_test_backtrace_gdb).and_return( @tools_test_backtrace_gdb )
1337
+
1338
+ expect(@dependinator).to receive(:register).with(
1339
+ @fixture_target,
1340
+ files: ['build/a_test.out'],
1341
+ meta: {
1342
+ tools: [@tools_test_fixture],
1343
+ use_backtrace: :gdb,
1344
+ backtrace_tools: [@tools_test_fixture_simple_backtrace, @tools_test_backtrace_gdb],
1345
+ include_test_case: '',
1346
+ exclude_test_case: ''
1347
+ }
1348
+ )
1349
+
1350
+ @executor.stage_execute( @state )
1351
+ end
1352
+
1353
+ # Regression guard: tools_test_backtrace_gdb only exists on the real Configurator
1354
+ # when :use_backtrace is :gdb (Configurator only merges its defaults in that case) --
1355
+ # calling it unconditionally raised NoMethodError against a real project configured
1356
+ # for :simple or :none. @configurator here is a plain double with no stub for
1357
+ # tools_test_backtrace_gdb, so it fails the same way a real run would if this
1358
+ # regressed.
1359
+ it "registers only the simple backtrace tool as meta, and never reads the gdb tool's config, when :use_backtrace is :simple" do
1360
+ @testable.executable_rebuilt = false
1361
+ allow(@generator).to receive(:generate_test_results)
1362
+ allow(@configurator).to receive(:project_config_hash).and_return( { project_use_backtrace: :simple } )
1363
+
1364
+ expect(@dependinator).to receive(:register).with(
1365
+ @fixture_target,
1366
+ files: ['build/a_test.out'],
1367
+ meta: {
1368
+ tools: [@tools_test_fixture],
1369
+ use_backtrace: :simple,
1370
+ backtrace_tools: [@tools_test_fixture_simple_backtrace],
1371
+ include_test_case: '',
1372
+ exclude_test_case: ''
1373
+ }
1374
+ )
1375
+
1376
+ @executor.stage_execute( @state )
1377
+ end
1378
+
1379
+ # An executable linked with command line arguments enabled is the same with or without
1380
+ # a filter, so only the filter tells one run's results from another's (GH #1360)
1381
+ it "registers the command line test case filters as meta" do
1382
+ @testable.executable_rebuilt = false
1383
+ allow(@generator).to receive(:generate_test_results)
1384
+ allow(@configurator).to receive(:include_test_case).and_return( 'test_one' )
1385
+ allow(@configurator).to receive(:exclude_test_case).and_return( 'test_two' )
1386
+
1387
+ expect(@dependinator).to receive(:register).with(
1388
+ @fixture_target,
1389
+ files: ['build/a_test.out'],
1390
+ meta: hash_including( include_test_case: 'test_one', exclude_test_case: 'test_two' )
1391
+ )
1392
+
1393
+ @executor.stage_execute( @state )
1394
+ end
1395
+
1396
+ it "reruns the test fixture when only the :tools ↳ :test_fixture configuration changed, even though the executable is unchanged" do
1397
+ @testable.executable_rebuilt = false
1398
+ allow(@dependinator).to receive(:stale?).with(@fixture_target).and_return( true )
1399
+ allow(@file_wrapper).to receive(:rm_f)
1400
+
1401
+ expect(@file_wrapper).to receive(:rm_f).with( Dir.glob( File.join( 'build/test/results', 'a_test.*' ) ) )
1402
+ expect(@generator).to receive(:generate_test_results).with( hash_including( skipped: false ) )
1403
+ expect(@dependinator).to receive(:mark_fresh).with(@fixture_target)
1404
+
1405
+ @executor.stage_execute( @state )
1406
+ end
1407
+
1408
+ # The whole reason this target is a dedicated marker file rather than the test's own
1409
+ # outcome-dependent .pass/.fail result file: a failing test never writes the .pass
1410
+ # path, and DependencyTracker#mark_fresh would otherwise crash trying to hash a target
1411
+ # that doesn't exist -- exactly the CI failure this scenario guards against regressing.
1412
+ it "marks the marker target fresh after a real run even when the test itself fails" do
1413
+ @testable.executable_rebuilt = true
1414
+ allow(@file_wrapper).to receive(:rm_f)
1415
+ allow(@generator).to receive(:generate_test_results).and_return( { results: { counts: { failed: 1 } } } )
1416
+
1417
+ expect(@file_wrapper).to receive(:touch).with(@fixture_target)
1418
+ expect(@dependinator).to receive(:mark_fresh).with(@fixture_target)
1419
+
1420
+ @executor.stage_execute( @state )
1421
+ end
1422
+
1423
+ it "does not mark the fixture target fresh when the run was skipped" do
1424
+ @testable.executable_rebuilt = false
1425
+ allow(@generator).to receive(:generate_test_results)
1426
+
1427
+ expect(@dependinator).to_not receive(:mark_fresh)
1428
+
1429
+ @executor.stage_execute( @state )
1430
+ end
1431
+ end
1432
+
1433
+ context "#stage_preprocess_mocks" do
1434
+ before(:each) do
1435
+ stub_batchinator_exec()
1436
+
1437
+ allow(@configurator).to receive(:test_build_preprocess_directives_only_available).and_return( false )
1438
+ allow(@configurator).to receive(:cmock_treat_inlines).and_return( :exclude )
1439
+ allow(@configurator).to receive(:project_build_vendor_ceedling_path).and_return( 'build/vendor/ceedling' )
1440
+ allow(@file_path_utils).to receive(:form_preprocessed_file_filepath).and_return( 'build/preprocess/MockFoo.h' )
1441
+
1442
+ @testable = TestInvokerTypes::Testable.new(
1443
+ :name => 'a_test',
1444
+ :preprocess_flags => [], :preprocess_defines => [], :search_paths => []
1445
+ )
1446
+ mock = TestInvokerTypes::MockWork.new(
1447
+ :details => TestInvokerTypes::MockDetails.new( :source => 'src/Foo.h', :path => 'sub' ),
1448
+ :testable => @testable,
1449
+ :name => :MockFoo,
1450
+ :directives_only_filepath => nil
1451
+ )
1452
+ @state = TestInvokerTypes::PipelineState.new( :testables => { :a_test => @testable }, :mocks_list => [mock], :context => :test, :options => [] )
1453
+ end
1454
+
1455
+ it "preprocesses and marks fresh the mockable header when the dependency tracker reports it stale" do
1456
+ allow(@dependinator).to receive(:stale?).and_return( true )
1457
+ expect(@preprocessinator).to receive(:preprocess_mockable_header_file)
1458
+ expect(@dependinator).to receive(:mark_fresh).with('build/preprocess/MockFoo.h')
1459
+
1460
+ @executor.stage_preprocess_mocks( @state )
1461
+ end
1462
+
1463
+ it "skips preprocessing the mockable header when the dependency tracker reports it unchanged" do
1464
+ allow(@dependinator).to receive(:stale?).and_return( false )
1465
+ expect(@preprocessinator).to_not receive(:preprocess_mockable_header_file)
1466
+ expect(@dependinator).to_not receive(:mark_fresh)
1467
+
1468
+ @executor.stage_preprocess_mocks( @state )
1469
+ end
1470
+
1471
+ it "logs a summary line stating how many mocks' preprocessing was recalled from cache" do
1472
+ allow(@dependinator).to receive(:stale?).and_return( false )
1473
+
1474
+ allow(@reportinator).to receive(:generate_skip_summary).and_return( "Skipping mock preprocessing for 1 mock (nothing changed)..." )
1475
+
1476
+ expect(@loginator).to receive(:log).with( "Skipping mock preprocessing for 1 mock (nothing changed)..." )
1477
+ @executor.stage_preprocess_mocks( @state )
1478
+ end
1479
+
1480
+ it "registers the bare-includes and directives-only preprocessor tools, and the fallback setting, as meta" do
1481
+ allow(@preprocessinator).to receive(:preprocess_mockable_header_file)
1482
+
1483
+ expect(@dependinator).to receive(:register).with(
1484
+ 'build/preprocess/MockFoo.h',
1485
+ files: ['src/Foo.h'],
1486
+ meta: {
1487
+ flags: [], defines: [], search_paths: [], extras: false,
1488
+ tools: [@tools_test_bare_includes_preprocessor, @tools_test_file_directives_only_preprocessor],
1489
+ preprocess_force_fallback: false
1490
+ }
1491
+ )
1492
+
1493
+ @executor.stage_preprocess_mocks( @state )
1494
+ end
1495
+
1496
+ it "runs the extra treat-inlines-aware pass for an ordinary mock when the project configures :treat_inlines: :include" do
1497
+ allow(@configurator).to receive(:cmock_treat_inlines).and_return( :include )
1498
+ allow(@preprocessinator).to receive(:preprocess_mockable_header_file)
1499
+
1500
+ expect(@dependinator).to receive(:register).with(
1501
+ 'build/preprocess/MockFoo.h',
1502
+ files: anything,
1503
+ meta: hash_including( extras: true )
1504
+ )
1505
+
1506
+ @executor.stage_preprocess_mocks( @state )
1507
+ end
1508
+
1509
+ it "skips the extra treat-inlines-aware pass for a Partial mock even when the project configures :treat_inlines: :include -- its own generated header is already inline-free" do
1510
+ @state.mocks_list.first.details.partial = true
1511
+ allow(@configurator).to receive(:cmock_treat_inlines).and_return( :include )
1512
+ allow(@preprocessinator).to receive(:preprocess_mockable_header_file)
1513
+
1514
+ expect(@dependinator).to receive(:register).with(
1515
+ 'build/preprocess/MockFoo.h',
1516
+ files: anything,
1517
+ meta: hash_including( extras: false )
1518
+ )
1519
+
1520
+ @executor.stage_preprocess_mocks( @state )
1521
+ end
1522
+ end
1523
+
1524
+ context "#stage_generate_mocks" do
1525
+ before(:each) do
1526
+ stub_batchinator_exec()
1527
+
1528
+ allow(@configurator).to receive(:project_config_hash).and_return( {} )
1529
+ allow(@configurator).to receive(:get_cmock_config).and_return( { mock_prefix: 'Mock' } )
1530
+ allow(@configurator).to receive(:cmock_mock_name_include_folder).and_return( true )
1531
+ allow(@file_wrapper).to receive(:mkdir)
1532
+ # Where a mock's files sit is composed in one shared place, so the stage that
1533
+ # compiles a mock and the stage that generates it cannot disagree.
1534
+ allow(@file_path_utils).to receive(:form_mock_output_path) do |root, subdir|
1535
+ subdir.nil? || subdir.empty? ? root : File.join( root, subdir )
1536
+ end
1537
+
1538
+ @testable = TestInvokerTypes::Testable.new(
1539
+ :name => 'a_test',
1540
+ :paths => { :mocks => 'build/test/mocks' }
1541
+ )
1542
+ mock = TestInvokerTypes::MockWork.new(
1543
+ :details => TestInvokerTypes::MockDetails.new(
1544
+ :source => 'src/Foo.h', :path => 'sub', :input => 'build/preprocess/MockFoo.h', :name => 'MockFoo'
1545
+ ),
1546
+ :testable => @testable,
1547
+ :name => :MockFoo
1548
+ )
1549
+ @state = TestInvokerTypes::PipelineState.new( :testables => { :a_test => @testable }, :mocks_list => [mock], :lock => Mutex.new, :context => :test, :options => [] )
1550
+ end
1551
+
1552
+ it "generates and marks fresh the mock when the dependency tracker reports it stale" do
1553
+ allow(@dependinator).to receive(:stale?).and_return( true )
1554
+ expect(@generator).to receive(:generate_mock)
1555
+ expect(@dependinator).to receive(:mark_fresh).with('build/test/mocks/sub/MockFoo.c')
1556
+
1557
+ @executor.stage_generate_mocks( @state )
1558
+ end
1559
+
1560
+ it "skips generating the mock when the dependency tracker reports it unchanged" do
1561
+ allow(@dependinator).to receive(:stale?).and_return( false )
1562
+ expect(@generator).to_not receive(:generate_mock)
1563
+ expect(@dependinator).to_not receive(:mark_fresh)
1564
+
1565
+ @executor.stage_generate_mocks( @state )
1566
+ end
1567
+
1568
+ it "logs a summary line stating how many mocks were recalled from cache" do
1569
+ allow(@dependinator).to receive(:stale?).and_return( false )
1570
+
1571
+ allow(@reportinator).to receive(:generate_skip_summary).and_return( "Skipping mock generation for 1 mock (nothing changed)..." )
1572
+
1573
+ expect(@loginator).to receive(:log).with( "Skipping mock generation for 1 mock (nothing changed)..." )
1574
+ @executor.stage_generate_mocks( @state )
1575
+ end
1576
+
1577
+ it "tracks the mock's own generated header as an output of the mock" do
1578
+ # Includes stand-in generation (test_build_setup.rb) can overwrite a mock's
1579
+ # generated header with a blank placeholder on a run where only the test file's
1580
+ # own bare-includes cache misses. The header's recorded hash is what lets that
1581
+ # overwrite be detected and the mock regenerated on the next run.
1582
+ allow(@dependinator).to receive(:stale?).and_return( true )
1583
+ allow(@generator).to receive(:generate_mock)
1584
+ allow(@dependinator).to receive(:mark_fresh)
1585
+
1586
+ expect(@dependinator).to receive(:register).with(
1587
+ 'build/test/mocks/sub/MockFoo.c',
1588
+ files: ['build/preprocess/MockFoo.h'],
1589
+ meta: anything,
1590
+ outputs: ['build/test/mocks/sub/MockFoo.h']
1591
+ )
1592
+
1593
+ @executor.stage_generate_mocks( @state )
1594
+ end
1595
+
1596
+ it "registers CMock's actual configuration as meta, not project_config_hash's flattened (and therefore always-empty) :cmock entry" do
1597
+ # project_config_hash is flattened -- CMock's settings live there as individual
1598
+ # top-level keys like :cmock_mock_prefix, never as a :cmock section -- so a
1599
+ # config change (e.g. :cmock ↳ :mock_prefix) can only be detected here via
1600
+ # get_cmock_config, the one place CMock's configuration still exists as a
1601
+ # single value.
1602
+ allow(@configurator).to receive(:get_cmock_config).and_return( { mock_prefix: 'Custom' } )
1603
+ allow(@dependinator).to receive(:stale?).and_return( true )
1604
+ allow(@generator).to receive(:generate_mock)
1605
+ allow(@dependinator).to receive(:mark_fresh)
1606
+
1607
+ expect(@dependinator).to receive(:register).with(
1608
+ 'build/test/mocks/sub/MockFoo.c',
1609
+ files: anything,
1610
+ meta: { cmock: { mock_prefix: 'Custom' } },
1611
+ outputs: anything
1612
+ )
1613
+
1614
+ @executor.stage_generate_mocks( @state )
1615
+ end
1616
+
1617
+ it "generates an ordinary mock with no configuration override" do
1618
+ allow(@dependinator).to receive(:stale?).and_return( true )
1619
+ allow(@dependinator).to receive(:mark_fresh)
1620
+
1621
+ expect(@generator).to receive(:generate_mock).with( hash_including( overrides: {} ) )
1622
+
1623
+ @executor.stage_generate_mocks( @state )
1624
+ end
1625
+
1626
+ it "generates a Partial mock with its inline handling disabled, redundant alongside Partials' own" do
1627
+ @state.mocks_list.first.details.partial = true
1628
+ allow(@dependinator).to receive(:stale?).and_return( true )
1629
+ allow(@dependinator).to receive(:mark_fresh)
1630
+
1631
+ expect(@generator).to receive(:generate_mock).with( hash_including( overrides: { treat_inlines: :exclude } ) )
1632
+
1633
+ @executor.stage_generate_mocks( @state )
1634
+ end
1635
+
1636
+ # CMock and the runner both name a mock by the folder its #include names. CMock writes
1637
+ # below its own root at that folder, so the folder must also end the mock's directory.
1638
+ context "naming a mock by its #include's folder" do
1639
+ before(:each) do
1640
+ allow(@dependinator).to receive(:stale?).and_return( true )
1641
+ allow(@dependinator).to receive(:mark_fresh)
1642
+ end
1643
+
1644
+ def include_as(path)
1645
+ @state.mocks_list.first.details.include_path = path
1646
+ end
1647
+
1648
+ it "passes no folder for a bare #include and keeps the mirrored location" do
1649
+ include_as( 'MockFoo.h' )
1650
+
1651
+ expect(@generator).to receive(:generate_mock)
1652
+ .with( hash_including( output_path: 'build/test/mocks/sub', folder: nil ) )
1653
+
1654
+ @executor.stage_generate_mocks( @state )
1655
+ end
1656
+
1657
+ it "passes the folder and keeps the mirrored location when the folder ends it" do
1658
+ include_as( 'sub/MockFoo.h' )
1659
+
1660
+ expect(@generator).to receive(:generate_mock)
1661
+ .with( hash_including( output_path: 'build/test/mocks/sub', folder: 'sub' ) )
1662
+
1663
+ @executor.stage_generate_mocks( @state )
1664
+ end
1665
+
1666
+ # The runner ignores a leading ./ too, so both name the mock alike
1667
+ it "drops a leading ./ from the folder" do
1668
+ include_as( './sub/MockFoo.h' )
1669
+
1670
+ expect(@generator).to receive(:generate_mock)
1671
+ .with( hash_including( output_path: 'build/test/mocks/sub', folder: 'sub' ) )
1672
+
1673
+ @executor.stage_generate_mocks( @state )
1674
+ end
1675
+
1676
+ # The mirror cannot hold a folder longer than itself, so the mock moves to the
1677
+ # written path below the per-test root, and its tracked target moves with it.
1678
+ it "places the mock at its written path when the #include spells more than the mirror" do
1679
+ include_as( 'more/sub/MockFoo.h' )
1680
+
1681
+ expect(@generator).to receive(:generate_mock)
1682
+ .with( hash_including( output_path: 'build/test/mocks/more/sub', folder: 'more/sub' ) )
1683
+ expect(@dependinator).to receive(:mark_fresh).with( 'build/test/mocks/more/sub/MockFoo.c' )
1684
+
1685
+ @executor.stage_generate_mocks( @state )
1686
+ end
1687
+
1688
+ it "passes no folder when :mock_name_include_folder is disabled" do
1689
+ allow(@configurator).to receive(:cmock_mock_name_include_folder).and_return( false )
1690
+ include_as( 'sub/MockFoo.h' )
1691
+
1692
+ expect(@generator).to receive(:generate_mock)
1693
+ .with( hash_including( output_path: 'build/test/mocks/sub', folder: nil ) )
1694
+
1695
+ @executor.stage_generate_mocks( @state )
1696
+ end
1697
+ end
1698
+ end
1699
+
1700
+ context "#tailor_search_paths" do
1701
+ PROJECT_BUILD_VENDOR_CMOCK_PATH = 'build/vendor/cmock' unless defined?(PROJECT_BUILD_VENDOR_CMOCK_PATH)
1702
+ PROJECT_BUILD_VENDOR_CEXCEPTION_PATH = 'build/vendor/cexception' unless defined?(PROJECT_BUILD_VENDOR_CEXCEPTION_PATH)
1703
+
1704
+ before(:each) do
1705
+ allow(@configurator).to receive(:collection_paths_support).and_return( ['support'] )
1706
+ end
1707
+
1708
+ it "returns the given search paths unchanged for an ordinary test source" do
1709
+ result = @executor.send( :tailor_search_paths, filepath: 'src/Foo.c', search_paths: ['src', 'test'] )
1710
+
1711
+ expect(result).to eq( ['src', 'test'] )
1712
+ end
1713
+
1714
+ it "swaps in the support paths plus Unity's own vendor path for Unity's own source" do
1715
+ filepath = File.join( PROJECT_BUILD_VENDOR_UNITY_PATH, UNITY_C_FILE )
1716
+
1717
+ result = @executor.send( :tailor_search_paths, filepath: filepath, search_paths: ['src', 'test'] )
1718
+
1719
+ expect(result).to eq( ['support', PROJECT_BUILD_VENDOR_UNITY_PATH] )
1720
+ end
1721
+
1722
+ it "swaps in the support, Unity, and CMock vendor paths for CMock's own source when mocks are in use" do
1723
+ allow(@configurator).to receive(:project_use_mocks).and_return( true )
1724
+ filepath = File.join( PROJECT_BUILD_VENDOR_CMOCK_PATH, CMOCK_C_FILE )
1725
+
1726
+ result = @executor.send( :tailor_search_paths, filepath: filepath, search_paths: ['src', 'test'] )
1727
+
1728
+ expect(result).to eq( ['support', PROJECT_BUILD_VENDOR_UNITY_PATH, PROJECT_BUILD_VENDOR_CMOCK_PATH] )
1729
+ end
1730
+
1731
+ it "also folds in the CException vendor path for CMock's own source when exceptions are also in use" do
1732
+ allow(@configurator).to receive(:project_use_mocks).and_return( true )
1733
+ allow(@configurator).to receive(:project_use_exceptions).and_return( true )
1734
+ filepath = File.join( PROJECT_BUILD_VENDOR_CMOCK_PATH, CMOCK_C_FILE )
1735
+
1736
+ result = @executor.send( :tailor_search_paths, filepath: filepath, search_paths: ['src', 'test'] )
1737
+
1738
+ expect(result).to eq(
1739
+ ['support', PROJECT_BUILD_VENDOR_UNITY_PATH, PROJECT_BUILD_VENDOR_CMOCK_PATH, PROJECT_BUILD_VENDOR_CEXCEPTION_PATH]
1740
+ )
1741
+ end
1742
+
1743
+ it "leaves CMock's own source untouched when mocks are not in use, falling through to the given search paths" do
1744
+ filepath = File.join( PROJECT_BUILD_VENDOR_CMOCK_PATH, CMOCK_C_FILE )
1745
+
1746
+ result = @executor.send( :tailor_search_paths, filepath: filepath, search_paths: ['src', 'test'] )
1747
+
1748
+ expect(result).to eq( ['src', 'test'] )
1749
+ end
1750
+
1751
+ it "swaps in the support and CException vendor paths for CException's own source when exceptions are in use" do
1752
+ allow(@configurator).to receive(:project_use_exceptions).and_return( true )
1753
+ filepath = File.join( PROJECT_BUILD_VENDOR_CEXCEPTION_PATH, CEXCEPTION_C_FILE )
1754
+
1755
+ result = @executor.send( :tailor_search_paths, filepath: filepath, search_paths: ['src', 'test'] )
1756
+
1757
+ expect(result).to eq( ['support', PROJECT_BUILD_VENDOR_CEXCEPTION_PATH] )
1758
+ end
1759
+
1760
+ it "adds the support and every in-use framework's own vendor path for a support file" do
1761
+ allow(@configurator).to receive(:project_use_mocks).and_return( true )
1762
+ allow(@configurator).to receive(:project_use_exceptions).and_return( true )
1763
+ allow(@configurator).to receive(:collection_all_support).and_return( ['test/support/CustomAsserts.c'] )
1764
+
1765
+ result = @executor.send( :tailor_search_paths, filepath: 'test/support/CustomAsserts.c', search_paths: ['src', 'test'] )
1766
+
1767
+ expect(result).to eq(
1768
+ ['src', 'test', 'support', PROJECT_BUILD_VENDOR_UNITY_PATH, PROJECT_BUILD_VENDOR_CMOCK_PATH, PROJECT_BUILD_VENDOR_CEXCEPTION_PATH]
1769
+ )
1770
+ end
1771
+
1772
+ it "deduplicates the tailored search paths it assembles" do
1773
+ allow(@configurator).to receive(:collection_paths_support).and_return( ['support', PROJECT_BUILD_VENDOR_UNITY_PATH] )
1774
+ filepath = File.join( PROJECT_BUILD_VENDOR_UNITY_PATH, UNITY_C_FILE )
1775
+
1776
+ result = @executor.send( :tailor_search_paths, filepath: filepath, search_paths: ['src', 'test'] )
1777
+
1778
+ expect(result).to eq( ['support', PROJECT_BUILD_VENDOR_UNITY_PATH] )
1779
+ end
1780
+ end
1781
+
1782
+
1783
+ context "#fixture_meta" do
1784
+ def meta(include: '', exclude: '')
1785
+ allow(@configurator).to receive(:include_test_case).and_return( include )
1786
+ allow(@configurator).to receive(:exclude_test_case).and_return( exclude )
1787
+ @executor.fixture_meta( fixture_tool: @tools_test_fixture, use_backtrace: :simple, backtrace_tools: [] )
1788
+ end
1789
+
1790
+ it "differs when the test case filters differ" do
1791
+ expect( meta( include: 'test_one' ) ).not_to eq( meta( include: 'test_two' ) )
1792
+ expect( meta( exclude: 'test_one' ) ).not_to eq( meta )
1793
+ end
1794
+
1795
+ it "is the same for an unset filter, whether nil or empty" do
1796
+ expect( meta( include: nil, exclude: nil ) ).to eq( meta( include: '', exclude: '' ) )
1797
+ end
113
1798
  end
114
1799
  end