ceedling 1.2.0 → 1.2.2

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 (383) hide show
  1. checksums.yaml +4 -4
  2. data/GIT_COMMIT_SHA +1 -1
  3. data/README.md +57 -58
  4. data/Rakefile +5 -3
  5. data/assets/features/ceedling +1 -1
  6. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_typo.c +14 -0
  7. data/assets/fixtures/tests_with_duplicate_test_names/test_foo.c +21 -0
  8. data/bin/actionator.rb +6 -12
  9. data/bin/app_cfg.rb +35 -1
  10. data/bin/ceedling +13 -3
  11. data/bin/cli.rb +25 -6
  12. data/bin/cli_handler.rb +119 -73
  13. data/bin/cli_helper.rb +56 -78
  14. data/bin/installation_selector.rb +81 -0
  15. data/bin/launchinator.rb +69 -0
  16. data/bin/mixin_resolvinator.rb +26 -36
  17. data/bin/objects.yml +13 -0
  18. data/bin/path_validator.rb +25 -29
  19. data/bin/versionator.rb +47 -48
  20. data/ceedling.gemspec +19 -15
  21. data/docs/BreakingChanges.md +70 -1
  22. data/docs/Changelog.md +84 -3
  23. data/docs/KnownIssues.md +90 -4
  24. data/docs/ReleaseNotes.md +13 -0
  25. data/docs/overrides/main.html +11 -8
  26. data/lib/ceedling/build_log_writer.rb +33 -0
  27. data/lib/ceedling/config/build_root_policy.rb +70 -0
  28. data/lib/ceedling/config/configurator.rb +19 -18
  29. data/lib/ceedling/config/configurator_builder.rb +58 -28
  30. data/lib/ceedling/config/configurator_paths_validator.rb +179 -0
  31. data/lib/ceedling/config/configurator_plugins.rb +1 -1
  32. data/lib/ceedling/config/configurator_setup.rb +39 -41
  33. data/lib/ceedling/config/configurator_validator.rb +1 -110
  34. data/lib/ceedling/defaults.rb +4 -4
  35. data/lib/ceedling/dependencies/README.md +18 -16
  36. data/lib/ceedling/dependencies/dependency_cache_store.rb +20 -3
  37. data/lib/ceedling/dependencies/dependency_hasher.rb +35 -1
  38. data/lib/ceedling/filename_extension.rb +7 -1
  39. data/lib/ceedling/filesystem/FILE_TREE.md +253 -0
  40. data/lib/ceedling/filesystem/PATH_HANDLING.md +304 -0
  41. data/lib/ceedling/filesystem/README.md +41 -0
  42. data/lib/ceedling/filesystem/build_subpath.rb +102 -0
  43. data/lib/ceedling/filesystem/destination_collision.rb +25 -0
  44. data/lib/ceedling/{file_finder.rb → filesystem/file_finder.rb} +159 -104
  45. data/lib/ceedling/{file_finder_helper.rb → filesystem/file_finder_helper.rb} +36 -31
  46. data/lib/ceedling/filesystem/file_path_collection_utils.rb +183 -0
  47. data/lib/ceedling/{file_path_utils.rb → filesystem/file_path_utils.rb} +108 -97
  48. data/lib/ceedling/{file_system_wrapper.rb → filesystem/file_system_wrapper.rb} +6 -5
  49. data/lib/ceedling/filesystem/file_tree.rb +241 -0
  50. data/lib/ceedling/{file_wrapper.rb → filesystem/file_wrapper.rb} +65 -28
  51. data/lib/ceedling/filesystem/path_exclusions.rb +30 -0
  52. data/lib/ceedling/{path_matcher.rb → filesystem/path_matcher.rb} +27 -23
  53. data/lib/ceedling/{path_mirror.rb → filesystem/path_mirror.rb} +19 -18
  54. data/lib/ceedling/filesystem/path_spellings.rb +55 -0
  55. data/lib/ceedling/filesystem/project_paths.rb +184 -0
  56. data/lib/ceedling/filesystem/working_dir.rb +40 -0
  57. data/lib/ceedling/generators/generator.rb +5 -6
  58. data/lib/ceedling/generators/generator_partials.rb +1 -1
  59. data/lib/ceedling/generators/generator_test_results_backtrace.rb +7 -7
  60. data/lib/ceedling/handoff.rb +121 -0
  61. data/lib/ceedling/includes/include_factory.rb +3 -3
  62. data/lib/ceedling/includes/include_pathinator.rb +67 -10
  63. data/lib/ceedling/includes/includes.rb +1 -1
  64. data/lib/ceedling/installation.rb +92 -0
  65. data/lib/ceedling/library_resolver.rb +99 -0
  66. data/lib/ceedling/objects.yml +23 -2
  67. data/lib/ceedling/partials/partializer.rb +4 -4
  68. data/lib/ceedling/partials/partializer_config.rb +3 -1
  69. data/lib/ceedling/plugins/report_log_writer_plugin.rb +3 -5
  70. data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +1 -1
  71. data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +1 -1
  72. data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +1 -1
  73. data/lib/ceedling/rake_app/rakefile_component_resolver.rb +10 -17
  74. data/lib/ceedling/rake_app/test_task_name.rb +29 -0
  75. data/lib/ceedling/rakefile.rb +16 -1
  76. data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
  77. data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
  78. data/lib/ceedling/rakefiles/tests/rules_tests.rake +3 -20
  79. data/lib/ceedling/rakefiles/tests/rules_tests_generate.rake +4 -30
  80. data/lib/ceedling/release_invoker/release_build_executor.rb +33 -44
  81. data/lib/ceedling/release_invoker/release_build_planner.rb +14 -6
  82. data/lib/ceedling/reportinator.rb +3 -4
  83. data/lib/ceedling/setupinator.rb +95 -87
  84. data/lib/ceedling/test_context_extractor.rb +5 -1
  85. data/lib/ceedling/test_invoker/PIPELINE.md +9 -7
  86. data/lib/ceedling/test_invoker/mock_locator.rb +60 -2
  87. data/lib/ceedling/test_invoker/partials_manager.rb +12 -0
  88. data/lib/ceedling/test_invoker/standin_headerinator.rb +22 -13
  89. data/lib/ceedling/test_invoker/test_build_executor.rb +42 -41
  90. data/lib/ceedling/test_invoker/test_build_planner.rb +37 -18
  91. data/lib/ceedling/test_invoker/test_build_setup.rb +17 -12
  92. data/lib/ceedling/test_invoker/test_build_validations.rb +16 -31
  93. data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +1 -1
  94. data/lib/ceedling/test_invoker/test_invoker.rb +6 -1
  95. data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +1 -1
  96. data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +40 -20
  97. data/lib/ceedling/tool_executor.rb +9 -3
  98. data/lib/ceedling/yaml_wrapper.rb +3 -2
  99. data/lib/version.rb +1 -1
  100. data/plugins/bullseye/bullseye.rake +6 -9
  101. data/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  102. data/plugins/bullseye/lib/bullseye.rb +9 -7
  103. data/plugins/cppcheck/config/defaults_cppcheck.rb +1 -1
  104. data/plugins/dependencies/config/defaults.yml +6 -6
  105. data/plugins/dependencies/dependencies.rake +4 -1
  106. data/plugins/dependencies/lib/dependencies.rb +18 -8
  107. data/plugins/dependencies/lib/dependency_spec.rb +17 -5
  108. data/plugins/fff/lib/fff.rb +45 -39
  109. data/plugins/fff/spec/fff_cmock_wrapper_spec.rb +128 -0
  110. data/plugins/gcov/config/defaults_gcov.rb +1 -1
  111. data/plugins/gcov/gcov.rake +6 -9
  112. data/plugins/gcov/lib/console_reportinator.rb +4 -18
  113. data/plugins/gcov/lib/gcov.rb +9 -2
  114. data/plugins/gcov/lib/gcovr_reportinator.rb +8 -40
  115. data/plugins/gcov/lib/gcovr_thresholds.rb +74 -0
  116. data/plugins/gcov/lib/reportgenerator_reportinator.rb +1 -1
  117. data/plugins/module_generator/lib/module_generator.rb +3 -3
  118. data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +53 -80
  119. data/plugins/sanitize/lib/sanitize_records.rb +3 -6
  120. data/plugins/sanitize/sanitize.rake +6 -6
  121. data/plugins/valgrind/lib/valgrind.rb +14 -7
  122. data/plugins/valgrind/valgrind.rake +6 -6
  123. data/site-local/404.html +6 -20
  124. data/site-local/assets/javascripts/{bundle.d7400e89.min.js → bundle.c21346df.min.js} +3 -3
  125. data/site-local/assets/javascripts/{bundle.d7400e89.min.js.map → bundle.c21346df.min.js.map} +2 -2
  126. data/site-local/assets/javascripts/workers/{search.2c215733.min.js → search.a7633da7.min.js} +2 -2
  127. data/site-local/assets/javascripts/workers/{search.2c215733.min.js.map → search.a7633da7.min.js.map} +1 -1
  128. data/site-local/assets/stylesheets/main.57a0d79d.min.css +6 -0
  129. data/site-local/assets/stylesheets/main.57a0d79d.min.css.map +1 -0
  130. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css +4 -0
  131. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css.map +1 -0
  132. data/site-local/configuration/environment-vars.html +6 -20
  133. data/site-local/configuration/global-collections.html +6 -20
  134. data/site-local/configuration/index.html +6 -20
  135. data/site-local/configuration/loading.html +6 -20
  136. data/site-local/configuration/mixins.html +10 -24
  137. data/site-local/configuration/parallel-builds.html +6 -20
  138. data/site-local/configuration/project-file.html +8 -22
  139. data/site-local/configuration/reference/cexception.html +6 -20
  140. data/site-local/configuration/reference/cmock.html +8 -21
  141. data/site-local/configuration/reference/defines.html +16 -30
  142. data/site-local/configuration/reference/environment.html +10 -24
  143. data/site-local/configuration/reference/extension.html +6 -20
  144. data/site-local/configuration/reference/files.html +22 -30
  145. data/site-local/configuration/reference/flags.html +13 -27
  146. data/site-local/configuration/reference/index.html +6 -20
  147. data/site-local/configuration/reference/libraries.html +27 -23
  148. data/site-local/configuration/reference/mixins.html +6 -20
  149. data/site-local/configuration/reference/partials.html +6 -20
  150. data/site-local/configuration/reference/paths.html +38 -29
  151. data/site-local/configuration/reference/plugins.html +6 -20
  152. data/site-local/configuration/reference/project.html +32 -36
  153. data/site-local/configuration/reference/release-build.html +8 -20
  154. data/site-local/configuration/reference/test-build.html +6 -20
  155. data/site-local/configuration/reference/test-runner.html +6 -20
  156. data/site-local/configuration/reference/tools.html +27 -32
  157. data/site-local/configuration/reference/unity.html +6 -20
  158. data/site-local/configuration/which-ceedling.html +383 -37
  159. data/site-local/development/index.html +6 -20
  160. data/site-local/development/plugins/configuration.html +6 -20
  161. data/site-local/development/plugins/index.html +6 -20
  162. data/site-local/development/plugins/plugin-subclass.html +54 -68
  163. data/site-local/development/plugins/rake-tasks.html +8 -22
  164. data/site-local/development/releases.html +84 -29
  165. data/site-local/development/workflow.html +62 -71
  166. data/site-local/getting-started/builds.html +8 -20
  167. data/site-local/getting-started/command-line.html +62 -24
  168. data/site-local/getting-started/example-projects/cipher-quest.html +6 -20
  169. data/site-local/getting-started/example-projects/index.html +6 -20
  170. data/site-local/getting-started/example-projects/temp-sensor.html +6 -20
  171. data/site-local/getting-started/example-projects/wondrous-forest.html +6 -20
  172. data/site-local/getting-started/index.html +6 -20
  173. data/site-local/getting-started/installation.html +6 -20
  174. data/site-local/getting-started/quick-start.html +6 -20
  175. data/site-local/help.html +6 -20
  176. data/site-local/index.html +11 -24
  177. data/site-local/overview/build-system.html +6 -20
  178. data/site-local/overview/index.html +6 -20
  179. data/site-local/overview/test-environments.html +6 -20
  180. data/site-local/overview/tools-and-frameworks.html +6 -20
  181. data/site-local/plugins/beep.html +6 -20
  182. data/site-local/plugins/bullseye/index.html +13 -24
  183. data/site-local/plugins/bullseye/licensing.html +14 -28
  184. data/site-local/plugins/command-hooks.html +8 -22
  185. data/site-local/plugins/compile-commands-json-db.html +6 -20
  186. data/site-local/plugins/cppcheck.html +8 -22
  187. data/site-local/plugins/dependencies.html +16 -27
  188. data/site-local/plugins/fff.html +49 -32
  189. data/site-local/plugins/gcov/examples.html +7 -21
  190. data/site-local/plugins/gcov/gcovr.html +22 -33
  191. data/site-local/plugins/gcov/index.html +6 -20
  192. data/site-local/plugins/gcov/overview.html +9 -20
  193. data/site-local/plugins/gcov/reportgenerator.html +9 -23
  194. data/site-local/plugins/gcov/reporting.html +6 -20
  195. data/site-local/plugins/gcov/setup.html +8 -21
  196. data/site-local/plugins/gcov/tool-versions.html +6 -20
  197. data/site-local/plugins/gcov/troubleshooting.html +10 -24
  198. data/site-local/plugins/index.html +6 -20
  199. data/site-local/plugins/module-generator.html +21 -35
  200. data/site-local/plugins/report-build-warnings-log.html +53 -67
  201. data/site-local/plugins/report-tests-gtestlike-stdout.html +6 -20
  202. data/site-local/plugins/report-tests-ide-stdout.html +43 -57
  203. data/site-local/plugins/report-tests-log-factory.html +50 -64
  204. data/site-local/plugins/report-tests-pretty-stdout.html +7 -21
  205. data/site-local/plugins/report-tests-raw-output-log.html +9 -21
  206. data/site-local/plugins/report-tests-teamcity-stdout.html +20 -31
  207. data/site-local/plugins/sanitize.html +56 -65
  208. data/site-local/plugins/valgrind.html +49 -58
  209. data/site-local/project/index.html +6 -20
  210. data/site-local/project/release-history.html +6 -20
  211. data/site-local/project/sbom.html +6 -20
  212. data/site-local/project/upgrade.html +9 -20
  213. data/site-local/reference/build-directives.html +6 -20
  214. data/site-local/reference/command-line.html +15 -22
  215. data/site-local/reference/environment-vars.html +6 -20
  216. data/site-local/reference/gcov-plugin.html +6 -20
  217. data/site-local/reference/global-collections.html +6 -20
  218. data/site-local/reference/index.html +6 -20
  219. data/site-local/reference/partials-macros.html +6 -20
  220. data/site-local/reference/project-configuration.html +6 -20
  221. data/site-local/sitemap.xml.gz +0 -0
  222. data/site-local/snapshot/examples/cipher_quest/index.html +16 -30
  223. data/site-local/snapshot/examples/temp_sensor/index.html +8 -22
  224. data/site-local/snapshot/examples/wondrous_forest/index.html +6 -20
  225. data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  226. data/site-local/snapshot/plugins/gcov/config/defaults_gcov.rb +1 -1
  227. data/site-local/testing-guide/build-directives.html +14 -28
  228. data/site-local/testing-guide/conventions.html +66 -27
  229. data/site-local/testing-guide/frameworks.html +11 -25
  230. data/site-local/testing-guide/index.html +6 -20
  231. data/site-local/testing-guide/partials/configuration.html +8 -22
  232. data/site-local/testing-guide/partials/conventions.html +8 -22
  233. data/site-local/testing-guide/partials/directives.html +16 -30
  234. data/site-local/testing-guide/partials/example.html +14 -28
  235. data/site-local/testing-guide/partials/index.html +6 -20
  236. data/site-local/testing-guide/partials/overview.html +6 -20
  237. data/site-local/testing-guide/partials/variables.html +11 -25
  238. data/site-local/testing-guide/test-cases.html +13 -27
  239. data/site-local/testing-guide/test-sample.html +12 -26
  240. data/site-local/testing-guide/test-suite-anatomy.html +6 -20
  241. data/spec/integration/actionator_file_operations_spec.rb +91 -1
  242. data/spec/integration/compile_commands_json_db_spec.rb +1 -1
  243. data/spec/integration/configurator_pipeline_spec.rb +10 -0
  244. data/spec/integration/configurator_validation_spec.rb +1 -1
  245. data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +26 -0
  246. data/spec/integration/dependencies/dependency_tracker_core_spec.rb +62 -0
  247. data/spec/integration/launcher_handoff_spec.rb +297 -0
  248. data/spec/integration/mixin_loading_spec.rb +1 -1
  249. data/spec/integration/module_generator_spec.rb +3 -3
  250. data/spec/integration/nested_test_artifacts_spec.rb +99 -0
  251. data/spec/integration/partials_module_resolution_spec.rb +7 -4
  252. data/spec/integration/path_intake_scenarios_spec.rb +101 -0
  253. data/spec/integration/path_scenarios_spec.rb +322 -0
  254. data/spec/integration/quote_include_isolator_spec.rb +1 -1
  255. data/spec/integration/rake_task_registry_plugins_spec.rb +95 -0
  256. data/spec/integration/report_build_warnings_log_spec.rb +1 -1
  257. data/spec/integration/report_tests_log_factory_spec.rb +1 -1
  258. data/spec/integration/test_executable_manifest_spec.rb +1 -1
  259. data/spec/integration/test_includes_extractinator_spec.rb +2 -1
  260. data/spec/integration/test_naming_spec.rb +198 -0
  261. data/spec/integration/test_source_file_checks_spec.rb +166 -0
  262. data/spec/integration/tool_validator_spec.rb +1 -1
  263. data/spec/integration/upgrade_docs_spec.rb +84 -0
  264. data/spec/integration/vendor_copy_transient_io_retry_spec.rb +192 -75
  265. data/spec/support/file_tree_helper.rb +88 -0
  266. data/spec/support/integration/configurator_integration_helper.rb +10 -7
  267. data/spec/support/integration/dependency_tracker_integration_helper.rb +1 -1
  268. data/spec/support/integration/partials_generation_integration_helper.rb +2 -2
  269. data/spec/support/integration/path_scenario_harness.rb +173 -0
  270. data/spec/support/integration/spec_integration_helper.rb +1 -1
  271. data/spec/support/integration/test_includes_harness.rb +13 -2
  272. data/spec/support/spec_helper.rb +2 -0
  273. data/spec/support/system/spec_system_helper.rb +7 -6
  274. data/spec/support/system/system_context.rb +21 -3
  275. data/spec/support/working_dir_tracking.rb +49 -0
  276. data/spec/system/build_output_mirroring_spec.rb +2 -2
  277. data/spec/system/conditional_mock_includes_spec.rb +1 -1
  278. data/spec/system/delta_builds_spec.rb +137 -11
  279. data/spec/system/gcov_deployment_spec.rb +1 -0
  280. data/spec/system/header_include_path_validation_spec.rb +4 -4
  281. data/spec/system/launcher_handoff_spec.rb +82 -0
  282. data/spec/system/mock_include_folders_spec.rb +91 -0
  283. data/spec/system/parent_directory_reference_spec.rb +5 -3
  284. data/spec/system/path_handling_probes_spec.rb +192 -0
  285. data/spec/system/preprocessing_parameterized_tests_spec.rb +1 -1
  286. data/spec/system/rake_release_task_path_disambiguation_spec.rb +6 -6
  287. data/spec/system/rake_test_task_path_disambiguation_spec.rb +85 -0
  288. data/spec/system/special_path_characters_spec.rb +86 -0
  289. data/spec/system/support/common_test_cases.rb +23 -21
  290. data/spec/system/support/gcov_common_test_cases.rb +37 -9
  291. data/spec/system/support/sanitize_common_test_cases.rb +2 -2
  292. data/spec/system/support/valgrind_common_test_cases.rb +12 -12
  293. data/spec/system/test_pipeline_stop_points_spec.rb +4 -4
  294. data/spec/system/test_runner_system_include_spec.rb +1 -1
  295. data/spec/system/test_source_file_directive_spec.rb +34 -5
  296. data/spec/units/bin/actionator_spec.rb +14 -17
  297. data/spec/units/bin/app_cfg_spec.rb +47 -0
  298. data/spec/units/bin/cli_handler_spec.rb +284 -7
  299. data/spec/units/bin/cli_helper_spec.rb +126 -45
  300. data/spec/units/bin/installation_selector_spec.rb +114 -0
  301. data/spec/units/bin/launchinator_spec.rb +171 -0
  302. data/spec/units/bin/path_validator_spec.rb +10 -0
  303. data/spec/units/bin/versionator_spec.rb +38 -6
  304. data/spec/units/build_log_writer_spec.rb +57 -0
  305. data/spec/units/config/build_root_policy_spec.rb +61 -0
  306. data/spec/units/config/configurator_builder_spec.rb +37 -6
  307. data/spec/units/config/configurator_paths_validator_spec.rb +292 -0
  308. data/spec/units/config/configurator_setup_spec.rb +65 -103
  309. data/spec/units/config/configurator_spec.rb +37 -6
  310. data/spec/units/config/configurator_validator_spec.rb +1 -172
  311. data/spec/units/default_tools_quoting_spec.rb +83 -0
  312. data/spec/units/dependencies/dependency_cache_store_spec.rb +33 -2
  313. data/spec/units/dependencies/dependency_debug_tree_spec.rb +1 -1
  314. data/spec/units/dependencies/dependency_hasher_spec.rb +42 -1
  315. data/spec/units/dependencies/dependency_path_normalizer_spec.rb +1 -1
  316. data/spec/units/dependencies/dependency_tracker_spec.rb +3 -1
  317. data/spec/units/filename_extension_spec.rb +11 -0
  318. data/spec/units/filesystem/build_subpath_spec.rb +122 -0
  319. data/spec/units/filesystem/destination_collision_spec.rb +30 -0
  320. data/spec/units/{file_finder_helper_spec.rb → filesystem/file_finder_helper_spec.rb} +46 -1
  321. data/spec/units/{file_finder_spec.rb → filesystem/file_finder_spec.rb} +188 -22
  322. data/spec/units/{file_path_collection_utils_spec.rb → filesystem/file_path_collection_utils_spec.rb} +181 -1
  323. data/spec/units/{file_path_utils_spec.rb → filesystem/file_path_utils_spec.rb} +204 -87
  324. data/spec/units/filesystem/file_system_wrapper_spec.rb +33 -0
  325. data/spec/units/filesystem/file_tree_spec.rb +511 -0
  326. data/spec/units/filesystem/file_tree_windows_spec.rb +78 -0
  327. data/spec/units/{file_wrapper_spec.rb → filesystem/file_wrapper_spec.rb} +154 -32
  328. data/spec/units/{path_matcher_spec.rb → filesystem/path_matcher_spec.rb} +12 -1
  329. data/spec/units/{path_mirror_spec.rb → filesystem/path_mirror_spec.rb} +32 -4
  330. data/spec/units/filesystem/project_paths_spec.rb +147 -0
  331. data/spec/units/filesystem/working_dir_spec.rb +71 -0
  332. data/spec/units/generators/generator_spec.rb +12 -6
  333. data/spec/units/generators/generator_test_results_backtrace_spec.rb +50 -46
  334. data/spec/units/generators/generator_test_results_spec.rb +1 -1
  335. data/spec/units/handoff_spec.rb +205 -0
  336. data/spec/units/includes/include_factory_spec.rb +3 -3
  337. data/spec/units/includes/include_pathinator_spec.rb +46 -0
  338. data/spec/units/installation_spec.rb +228 -0
  339. data/spec/units/library_resolver_spec.rb +157 -0
  340. data/spec/units/mock_locator_spec.rb +76 -1
  341. data/spec/units/partials/partializer_config_spec.rb +7 -0
  342. data/spec/units/partials/partializer_spec.rb +1 -0
  343. data/spec/units/partials_manager_spec.rb +17 -0
  344. data/spec/units/plugins/bullseye_spec.rb +15 -2
  345. data/spec/units/plugins/console_reportinator_spec.rb +18 -20
  346. data/spec/units/plugins/dependencies_spec.rb +33 -7
  347. data/spec/units/plugins/dependency_spec_spec.rb +17 -0
  348. data/spec/units/plugins/gcov_spec.rb +28 -3
  349. data/spec/units/plugins/gcovr_reportinator_spec.rb +19 -47
  350. data/spec/units/plugins/gcovr_thresholds_spec.rb +95 -0
  351. data/spec/units/plugins/module_generator_spec.rb +5 -5
  352. data/spec/units/plugins/report_build_warnings_log_spec.rb +3 -3
  353. data/spec/units/plugins/report_log_writer_plugin_spec.rb +10 -1
  354. data/spec/units/plugins/report_tests_raw_output_log_spec.rb +13 -2
  355. data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +77 -3
  356. data/spec/units/plugins/reportgenerator_reportinator_spec.rb +1 -1
  357. data/spec/units/plugins/sanitize_records_spec.rb +3 -1
  358. data/spec/units/plugins/sanitize_spec.rb +1 -1
  359. data/spec/units/plugins/valgrind_spec.rb +23 -8
  360. data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +1 -1
  361. data/spec/units/rake_app/rakefile_component_resolver_spec.rb +21 -0
  362. data/spec/units/rake_app/test_task_name_spec.rb +47 -0
  363. data/spec/units/release_build_executor_spec.rb +53 -14
  364. data/spec/units/release_build_planner_spec.rb +15 -3
  365. data/spec/units/reportinator_spec.rb +5 -5
  366. data/spec/units/standin_headerinator_spec.rb +31 -1
  367. data/spec/units/test_build_executor_spec.rb +107 -5
  368. data/spec/units/test_build_planner_spec.rb +104 -2
  369. data/spec/units/test_build_setup_spec.rb +96 -12
  370. data/spec/units/test_context_extractor_spec.rb +25 -0
  371. data/spec/units/test_file_preprocessinator_spec.rb +17 -1
  372. data/spec/units/test_includes_extractinator_spec.rb +5 -1
  373. data/spec/units/test_invoker/objects_wiring_spec.rb +6 -3
  374. data/spec/units/test_invoker_spec.rb +14 -1
  375. data/spec/units/test_source_file_directive_resolver_spec.rb +38 -7
  376. data/spec/units/tool_executor_spec.rb +26 -0
  377. data/spec/units/yaml_wrapper_spec.rb +11 -0
  378. metadata +122 -33
  379. data/lib/ceedling/file_path_collection_utils.rb +0 -164
  380. data/site-local/assets/stylesheets/main.ec1eaa64.min.css +0 -1
  381. data/site-local/assets/stylesheets/main.ec1eaa64.min.css.map +0 -1
  382. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css +0 -1
  383. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css.map +0 -1
@@ -42,7 +42,7 @@ describe Valgrind do
42
42
  let(:plugin_manager) { double('plugin_manager', register_build_failure: nil) }
43
43
  let(:plugin_reportinator) { double('plugin_reportinator') }
44
44
  let(:dependinator) { double('dependinator', register: nil) }
45
- let(:file_wrapper) { double('file_wrapper', exist?: true, read: '', mkdir: nil) }
45
+ let(:file_wrapper) { double('file_wrapper', exist_with_retry?: true, read: '', mkdir: nil) }
46
46
  let(:system_wrapper) { double('system_wrapper', windows?: false) }
47
47
  let(:ceedling) do
48
48
  {
@@ -207,13 +207,28 @@ describe Valgrind do
207
207
  end
208
208
 
209
209
  describe '#pre_test_fixture_register' do
210
- def register(project_config, context: VALGRIND_SYM)
210
+ before(:each) do
211
+ allow(file_wrapper).to receive(:mkdir_for) { |path| path }
212
+ end
213
+
214
+ def register(project_config, context: VALGRIND_SYM, test_name: 'test_thing')
211
215
  valgrind = build_valgrind(project_config)
212
- arg_hash = { context: context, test_name: 'test_thing', target: 'build/out/test_thing.out', tool: { name: 'original' } }
216
+ arg_hash = { context: context, test_name: test_name, target: 'build/out/test_thing.out', tool: { name: 'original' } }
213
217
  valgrind.pre_test_fixture_register(arg_hash)
214
218
  [valgrind, arg_hash]
215
219
  end
216
220
 
221
+ # GH #1364: Valgrind writes its reports but makes no directories of its own
222
+ it "makes the directories a nested test's reports go in" do
223
+ expect(file_wrapper).to receive(:mkdir_for).with('artifacts/valgrind/test/unit/test_thing.log')
224
+ expect(file_wrapper).to receive(:mkdir_for).with('artifacts/valgrind/test/unit/test_thing.xml')
225
+
226
+ _valgrind, arg_hash = register({ valgrind_xml_report: true }, test_name: 'test/unit/test_thing')
227
+
228
+ expect(arg_hash[:tool][:arguments]).to include('--log-file="artifacts/valgrind/test/unit/test_thing.log"')
229
+ expect(arg_hash[:tool][:arguments]).to include('--xml-file="artifacts/valgrind/test/unit/test_thing.xml"')
230
+ end
231
+
217
232
  it 'leaves a non-valgrind context untouched' do
218
233
  original = { name: 'original' }
219
234
  valgrind = build_valgrind({})
@@ -232,10 +247,10 @@ describe Valgrind do
232
247
  expect(arg_hash[:tool][:arguments]).to include('--log-file="artifacts/valgrind/test_thing.log"')
233
248
  end
234
249
 
235
- it 'appends the executable substitution token last' do
250
+ it 'appends the executable substitution token last, quoted as a path' do
236
251
  _valgrind, arg_hash = register({ valgrind_arguments: ['--leak-check=full'] })
237
252
 
238
- expect(arg_hash[:tool][:arguments].last).to eq('${1}')
253
+ expect(arg_hash[:tool][:arguments].last).to eq('"${1}"')
239
254
  end
240
255
 
241
256
  it 'places user arguments after the plugin-managed ones' do
@@ -315,7 +330,7 @@ describe Valgrind do
315
330
  end
316
331
 
317
332
  def explain(report, project_config: {}, context: VALGRIND_SYM, crash_notice: true, exists: true)
318
- wrapper = double('file_wrapper', exist?: exists, read: report)
333
+ wrapper = double('file_wrapper', exist_with_retry?: exists, read: report)
319
334
  valgrind = build_valgrind(project_config, file_wrapper: wrapper)
320
335
  arg_hash = { context: context, test_name: 'test_thing', crash_notice: crash_notice, explanation: nil }
321
336
  valgrind.explain_test_crash( arg_hash )
@@ -384,7 +399,7 @@ describe Valgrind do
384
399
 
385
400
  describe '#post_test_fixture_execute' do
386
401
  def execute(project_config, log_contents, exists: true, result_file: File.join('build', 'valgrind', 'results', 'test_thing.pass'))
387
- wrapper = double('file_wrapper', exist?: exists, read: log_contents)
402
+ wrapper = double('file_wrapper', exist_with_retry?: exists, read: log_contents)
388
403
  valgrind = build_valgrind(project_config, file_wrapper: wrapper)
389
404
  valgrind.post_test_fixture_execute(
390
405
  { context: VALGRIND_SYM, test_name: 'test_thing', result_file: result_file }
@@ -451,7 +466,7 @@ describe Valgrind do
451
466
 
452
467
  # A silent skip reads exactly like a clean result. It is not one.
453
468
  it 'warns and records nothing when no report was written' do
454
- expect(loginator).to receive(:log).with(/wrote no report for test_thing/, anything, anything)
469
+ expect(loginator).to receive(:log).with(/wrote no report for test_thing/, Verbosity::COMPLAIN)
455
470
 
456
471
  valgrind = execute({}, '', exists: false)
457
472
 
@@ -9,7 +9,7 @@ require 'spec_helper'
9
9
  require 'ceedling/preprocess/c_comment_scanner'
10
10
  require 'ceedling/preprocess/preprocessinator_comment_stripper'
11
11
  require 'ceedling/preprocess/preprocessinator_code_finder'
12
- require 'ceedling/file_wrapper'
12
+ require 'ceedling/filesystem/file_wrapper'
13
13
 
14
14
  RSpec.describe PreprocessinatorCommentStripper do
15
15
 
@@ -33,6 +33,18 @@ describe RakefileComponentResolver do
33
33
 
34
34
  expect(result).to eq(['ceedling/plugins'])
35
35
  end
36
+
37
+ # The path handling audit around GH #1370: bin/ reads :load_paths before the
38
+ # configuration pipeline, so it must expand and standardize them as that pipeline does
39
+ it 'expands and standardizes each configured load path, leaving the configuration as written' do
40
+ config = { plugins: { load_paths: ["\#{'my'}\\plugins\\", '~/plugins'] } }
41
+ expand = ->(path) { path.sub( "\#{'my'}", 'my' ) }
42
+
43
+ result = described_class.prepare_plugin_load_paths(config, 'ceedling/plugins', expand: expand)
44
+
45
+ expect(result).to eq(['my/plugins', File.join( Dir.home, 'plugins' ), 'ceedling/plugins'])
46
+ expect(config[:plugins][:load_paths].first).to eq( "\#{'my'}\\plugins\\" )
47
+ end
36
48
  end
37
49
 
38
50
  describe '.gather_rakefiles' do
@@ -125,6 +137,15 @@ describe RakefileComponentResolver do
125
137
  File.join('ceedling/plugins', 'gcov', 'gcov.rake'),
126
138
  ])
127
139
  end
140
+
141
+ it 'finds a plugin below a load path that needs expanding' do
142
+ config = { project: { release_build: false }, plugins: { enabled: ['mine'], load_paths: ["\#{'my'}/plugins"] } }
143
+ allow(File).to receive(:exist?).with(File.join('my/plugins', 'mine', 'mine.rake')).and_return(true)
144
+
145
+ result = described_class.resolve(config, 'lib', 'ceedling/plugins', expand: ->(path) { path.sub( "\#{'my'}", 'my' ) })
146
+
147
+ expect(result.last).to eq( File.join('my/plugins', 'mine', 'mine.rake') )
148
+ end
128
149
  end
129
150
 
130
151
  describe '.plugin_rake_files' do
@@ -0,0 +1,47 @@
1
+ # =========================================================================
2
+ # Ceedling - Test-Centered Build System for C
3
+ # ThrowTheSwitch.org
4
+ # Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ # SPDX-License-Identifier: MIT
6
+ # =========================================================================
7
+
8
+ require 'spec_helper'
9
+ require 'ceedling/rake_app/test_task_name'
10
+
11
+ # Every per-file test task (test:, gen:mocks:, gcov:, valgrind:, sanitize:, bullseye:) turns
12
+ # its task name into the test name file lookup needs. A directory ahead of the name
13
+ # distinguishes same-named tests, so only the basename is prefixed (GH #1362).
14
+ describe TestTaskName do
15
+ def name(task, root: 'gcov:')
16
+ TestTaskName.test_name( task, root: root, extensions: ['.c', '.cpp'], prefix: 'test_' )
17
+ end
18
+
19
+ it 'prefixes a bare name' do
20
+ expect( name( 'gcov:calculator.c' ) ).to eq( 'test_calculator' )
21
+ end
22
+
23
+ it 'leaves a name that already has the prefix' do
24
+ expect( name( 'gcov:test_calculator.c' ) ).to eq( 'test_calculator' )
25
+ end
26
+
27
+ it 'keeps a directory, prefixing only the file name' do
28
+ expect( name( 'gcov:test/calculator.c' ) ).to eq( 'test/test_calculator' )
29
+ expect( name( 'gcov:test/test_calculator.c' ) ).to eq( 'test/test_calculator' )
30
+ expect( name( 'gcov:test/unit/test_calculator.c' ) ).to eq( 'test/unit/test_calculator' )
31
+ end
32
+
33
+ it 'normalizes backslashes in a directory' do
34
+ expect( name( 'gcov:test\\unit\\calculator.c' ) ).to eq( 'test/unit/test_calculator' )
35
+ end
36
+
37
+ it 'strips any configured source extension, and leaves a name without one' do
38
+ expect( name( 'gcov:calculator.cpp' ) ).to eq( 'test_calculator' )
39
+ expect( name( 'gcov:calculator' ) ).to eq( 'test_calculator' )
40
+ end
41
+
42
+ it 'strips the given task root, whatever the task' do
43
+ expect( name( 'valgrind:test/calculator.c', root: 'valgrind:' ) ).to eq( 'test/test_calculator' )
44
+ expect( name( 'gen:mocks:test/calculator.c', root: 'gen:mocks:' ) ).to eq( 'test/test_calculator' )
45
+ expect( name( ' test:calculator.c ', root: 'test:' ) ).to eq( 'test_calculator' )
46
+ end
47
+ end
@@ -23,6 +23,7 @@ describe ReleaseBuildExecutor do
23
23
  @file_wrapper = double( "FileWrapper" )
24
24
  @file_path_utils = double( "FilePathUtils" )
25
25
  @dependinator = double( "Dependinator" )
26
+ @library_resolver = double( "LibraryResolver" )
26
27
 
27
28
  @tools_release_compiler = { name: 'fake compiler' }
28
29
  @tools_release_assembler = { name: 'fake assembler' }
@@ -56,6 +57,8 @@ describe ReleaseBuildExecutor do
56
57
  allow(@dependinator).to receive(:register_gcc_deps_file)
57
58
  allow(@dependinator).to receive(:stale?).and_return( true )
58
59
  allow(@dependinator).to receive(:mark_fresh)
60
+ allow(@library_resolver).to receive(:link_files).and_return( [] )
61
+ allow(@library_resolver).to receive(:search_path_arguments).and_return( [] )
59
62
 
60
63
  @executor = described_class.new(
61
64
  {
@@ -67,7 +70,8 @@ describe ReleaseBuildExecutor do
67
70
  :file_finder => @file_finder,
68
71
  :file_wrapper => @file_wrapper,
69
72
  :file_path_utils => @file_path_utils,
70
- :dependinator => @dependinator
73
+ :dependinator => @dependinator,
74
+ :library_resolver => @library_resolver
71
75
  }
72
76
  )
73
77
 
@@ -278,6 +282,18 @@ describe ReleaseBuildExecutor do
278
282
  @executor.link( @state )
279
283
  end
280
284
 
285
+ it "separates every configured library extension, and a subproject's, from plain objects" do
286
+ stub_const( "EXTENSION_LIBRARIES", FilenameExtension.new( ['.a', '.so'] ) )
287
+ stub_const( "EXTENSION_SUBPROJECTS", '.lib' )
288
+ @state.objects = ['build/release/out/foo.o', 'vendor/libbar.a', 'vendor/libbaz.so', 'sub/x.lib', 'build/release/out/so.o']
289
+
290
+ expect(@generator).to receive(:generate_executable_file) do |_tool, _sym, objects, *_rest|
291
+ expect(objects).to eq( ['build/release/out/foo.o', 'build/release/out/so.o'] )
292
+ end
293
+
294
+ @executor.link( @state )
295
+ end
296
+
281
297
  it "formats a separated library as a linker argument via the configured flag template" do
282
298
  stub_const( "EXTENSION_LIBRARIES", FilenameExtension.new('.a') )
283
299
  stub_const( "LIBRARIES_FLAG", '-l${1}' )
@@ -302,9 +318,8 @@ describe ReleaseBuildExecutor do
302
318
  @executor.link( @state )
303
319
  end
304
320
 
305
- it "formats configured library search paths as linker arguments via the configured flag template" do
306
- stub_const( "PATHS_LIBRARIES", ['vendor/lib'] )
307
- stub_const( "LIBRARIES_PATH_FLAG", '-L${1}' )
321
+ it "links with the library search path arguments the resolver gives" do
322
+ allow(@library_resolver).to receive(:search_path_arguments).and_return( ['-Lvendor/lib'] )
308
323
 
309
324
  expect(@generator).to receive(:generate_executable_file) do |_tool, _sym, _objects, _flags, _target, _map, _lib_args, lib_paths|
310
325
  expect(lib_paths).to eq( ['-Lvendor/lib'] )
@@ -313,14 +328,12 @@ describe ReleaseBuildExecutor do
313
328
  @executor.link( @state )
314
329
  end
315
330
 
316
- # Quoted like every other default path argument, so a path with a space survives the shell
317
- it "quotes each library search path under the default flag template" do
318
- stub_const( "PATHS_LIBRARIES", ['vendor/third party/lib'] )
319
- stub_const( "LIBRARIES_PATH_FLAG", DEFAULT_CEEDLING_PROJECT_CONFIG[:libraries][:path_flag] )
331
+ # A target named by an absolute :output may sit in a directory no build made
332
+ it "makes the target's directory before linking" do
333
+ allow(@configurator).to receive(:project_release_build_target).and_return( '/elsewhere/out/app.elf' )
320
334
 
321
- expect(@generator).to receive(:generate_executable_file) do |_tool, _sym, _objects, _flags, _target, _map, _lib_args, lib_paths|
322
- expect(lib_paths).to eq( ['-L "vendor/third party/lib"'] )
323
- end
335
+ expect(@file_wrapper).to receive(:mkdir).with( '/elsewhere/out' ).ordered
336
+ expect(@generator).to receive(:generate_executable_file).ordered
324
337
 
325
338
  @executor.link( @state )
326
339
  end
@@ -338,14 +351,40 @@ describe ReleaseBuildExecutor do
338
351
  it "registers the resolved link flags and library arguments, not just the object files, as meta" do
339
352
  stub_const( "LIBRARIES_SYSTEM", ['m'] )
340
353
  stub_const( "LIBRARIES_FLAG", '-l${1}' )
341
- stub_const( "PATHS_LIBRARIES", ['vendor/lib'] )
342
- stub_const( "LIBRARIES_PATH_FLAG", '-L${1}' )
354
+ allow(@library_resolver).to receive(:search_path_arguments).and_return( ['-Lvendor/lib'] )
343
355
  @state.link_flags = ['-Wall']
344
356
 
345
357
  expect(@dependinator).to receive(:register).with(
346
358
  'build/release/out/project.out',
347
359
  files: ['build/release/out/foo.o'],
348
- meta: { flags: ['-Wall'], lib_args: ['-lm'], lib_paths: ['-Lvendor/lib'], tools: [@tools_release_linker] }
360
+ meta: { flags: ['-Wall'], lib_args: ['-lm'], lib_paths: ['-Lvendor/lib'], tools: [@tools_release_linker], objects: ['build/release/out/foo.o'], libraries: [] }
361
+ )
362
+
363
+ @executor.link( @state )
364
+ end
365
+
366
+ # A source dropped from the build leaves every remaining object as it was, so only the
367
+ # object list, as meta, relinks an artifact that would otherwise keep the dropped code
368
+ it "registers the objects it links as meta" do
369
+ expect(@dependinator).to receive(:register).with(
370
+ 'build/release/out/project.out', files: ['build/release/out/foo.o'], meta: hash_including( objects: ['build/release/out/foo.o'] )
371
+ )
372
+
373
+ @executor.link( @state )
374
+ end
375
+
376
+ # GH #1368: a library rebuilt under the same name changed nothing a link registered
377
+ it "registers the library files its libraries resolve to, including those named by path, as files and as meta" do
378
+ @state.objects = ['build/release/out/foo.o', 'vendor/prebuilt/libp.a']
379
+ stub_const( 'EXTENSION_LIBRARIES', FilenameExtension.new( ['.a'] ) )
380
+ stub_const( 'LIBRARIES_SYSTEM', ['m'] )
381
+ stub_const( 'LIBRARIES_RELEASE', ['x'] )
382
+
383
+ expect(@library_resolver).to receive(:link_files).with( ['vendor/prebuilt/libp.a', 'm', 'x'] ).and_return( ['vendor/prebuilt/libp.a', 'vendor/lib/libx.a', 'build/deps/libfusion.a'] )
384
+ expect(@dependinator).to receive(:register).with(
385
+ 'build/release/out/project.out',
386
+ files: ['build/release/out/foo.o', 'vendor/prebuilt/libp.a', 'vendor/lib/libx.a', 'build/deps/libfusion.a'],
387
+ meta: hash_including( libraries: ['vendor/prebuilt/libp.a', 'vendor/lib/libx.a', 'build/deps/libfusion.a'] )
349
388
  )
350
389
 
351
390
  @executor.link( @state )
@@ -51,9 +51,21 @@ describe ReleaseBuildPlanner do
51
51
  end
52
52
 
53
53
  it "includes extra link-only objects alongside the compiled sources" do
54
- allow(@configurator).to receive(:collection_release_artifact_extra_link_objects).and_return( ['vendor/cexception/CException.o'] )
55
- expect(@file_path_utils).to receive(:form_release_build_objects_filelist).with( ['src/Foo.c', 'vendor/cexception/CException.o'] ).and_return( [] )
54
+ allow(@configurator).to receive(:collection_release_artifact_extra_link_objects).and_return( ['CException.o'] )
56
55
  @planner.plan( @state, files: nil )
56
+ expect( @state.objects ).to eq( ['build/release/out/Foo.o', 'build/release/out/CException.o'] )
57
+ end
58
+
59
+ # A link-only name is no source of its own, so naming the object a compiled source builds
60
+ # to is no collision between two sources
61
+ it "places link-only objects apart from the compiled sources, adding a shared object once" do
62
+ allow(@configurator).to receive(:collection_release_build_input).and_return( ['build/vendor/c_exception/lib/CException.c'] )
63
+ allow(@configurator).to receive(:collection_release_artifact_extra_link_objects).and_return( ['CException.o'] )
64
+ expect(@file_path_utils).to receive(:form_release_build_objects_filelist).with( ['build/vendor/c_exception/lib/CException.c'] ).and_return( ['build/release/out/CException.o'] )
65
+ expect(@file_path_utils).to receive(:form_release_build_objects_filelist).with( ['CException.o'] ).and_return( ['build/release/out/CException.o'] )
66
+
67
+ @planner.plan( @state, files: nil )
68
+ expect( @state.objects ).to eq( ['build/release/out/CException.o'] )
57
69
  end
58
70
 
59
71
  it "scopes the object list to just the given file when files is provided, ignoring the full source collection" do
@@ -124,7 +136,7 @@ describe ReleaseBuildPlanner do
124
136
 
125
137
  expect( compiler[:arguments] ).to include( '-fPIC' )
126
138
  expect( linker[:executable] ).to eq( 'ar' )
127
- expect( linker[:arguments] ).to eq( ['rcs', '${2}', '${1}'] )
139
+ expect( linker[:arguments] ).to eq( ['rcs', '"${2}"', '"${1}"'] )
128
140
  end
129
141
 
130
142
  it "does nothing when the project has configured its own compiler tool (not the Ceedling default)" do
@@ -225,14 +225,14 @@ describe Reportinator do
225
225
  expect(result).to eq("Compiling bar::baz.c...")
226
226
  end
227
227
 
228
- it 'omits module label when filename matches only the last segment of a mirrored, multi-segment module name' do
229
- result = @rp.generate_module_progress(module_name: 'adc/TestFoo', filename: 'TestFoo.c', operation: 'Compiling')
228
+ it 'omits module label when filename matches only the last segment of a multi-segment module name' do
229
+ result = @rp.generate_module_progress(module_name: 'test/adc/TestFoo', filename: 'TestFoo.c', operation: 'Compiling')
230
230
  expect(result).to eq("Compiling TestFoo.c...")
231
231
  end
232
232
 
233
- it 'prepends the full mirrored module name when filename differs from its last segment' do
234
- result = @rp.generate_module_progress(module_name: 'adc/TestFoo', filename: 'MockBar.c', operation: 'Generating mock for')
235
- expect(result).to eq("Generating mock for adc/TestFoo::MockBar.c...")
233
+ it 'prepends the full module name when filename differs from its last segment' do
234
+ result = @rp.generate_module_progress(module_name: 'test/adc/TestFoo', filename: 'MockBar.c', operation: 'Generating mock for')
235
+ expect(result).to eq("Generating mock for test/adc/TestFoo::MockBar.c...")
236
236
  end
237
237
  end
238
238
 
@@ -10,6 +10,7 @@ require 'ceedling/constants'
10
10
  require 'ceedling/includes/includes'
11
11
  require 'ceedling/test_invoker/test_invoker_types'
12
12
  require 'ceedling/test_invoker/standin_headerinator'
13
+ require 'ceedling/test_invoker/mock_locator'
13
14
 
14
15
  describe StandinHeaderinator do
15
16
  before(:each) do
@@ -33,6 +34,11 @@ describe StandinHeaderinator do
33
34
  end
34
35
  allow(@mock_locator).to receive(:header_collection).and_return( ['src/drivers/foo.h'] )
35
36
  allow(@mock_locator).to receive(:locate).and_return( ['src/drivers/foo.h', 'drivers'] )
37
+ allow(@mock_locator).to receive(:placement) do |mocks_root:, subdir:, **|
38
+ dir = subdir.empty? ? mocks_root : File.join( mocks_root, subdir )
39
+ MockLocator::MockPlacement.new( folder: nil, directory: dir, root: dir, reach: dir )
40
+ end
41
+ allow(@mock_locator).to receive(:search_directories) { |placement| [placement.directory] }
36
42
 
37
43
  @standins = described_class.new(
38
44
  configurator: @configurator, loginator: @loginator, reportinator: @reportinator,
@@ -110,9 +116,33 @@ describe StandinHeaderinator do
110
116
  expect(dirs).to eq( ['build/test/mocks/a_test/drivers'] )
111
117
  end
112
118
 
113
- it "gives no directories when the test has no mock root" do
119
+ # The test's #include reaches the stand-in only from the directory the folder climbs from, so it must exist
120
+ it "writes a climbing folder's stand-in where its mock will be, giving and making the directory it is reached from" do
121
+ climbing = MockLocator::MockPlacement.new( folder: '../x', directory: 'build/test/mocks/a_test/_up_/x', root: 'build/test/mocks/a_test/_up_/_up_', reach: 'build/test/mocks/a_test/_up_/_up_' )
122
+ allow(@mock_locator).to receive(:placement).with( mocks_root: 'build/test/mocks/a_test', subdir: 'drivers', include_path: '../x/MockFoo.h' ).and_return( climbing )
123
+ allow(@mock_locator).to receive(:search_directories).with( climbing ).and_return( [climbing.directory, climbing.root] )
124
+
125
+ expect(@file_wrapper).to receive(:mkdir).with( 'build/test/mocks/a_test/_up_/_up_' )
126
+ expect(@file_wrapper).to receive(:write).with( 'build/test/mocks/a_test/_up_/x/MockFoo.h', anything )
127
+
128
+ expect(@standins.place( @testable, [Include.new( '../x/MockFoo.h' )] ))
129
+ .to eq( ['build/test/mocks/a_test/_up_/x', 'build/test/mocks/a_test/_up_/_up_'] )
130
+ end
131
+
132
+ # The real mock opens with the header as CMock names it, by the folder CMock is given
133
+ it "includes the header by the folder its mock is named by" do
134
+ named = MockLocator::MockPlacement.new( folder: 'drivers', directory: 'build/test/mocks/a_test/drivers', root: 'build/test/mocks/a_test', reach: 'build/test/mocks/a_test' )
135
+ allow(@mock_locator).to receive(:placement).and_return( named )
136
+
137
+ expect(@file_wrapper).to receive(:write).with( 'build/test/mocks/a_test/drivers/MockFoo.h', "#{StandinHeaderinator::MARKER}\n#include \"drivers/foo.h\"\n" )
138
+
139
+ @standins.place( @testable, [Include.new( 'drivers/MockFoo.h' )] )
140
+ end
141
+
142
+ it "places no stand-in and gives no directories when the test has no mock root" do
114
143
  @testable.paths = {}
115
144
 
145
+ expect(@file_wrapper).to_not receive(:write)
116
146
  expect(@standins.place( @testable, [Include.new( 'MockFoo.h' )] )).to eq( [] )
117
147
  end
118
148
 
@@ -9,6 +9,7 @@ require 'spec_helper'
9
9
  require 'ceedling/filename_extension'
10
10
  require 'rake'
11
11
  require 'ceedling/test_invoker/test_build_executor'
12
+ require 'ceedling/test_invoker/mock_locator'
12
13
  require 'ceedling/test_invoker/test_invoker_types'
13
14
  require 'ceedling/partials/partials'
14
15
  require 'ceedling/test_context_extractor'
@@ -35,6 +36,7 @@ describe TestBuildExecutor do
35
36
  @gcc_dependency_parser = double( "GccDependencyParser" )
36
37
  @quote_include_isolator = double( "QuoteIncludeIsolator" )
37
38
  @generator_helper = double( "GeneratorHelper" )
39
+ @library_resolver = double( "LibraryResolver" )
38
40
 
39
41
  @tools_test_compiler = { name: 'fake compiler' }
40
42
  @tools_test_assembler = { name: 'fake assembler' }
@@ -60,6 +62,8 @@ describe TestBuildExecutor do
60
62
  # real Configurator would raise NoMethodError.
61
63
  allow(@configurator).to receive(:tools_test_fixture_simple_backtrace).and_return( @tools_test_fixture_simple_backtrace )
62
64
  allow(@configurator).to receive(:project_config_hash).and_return( { project_use_backtrace: :simple } )
65
+ allow(@configurator).to receive(:include_test_case).and_return( '' )
66
+ allow(@configurator).to receive(:exclude_test_case).and_return( '' )
63
67
  allow(@configurator).to receive(:test_build_preprocess_force_fallback).and_return( false )
64
68
  allow(@configurator).to receive(:project_use_mocks).and_return( false )
65
69
  allow(@configurator).to receive(:project_use_exceptions).and_return( false )
@@ -105,6 +109,8 @@ describe TestBuildExecutor do
105
109
  allow(@dependinator).to receive(:stale?).and_return( true )
106
110
  allow(@dependinator).to receive(:mark_fresh)
107
111
  allow(@test_source_file_directive_resolver).to receive(:validate!)
112
+ allow(@library_resolver).to receive(:link_files).and_return( [] )
113
+ allow(@library_resolver).to receive(:search_path_arguments).and_return( [] )
108
114
 
109
115
  @executor = described_class.new(
110
116
  {
@@ -121,7 +127,11 @@ describe TestBuildExecutor do
121
127
  :dependinator => @dependinator,
122
128
  :gcc_dependency_parser => @gcc_dependency_parser,
123
129
  :quote_include_isolator => @quote_include_isolator,
124
- :generator_helper => @generator_helper
130
+ :generator_helper => @generator_helper,
131
+ :library_resolver => @library_resolver,
132
+ :mock_locator => MockLocator.new(
133
+ configurator: @configurator, include_pathinator: double( 'include_pathinator' ), file_finder: @file_finder, file_path_utils: @file_path_utils
134
+ )
125
135
  }
126
136
  )
127
137
 
@@ -1057,12 +1067,42 @@ describe TestBuildExecutor do
1057
1067
  expect(@dependinator).to receive(:register).with(
1058
1068
  'build/a_test.out',
1059
1069
  files: ['build/foo.o'],
1060
- meta: { flags: [], lib_args: [], lib_paths: [], tools: [@tools_test_linker] }
1070
+ meta: { flags: [], lib_args: [], lib_paths: [], tools: [@tools_test_linker], objects: ['build/foo.o'], libraries: [] }
1071
+ )
1072
+
1073
+ @executor.stage_build_executables( @state )
1074
+ end
1075
+
1076
+ # GH #1368: a library rebuilt under the same name changed nothing a link registered
1077
+ it "registers the library files its libraries resolve to, as files and as meta" do
1078
+ allow(@dependinator).to receive(:stale?).and_return( false )
1079
+ allow(@configurator).to receive(:project_config_hash).and_return( { libraries_test: ['x'] } )
1080
+ stub_const( 'LIBRARIES_SYSTEM', ['m', 'fusion'] )
1081
+
1082
+ expect(@library_resolver).to receive(:link_files).with( ['x', 'm', 'fusion'] ).and_return( ['vendor/lib/libx.a', 'build/deps/libfusion.so.1'] )
1083
+ expect(@dependinator).to receive(:register).with(
1084
+ 'build/a_test.out',
1085
+ files: ['build/foo.o', 'vendor/lib/libx.a', 'build/deps/libfusion.so.1'],
1086
+ meta: hash_including( libraries: ['vendor/lib/libx.a', 'build/deps/libfusion.so.1'] )
1061
1087
  )
1062
1088
 
1063
1089
  @executor.stage_build_executables( @state )
1064
1090
  end
1065
1091
 
1092
+ # Staleness checks only the objects registered this build, so an object dropped from the
1093
+ # link changes nothing they see. The list itself, as meta, does change (a source deleted,
1094
+ # excluded, or moved out of the configured paths).
1095
+ it "registers the objects it links as meta, as a plain list" do
1096
+ allow(@dependinator).to receive(:stale?).and_return( false )
1097
+ @testable.objects = FileList.new.tap { |list| list << 'build/foo.o' }
1098
+
1099
+ expect(@dependinator).to receive(:register).with( 'build/a_test.out', files: ['build/foo.o'], meta: hash_including( objects: ['build/foo.o'] ) ) do |_, files:, meta:|
1100
+ expect(meta[:objects]).to be_an_instance_of( Array )
1101
+ end
1102
+
1103
+ @executor.stage_build_executables( @state )
1104
+ end
1105
+
1066
1106
  it "logs a summary line stating how many executables were recalled from cache" do
1067
1107
  allow(@dependinator).to receive(:stale?).and_return( false )
1068
1108
 
@@ -1339,7 +1379,9 @@ describe TestBuildExecutor do
1339
1379
  meta: {
1340
1380
  tools: [@tools_test_fixture],
1341
1381
  use_backtrace: :gdb,
1342
- backtrace_tools: [@tools_test_fixture_simple_backtrace, @tools_test_backtrace_gdb]
1382
+ backtrace_tools: [@tools_test_fixture_simple_backtrace, @tools_test_backtrace_gdb],
1383
+ include_test_case: '',
1384
+ exclude_test_case: ''
1343
1385
  }
1344
1386
  )
1345
1387
 
@@ -1363,13 +1405,32 @@ describe TestBuildExecutor do
1363
1405
  meta: {
1364
1406
  tools: [@tools_test_fixture],
1365
1407
  use_backtrace: :simple,
1366
- backtrace_tools: [@tools_test_fixture_simple_backtrace]
1408
+ backtrace_tools: [@tools_test_fixture_simple_backtrace],
1409
+ include_test_case: '',
1410
+ exclude_test_case: ''
1367
1411
  }
1368
1412
  )
1369
1413
 
1370
1414
  @executor.stage_execute( @state )
1371
1415
  end
1372
1416
 
1417
+ # An executable linked with command line arguments enabled is the same with or without
1418
+ # a filter, so only the filter tells one run's results from another's (GH #1360)
1419
+ it "registers the command line test case filters as meta" do
1420
+ @testable.executable_rebuilt = false
1421
+ allow(@generator).to receive(:generate_test_results)
1422
+ allow(@configurator).to receive(:include_test_case).and_return( 'test_one' )
1423
+ allow(@configurator).to receive(:exclude_test_case).and_return( 'test_two' )
1424
+
1425
+ expect(@dependinator).to receive(:register).with(
1426
+ @fixture_target,
1427
+ files: ['build/a_test.out'],
1428
+ meta: hash_including( include_test_case: 'test_one', exclude_test_case: 'test_two' )
1429
+ )
1430
+
1431
+ @executor.stage_execute( @state )
1432
+ end
1433
+
1373
1434
  it "reruns the test fixture when only the :tools ↳ :test_fixture configuration changed, even though the executable is unchanged" do
1374
1435
  @testable.executable_rebuilt = false
1375
1436
  allow(@dependinator).to receive(:stale?).with(@fixture_target).and_return( true )
@@ -1635,7 +1696,7 @@ describe TestBuildExecutor do
1635
1696
  include_as( 'sub/MockFoo.h' )
1636
1697
 
1637
1698
  expect(@generator).to receive(:generate_mock)
1638
- .with( hash_including( output_path: 'build/test/mocks/sub', folder: 'sub' ) )
1699
+ .with( hash_including( output_path: 'build/test/mocks/sub', mock_root: 'build/test/mocks', folder: 'sub' ) )
1639
1700
 
1640
1701
  @executor.stage_generate_mocks( @state )
1641
1702
  end
@@ -1662,6 +1723,30 @@ describe TestBuildExecutor do
1662
1723
  @executor.stage_generate_mocks( @state )
1663
1724
  end
1664
1725
 
1726
+ # The path handling audit around GH #1370: a folder that climbs must not carry the
1727
+ # mock out of its test's mocks directory
1728
+ it "G14: keeps the mock below its test's mocks directory for a folder that climbs" do
1729
+ include_as( '../x/MockFoo.h' )
1730
+
1731
+ expect(@generator).to receive(:generate_mock) do |args|
1732
+ expect(args[:output_path].split( '/' )).to_not include( '..' )
1733
+ end
1734
+
1735
+ @executor.stage_generate_mocks( @state )
1736
+ end
1737
+
1738
+ # The compiler finds the mock as written only through CMock's root, so it must exist
1739
+ it "roots CMock as deep as a climbing folder climbs, and makes that root" do
1740
+ include_as( '../x/MockFoo.h' )
1741
+
1742
+ expect(@file_wrapper).to receive(:mkdir).with( 'build/test/mocks/_up_/x' )
1743
+ expect(@file_wrapper).to receive(:mkdir).with( 'build/test/mocks/_up_/_up_' )
1744
+ expect(@generator).to receive(:generate_mock)
1745
+ .with( hash_including( output_path: 'build/test/mocks/_up_/x', mock_root: 'build/test/mocks/_up_/_up_', folder: '../x' ) )
1746
+
1747
+ @executor.stage_generate_mocks( @state )
1748
+ end
1749
+
1665
1750
  it "passes no folder when :mock_name_include_folder is disabled" do
1666
1751
  allow(@configurator).to receive(:cmock_mock_name_include_folder).and_return( false )
1667
1752
  include_as( 'sub/MockFoo.h' )
@@ -1756,4 +1841,21 @@ describe TestBuildExecutor do
1756
1841
  end
1757
1842
  end
1758
1843
 
1844
+
1845
+ context "#fixture_meta" do
1846
+ def meta(include: '', exclude: '')
1847
+ allow(@configurator).to receive(:include_test_case).and_return( include )
1848
+ allow(@configurator).to receive(:exclude_test_case).and_return( exclude )
1849
+ @executor.fixture_meta( fixture_tool: @tools_test_fixture, use_backtrace: :simple, backtrace_tools: [] )
1850
+ end
1851
+
1852
+ it "differs when the test case filters differ" do
1853
+ expect( meta( include: 'test_one' ) ).not_to eq( meta( include: 'test_two' ) )
1854
+ expect( meta( exclude: 'test_one' ) ).not_to eq( meta )
1855
+ end
1856
+
1857
+ it "is the same for an unset filter, whether nil or empty" do
1858
+ expect( meta( include: nil, exclude: nil ) ).to eq( meta( include: '', exclude: '' ) )
1859
+ end
1860
+ end
1759
1861
  end