ceedling 1.2.1 → 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 (276) hide show
  1. checksums.yaml +4 -4
  2. data/GIT_COMMIT_SHA +1 -1
  3. data/README.md +11 -9
  4. data/Rakefile +2 -1
  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 +14 -1
  10. data/bin/ceedling +13 -3
  11. data/bin/cli.rb +25 -6
  12. data/bin/cli_handler.rb +113 -73
  13. data/bin/cli_helper.rb +51 -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 +74 -3
  23. data/docs/KnownIssues.md +90 -4
  24. data/docs/ReleaseNotes.md +13 -0
  25. data/lib/ceedling/build_log_writer.rb +33 -0
  26. data/lib/ceedling/config/build_root_policy.rb +70 -0
  27. data/lib/ceedling/config/configurator.rb +14 -16
  28. data/lib/ceedling/config/configurator_builder.rb +58 -28
  29. data/lib/ceedling/config/configurator_paths_validator.rb +179 -0
  30. data/lib/ceedling/config/configurator_plugins.rb +1 -1
  31. data/lib/ceedling/config/configurator_setup.rb +15 -28
  32. data/lib/ceedling/config/configurator_validator.rb +1 -110
  33. data/lib/ceedling/defaults.rb +4 -4
  34. data/lib/ceedling/dependencies/README.md +18 -16
  35. data/lib/ceedling/dependencies/dependency_cache_store.rb +20 -3
  36. data/lib/ceedling/dependencies/dependency_hasher.rb +35 -1
  37. data/lib/ceedling/filename_extension.rb +7 -1
  38. data/lib/ceedling/filesystem/FILE_TREE.md +253 -0
  39. data/lib/ceedling/filesystem/PATH_HANDLING.md +304 -0
  40. data/lib/ceedling/filesystem/README.md +41 -0
  41. data/lib/ceedling/filesystem/build_subpath.rb +102 -0
  42. data/lib/ceedling/filesystem/destination_collision.rb +25 -0
  43. data/lib/ceedling/{file_finder.rb → filesystem/file_finder.rb} +159 -104
  44. data/lib/ceedling/{file_finder_helper.rb → filesystem/file_finder_helper.rb} +36 -31
  45. data/lib/ceedling/filesystem/file_path_collection_utils.rb +183 -0
  46. data/lib/ceedling/{file_path_utils.rb → filesystem/file_path_utils.rb} +108 -97
  47. data/lib/ceedling/{file_system_wrapper.rb → filesystem/file_system_wrapper.rb} +6 -5
  48. data/lib/ceedling/filesystem/file_tree.rb +241 -0
  49. data/lib/ceedling/{file_wrapper.rb → filesystem/file_wrapper.rb} +45 -38
  50. data/lib/ceedling/filesystem/path_exclusions.rb +30 -0
  51. data/lib/ceedling/{path_matcher.rb → filesystem/path_matcher.rb} +27 -23
  52. data/lib/ceedling/{path_mirror.rb → filesystem/path_mirror.rb} +19 -18
  53. data/lib/ceedling/filesystem/path_spellings.rb +55 -0
  54. data/lib/ceedling/filesystem/project_paths.rb +184 -0
  55. data/lib/ceedling/filesystem/working_dir.rb +40 -0
  56. data/lib/ceedling/generators/generator.rb +5 -6
  57. data/lib/ceedling/generators/generator_partials.rb +1 -1
  58. data/lib/ceedling/generators/generator_test_results_backtrace.rb +7 -7
  59. data/lib/ceedling/handoff.rb +121 -0
  60. data/lib/ceedling/includes/include_factory.rb +3 -3
  61. data/lib/ceedling/includes/include_pathinator.rb +67 -10
  62. data/lib/ceedling/includes/includes.rb +1 -1
  63. data/lib/ceedling/installation.rb +92 -0
  64. data/lib/ceedling/library_resolver.rb +99 -0
  65. data/lib/ceedling/objects.yml +23 -2
  66. data/lib/ceedling/partials/partializer.rb +4 -4
  67. data/lib/ceedling/partials/partializer_config.rb +3 -1
  68. data/lib/ceedling/plugins/report_log_writer_plugin.rb +3 -5
  69. data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +1 -1
  70. data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +1 -1
  71. data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +1 -1
  72. data/lib/ceedling/rake_app/rakefile_component_resolver.rb +10 -17
  73. data/lib/ceedling/rakefile.rb +15 -1
  74. data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
  75. data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
  76. data/lib/ceedling/release_invoker/release_build_executor.rb +33 -44
  77. data/lib/ceedling/release_invoker/release_build_planner.rb +14 -6
  78. data/lib/ceedling/reportinator.rb +3 -4
  79. data/lib/ceedling/setupinator.rb +94 -90
  80. data/lib/ceedling/test_context_extractor.rb +5 -1
  81. data/lib/ceedling/test_invoker/PIPELINE.md +9 -7
  82. data/lib/ceedling/test_invoker/mock_locator.rb +60 -2
  83. data/lib/ceedling/test_invoker/partials_manager.rb +12 -0
  84. data/lib/ceedling/test_invoker/standin_headerinator.rb +22 -13
  85. data/lib/ceedling/test_invoker/test_build_executor.rb +24 -40
  86. data/lib/ceedling/test_invoker/test_build_planner.rb +37 -18
  87. data/lib/ceedling/test_invoker/test_build_setup.rb +17 -12
  88. data/lib/ceedling/test_invoker/test_build_validations.rb +16 -31
  89. data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +1 -1
  90. data/lib/ceedling/test_invoker/test_invoker.rb +6 -1
  91. data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +1 -1
  92. data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +40 -20
  93. data/lib/ceedling/tool_executor.rb +9 -3
  94. data/lib/ceedling/yaml_wrapper.rb +3 -2
  95. data/lib/version.rb +1 -1
  96. data/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  97. data/plugins/bullseye/lib/bullseye.rb +9 -7
  98. data/plugins/cppcheck/config/defaults_cppcheck.rb +1 -1
  99. data/plugins/dependencies/config/defaults.yml +6 -6
  100. data/plugins/dependencies/dependencies.rake +4 -1
  101. data/plugins/dependencies/lib/dependencies.rb +18 -8
  102. data/plugins/dependencies/lib/dependency_spec.rb +17 -5
  103. data/plugins/fff/lib/fff.rb +45 -39
  104. data/plugins/fff/spec/fff_cmock_wrapper_spec.rb +128 -0
  105. data/plugins/gcov/config/defaults_gcov.rb +1 -1
  106. data/plugins/gcov/lib/console_reportinator.rb +4 -18
  107. data/plugins/gcov/lib/gcov.rb +9 -2
  108. data/plugins/gcov/lib/gcovr_reportinator.rb +8 -40
  109. data/plugins/gcov/lib/gcovr_thresholds.rb +74 -0
  110. data/plugins/gcov/lib/reportgenerator_reportinator.rb +1 -1
  111. data/plugins/module_generator/lib/module_generator.rb +3 -3
  112. data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +53 -80
  113. data/plugins/sanitize/lib/sanitize_records.rb +3 -6
  114. data/plugins/valgrind/lib/valgrind.rb +14 -7
  115. data/site-local/configuration/reference/cmock.html +2 -1
  116. data/site-local/configuration/reference/files.html +9 -3
  117. data/site-local/configuration/reference/libraries.html +21 -3
  118. data/site-local/configuration/reference/paths.html +29 -6
  119. data/site-local/configuration/reference/project.html +17 -7
  120. data/site-local/configuration/reference/release-build.html +2 -0
  121. data/site-local/configuration/reference/tools.html +9 -0
  122. data/site-local/configuration/which-ceedling.html +377 -17
  123. data/site-local/development/releases.html +5 -1
  124. data/site-local/development/workflow.html +48 -43
  125. data/site-local/getting-started/builds.html +2 -0
  126. data/site-local/getting-started/command-line.html +56 -4
  127. data/site-local/plugins/dependencies.html +6 -3
  128. data/site-local/plugins/fff.html +42 -11
  129. data/site-local/plugins/gcov/gcovr.html +15 -12
  130. data/site-local/plugins/gcov/setup.html +2 -1
  131. data/site-local/plugins/report-tests-raw-output-log.html +3 -1
  132. data/site-local/plugins/report-tests-teamcity-stdout.html +6 -3
  133. data/site-local/plugins/sanitize.html +7 -6
  134. data/site-local/plugins/valgrind.html +8 -7
  135. data/site-local/project/upgrade.html +3 -0
  136. data/site-local/reference/command-line.html +9 -2
  137. data/site-local/sitemap.xml.gz +0 -0
  138. data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  139. data/site-local/snapshot/plugins/gcov/config/defaults_gcov.rb +1 -1
  140. data/site-local/testing-guide/conventions.html +53 -0
  141. data/spec/integration/actionator_file_operations_spec.rb +91 -1
  142. data/spec/integration/compile_commands_json_db_spec.rb +1 -1
  143. data/spec/integration/configurator_validation_spec.rb +1 -1
  144. data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +26 -0
  145. data/spec/integration/dependencies/dependency_tracker_core_spec.rb +22 -0
  146. data/spec/integration/launcher_handoff_spec.rb +297 -0
  147. data/spec/integration/mixin_loading_spec.rb +1 -1
  148. data/spec/integration/module_generator_spec.rb +3 -3
  149. data/spec/integration/nested_test_artifacts_spec.rb +99 -0
  150. data/spec/integration/partials_module_resolution_spec.rb +7 -4
  151. data/spec/integration/path_intake_scenarios_spec.rb +101 -0
  152. data/spec/integration/path_scenarios_spec.rb +322 -0
  153. data/spec/integration/quote_include_isolator_spec.rb +1 -1
  154. data/spec/integration/report_build_warnings_log_spec.rb +1 -1
  155. data/spec/integration/report_tests_log_factory_spec.rb +1 -1
  156. data/spec/integration/test_executable_manifest_spec.rb +1 -1
  157. data/spec/integration/test_includes_extractinator_spec.rb +2 -1
  158. data/spec/integration/test_naming_spec.rb +198 -0
  159. data/spec/integration/test_source_file_checks_spec.rb +166 -0
  160. data/spec/integration/tool_validator_spec.rb +1 -1
  161. data/spec/integration/upgrade_docs_spec.rb +84 -0
  162. data/spec/integration/vendor_copy_transient_io_retry_spec.rb +74 -5
  163. data/spec/support/file_tree_helper.rb +88 -0
  164. data/spec/support/integration/configurator_integration_helper.rb +6 -6
  165. data/spec/support/integration/dependency_tracker_integration_helper.rb +1 -1
  166. data/spec/support/integration/partials_generation_integration_helper.rb +2 -2
  167. data/spec/support/integration/path_scenario_harness.rb +173 -0
  168. data/spec/support/integration/spec_integration_helper.rb +1 -1
  169. data/spec/support/integration/test_includes_harness.rb +13 -2
  170. data/spec/support/spec_helper.rb +2 -0
  171. data/spec/support/system/spec_system_helper.rb +7 -6
  172. data/spec/support/system/system_context.rb +21 -3
  173. data/spec/support/working_dir_tracking.rb +49 -0
  174. data/spec/system/build_output_mirroring_spec.rb +2 -2
  175. data/spec/system/conditional_mock_includes_spec.rb +1 -1
  176. data/spec/system/delta_builds_spec.rb +137 -11
  177. data/spec/system/gcov_deployment_spec.rb +1 -0
  178. data/spec/system/header_include_path_validation_spec.rb +4 -4
  179. data/spec/system/launcher_handoff_spec.rb +82 -0
  180. data/spec/system/mock_include_folders_spec.rb +91 -0
  181. data/spec/system/parent_directory_reference_spec.rb +5 -3
  182. data/spec/system/path_handling_probes_spec.rb +192 -0
  183. data/spec/system/preprocessing_parameterized_tests_spec.rb +1 -1
  184. data/spec/system/rake_release_task_path_disambiguation_spec.rb +6 -6
  185. data/spec/system/rake_test_task_path_disambiguation_spec.rb +85 -0
  186. data/spec/system/special_path_characters_spec.rb +86 -0
  187. data/spec/system/support/common_test_cases.rb +23 -21
  188. data/spec/system/support/gcov_common_test_cases.rb +37 -9
  189. data/spec/system/support/sanitize_common_test_cases.rb +2 -2
  190. data/spec/system/support/valgrind_common_test_cases.rb +12 -12
  191. data/spec/system/test_pipeline_stop_points_spec.rb +4 -4
  192. data/spec/system/test_runner_system_include_spec.rb +1 -1
  193. data/spec/system/test_source_file_directive_spec.rb +34 -5
  194. data/spec/units/bin/actionator_spec.rb +14 -17
  195. data/spec/units/bin/app_cfg_spec.rb +37 -0
  196. data/spec/units/bin/cli_handler_spec.rb +282 -6
  197. data/spec/units/bin/cli_helper_spec.rb +116 -45
  198. data/spec/units/bin/installation_selector_spec.rb +114 -0
  199. data/spec/units/bin/launchinator_spec.rb +171 -0
  200. data/spec/units/bin/path_validator_spec.rb +10 -0
  201. data/spec/units/bin/versionator_spec.rb +38 -6
  202. data/spec/units/build_log_writer_spec.rb +57 -0
  203. data/spec/units/config/build_root_policy_spec.rb +61 -0
  204. data/spec/units/config/configurator_builder_spec.rb +37 -6
  205. data/spec/units/config/configurator_paths_validator_spec.rb +292 -0
  206. data/spec/units/config/configurator_setup_spec.rb +9 -65
  207. data/spec/units/config/configurator_spec.rb +27 -5
  208. data/spec/units/config/configurator_validator_spec.rb +1 -172
  209. data/spec/units/default_tools_quoting_spec.rb +83 -0
  210. data/spec/units/dependencies/dependency_cache_store_spec.rb +33 -2
  211. data/spec/units/dependencies/dependency_debug_tree_spec.rb +1 -1
  212. data/spec/units/dependencies/dependency_hasher_spec.rb +42 -1
  213. data/spec/units/dependencies/dependency_path_normalizer_spec.rb +1 -1
  214. data/spec/units/dependencies/dependency_tracker_spec.rb +3 -1
  215. data/spec/units/filename_extension_spec.rb +11 -0
  216. data/spec/units/filesystem/build_subpath_spec.rb +122 -0
  217. data/spec/units/filesystem/destination_collision_spec.rb +30 -0
  218. data/spec/units/{file_finder_helper_spec.rb → filesystem/file_finder_helper_spec.rb} +46 -1
  219. data/spec/units/{file_finder_spec.rb → filesystem/file_finder_spec.rb} +188 -22
  220. data/spec/units/{file_path_collection_utils_spec.rb → filesystem/file_path_collection_utils_spec.rb} +181 -1
  221. data/spec/units/{file_path_utils_spec.rb → filesystem/file_path_utils_spec.rb} +204 -87
  222. data/spec/units/filesystem/file_system_wrapper_spec.rb +33 -0
  223. data/spec/units/filesystem/file_tree_spec.rb +511 -0
  224. data/spec/units/filesystem/file_tree_windows_spec.rb +78 -0
  225. data/spec/units/{file_wrapper_spec.rb → filesystem/file_wrapper_spec.rb} +95 -12
  226. data/spec/units/{path_matcher_spec.rb → filesystem/path_matcher_spec.rb} +12 -1
  227. data/spec/units/{path_mirror_spec.rb → filesystem/path_mirror_spec.rb} +32 -4
  228. data/spec/units/filesystem/project_paths_spec.rb +147 -0
  229. data/spec/units/filesystem/working_dir_spec.rb +71 -0
  230. data/spec/units/generators/generator_spec.rb +12 -6
  231. data/spec/units/generators/generator_test_results_backtrace_spec.rb +50 -46
  232. data/spec/units/generators/generator_test_results_spec.rb +1 -1
  233. data/spec/units/handoff_spec.rb +205 -0
  234. data/spec/units/includes/include_factory_spec.rb +3 -3
  235. data/spec/units/includes/include_pathinator_spec.rb +46 -0
  236. data/spec/units/installation_spec.rb +228 -0
  237. data/spec/units/library_resolver_spec.rb +157 -0
  238. data/spec/units/mock_locator_spec.rb +76 -1
  239. data/spec/units/partials/partializer_config_spec.rb +7 -0
  240. data/spec/units/partials/partializer_spec.rb +1 -0
  241. data/spec/units/partials_manager_spec.rb +17 -0
  242. data/spec/units/plugins/bullseye_spec.rb +15 -2
  243. data/spec/units/plugins/console_reportinator_spec.rb +18 -20
  244. data/spec/units/plugins/dependencies_spec.rb +33 -7
  245. data/spec/units/plugins/dependency_spec_spec.rb +17 -0
  246. data/spec/units/plugins/gcov_spec.rb +28 -3
  247. data/spec/units/plugins/gcovr_reportinator_spec.rb +19 -47
  248. data/spec/units/plugins/gcovr_thresholds_spec.rb +95 -0
  249. data/spec/units/plugins/module_generator_spec.rb +5 -5
  250. data/spec/units/plugins/report_build_warnings_log_spec.rb +3 -3
  251. data/spec/units/plugins/report_log_writer_plugin_spec.rb +10 -1
  252. data/spec/units/plugins/report_tests_raw_output_log_spec.rb +13 -2
  253. data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +77 -3
  254. data/spec/units/plugins/reportgenerator_reportinator_spec.rb +1 -1
  255. data/spec/units/plugins/sanitize_records_spec.rb +3 -1
  256. data/spec/units/plugins/sanitize_spec.rb +1 -1
  257. data/spec/units/plugins/valgrind_spec.rb +23 -8
  258. data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +1 -1
  259. data/spec/units/rake_app/rakefile_component_resolver_spec.rb +21 -0
  260. data/spec/units/release_build_executor_spec.rb +53 -14
  261. data/spec/units/release_build_planner_spec.rb +15 -3
  262. data/spec/units/reportinator_spec.rb +5 -5
  263. data/spec/units/standin_headerinator_spec.rb +31 -1
  264. data/spec/units/test_build_executor_spec.rb +65 -3
  265. data/spec/units/test_build_planner_spec.rb +104 -2
  266. data/spec/units/test_build_setup_spec.rb +96 -12
  267. data/spec/units/test_context_extractor_spec.rb +25 -0
  268. data/spec/units/test_file_preprocessinator_spec.rb +17 -1
  269. data/spec/units/test_includes_extractinator_spec.rb +5 -1
  270. data/spec/units/test_invoker/objects_wiring_spec.rb +6 -3
  271. data/spec/units/test_invoker_spec.rb +14 -1
  272. data/spec/units/test_source_file_directive_resolver_spec.rb +38 -7
  273. data/spec/units/tool_executor_spec.rb +26 -0
  274. data/spec/units/yaml_wrapper_spec.rb +11 -0
  275. metadata +109 -25
  276. data/lib/ceedling/file_path_collection_utils.rb +0 -164
@@ -86,8 +86,8 @@ ceedling_system_tests do
86
86
  # A mock's location mirrors its real header's resolved path, not whatever path its
87
87
  # own #include happened to write, so both tests' mocks land at the identical
88
88
  # location -- each #include names the same real header, drivers/foo.h.
89
- expect(File.exist?('build/test/mocks/test_bare_mock/drivers/mock_foo.h')).to be true
90
- expect(File.exist?('build/test/mocks/test_pathed_mock/drivers/mock_foo.h')).to be true
89
+ expect(File.exist?('build/test/mocks/test/test_bare_mock/drivers/mock_foo.h')).to be true
90
+ expect(File.exist?('build/test/mocks/test/test_pathed_mock/drivers/mock_foo.h')).to be true
91
91
  end
92
92
  end
93
93
 
@@ -159,7 +159,7 @@ ceedling_system_tests do
159
159
 
160
160
  # alt_drivers sorts ahead of drivers within :include's single src/** glob,
161
161
  # so the generated mock mirrors alt_drivers/foo.h's own location.
162
- expect(File.exist?('build/test/mocks/test_ambiguous_mock/alt_drivers/mock_foo.h')).to be true
162
+ expect(File.exist?('build/test/mocks/test/test_ambiguous_mock/alt_drivers/mock_foo.h')).to be true
163
163
  end
164
164
  end
165
165
 
@@ -172,7 +172,7 @@ ceedling_system_tests do
172
172
  expect(output).to match(/TESTED:\s+1/)
173
173
  expect(output).to match(/PASSED:\s+1/)
174
174
 
175
- expect(File.exist?('build/test/mocks/test_pathed_mock_ambiguous/drivers/mock_foo.h')).to be true
175
+ expect(File.exist?('build/test/mocks/test/test_pathed_mock_ambiguous/drivers/mock_foo.h')).to be true
176
176
  end
177
177
  end
178
178
 
@@ -0,0 +1,82 @@
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_system_helper'
9
+
10
+ ##
11
+ ## Launcher Hand-off
12
+ ## =================
13
+ ##
14
+ ## GH #1365: a launcher selecting another installation ran that installation's
15
+ ## application inside its own process. The gem's launcher now hands a `--local`
16
+ ## project's build to the vendored copy's own launcher, in its own process.
17
+ ##
18
+ ## spec/integration/launcher_handoff_spec.rb covers every command short of a build.
19
+ ## These run a real build through a hand-off, on every platform, where Windows
20
+ ## emulates the process replacement and must still carry the build's exit status.
21
+ ##
22
+
23
+ ceedling_system_tests do
24
+ before :all do
25
+ @c = SystemContext.new
26
+ @c.deploy_gem
27
+ end
28
+
29
+ after :all do
30
+ @c.done!
31
+ end
32
+
33
+ before { @proj_name = unique_proj_name("handoff") }
34
+
35
+ # A vendored copy reporting its own version, a test file with one failing test, and
36
+ # the Windows executable extension the build expects
37
+ def prepare_vendored_project
38
+ version_rb = File.join( 'vendor', 'ceedling', 'lib', 'version.rb' )
39
+ File.write( version_rb, File.read( version_rb ).sub( /BASE = '[^']+'/, "BASE = '9.9.9'" ) )
40
+
41
+ FileUtils.cp test_asset_path("example_file.h"), 'src/'
42
+ FileUtils.cp test_asset_path("example_file.c"), 'src/'
43
+ FileUtils.cp test_asset_path("test_example_file.c"), 'test/'
44
+
45
+ @c.remove_project_yml_option_for_test( :extension, :executable ) if /mingw|win32/.match?( RUBY_PLATFORM.downcase )
46
+ end
47
+
48
+ def expect_build_in_vendored_copy(output)
49
+ expect(@c.last_exit_status).to eq(1), output
50
+ expect(output).to match(/is handing off to Ceedling 9\.9\.9\S* at /)
51
+ expect(output).to match(/Ceedling 9\.9\.9\S* at .+ is now running, launched from Ceedling /)
52
+ expect(output).to match(/TESTED:\s+2/)
53
+ expect(output).to match(/PASSED:\s+1/)
54
+ expect(output).to match(/FAILED:\s+1/)
55
+ end
56
+
57
+ describe "A `--local` project run by the gem" do
58
+ before { @c.with_context { @c.ceedling_appcmd_exec("new --local #{@proj_name}") } }
59
+
60
+ it "builds in the vendored copy its :which_ceedling selects and exits with the build's status" do
61
+ @c.with_context do
62
+ Dir.chdir @proj_name do
63
+ prepare_vendored_project()
64
+
65
+ expect_build_in_vendored_copy( @c.ceedling_build_exec("test:all") )
66
+ end
67
+ end
68
+ end
69
+
70
+ it "builds in the vendored copy WHICH_CEEDLING selects over the project's own setting" do
71
+ @c.with_context do
72
+ Dir.chdir @proj_name do
73
+ prepare_vendored_project()
74
+ @c.merge_project_yml_for_test( {:project => {:which_ceedling => 'gem'}} )
75
+ ENV['WHICH_CEEDLING'] = 'vendor/ceedling'
76
+
77
+ expect_build_in_vendored_copy( @c.ceedling_build_exec("test:all") )
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,91 @@
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_system_helper'
9
+
10
+ ##
11
+ ## Mocks Named by the Folders Their #includes Spell
12
+ ## ================================================
13
+ ##
14
+ ## CMock names a mock by the folder its #include names, and the compiler reaches the mock
15
+ ## through that #include as written. Mock generation, stand-ins, compiled sources and search
16
+ ## paths must all agree on where each mock lives (the path handling audit around GH #1370).
17
+ ##
18
+
19
+ MOCK_FOLDER_PREAMBLE = "#include \"unity.h\"\nvoid setUp(void) {}\nvoid tearDown(void) {}\n"
20
+
21
+ ceedling_system_tests do
22
+ include_context "a fresh ceedling gem project", "mock_folders"
23
+
24
+ def write(path, content)
25
+ FileUtils.mkdir_p( File.dirname( path ) )
26
+ File.write( path, content )
27
+ end
28
+
29
+ def build(include_paths, preprocessor: :none)
30
+ @c.merge_project_yml_for_test( { :project => { :use_test_preprocessor => preprocessor }, :paths => { :include => include_paths } } )
31
+ output = @c.ceedling_build_exec( "test:all" )
32
+
33
+ expect(@c.last_exit_status).to eq(0), output
34
+ expect(output).to match(/PASSED:\s+1/)
35
+ end
36
+
37
+ it "builds two same-named mocks whose #include folders alone tell them apart" do
38
+ in_project do
39
+ write( 'inc/a/foo.h', "int a_read(void);\n" )
40
+ write( 'inc/b/foo.h', "int b_read(void);\n" )
41
+ write( 'test/test_c.c', MOCK_FOLDER_PREAMBLE + "#include \"a/mock_foo.h\"\n#include \"b/mock_foo.h\"\n" \
42
+ "void test_reads(void) { a_read_ExpectAndReturn(5); b_read_ExpectAndReturn(6); TEST_ASSERT_EQUAL_INT(11, a_read() + b_read()); }\n" )
43
+
44
+ build( ['inc', 'inc/a', 'inc/b'] )
45
+ end
46
+ end
47
+
48
+ # The mocks root carries the test's name, which the #include's folder happens to share
49
+ it "builds a mock whose #include folder shares the test's own name" do
50
+ in_project do
51
+ write( 'inc/test_c/foo.h', "int foo_read(void);\n" )
52
+ write( 'test/test_c.c', MOCK_FOLDER_PREAMBLE + "#include \"test_c/mock_foo.h\"\nvoid test_reads(void) { foo_read_ExpectAndReturn(5); TEST_ASSERT_EQUAL_INT(5, foo_read()); }\n" )
53
+
54
+ build( ['inc', 'inc/test_c'] )
55
+ end
56
+ end
57
+
58
+ it "builds a mock whose #include spells more path than its header's mirror without naming it by folder" do
59
+ in_project do
60
+ @c.merge_project_yml_for_test( { :cmock => { :mock_name_include_folder => false } } )
61
+ write( 'inc/a/foo.h', "int foo_read(void);\n" )
62
+ write( 'test/test_c.c', MOCK_FOLDER_PREAMBLE + "#include \"inc/a/mock_foo.h\"\nvoid test_reads(void) { foo_read_ExpectAndReturn(5); TEST_ASSERT_EQUAL_INT(5, foo_read()); }\n" )
63
+
64
+ build( ['inc/**'] )
65
+ end
66
+ end
67
+
68
+ # Each stand-in opens as its real mock will, through its own folder, so a macro one header
69
+ # defines selects a mock only where that header is the one included
70
+ it "reconciles #includes through the header each same-named mock's folder names" do
71
+ in_project do
72
+ write( 'inc/a/foo.h', "int a_read(void);\n" )
73
+ write( 'inc/b/foo.h', "#define USE_B_EXTRA 1\nint b_read(void);\n" )
74
+ write( 'inc/extra.h', "int extra(void);\n" )
75
+ write( 'test/test_c.c', MOCK_FOLDER_PREAMBLE + "#include \"a/mock_foo.h\"\n#include \"b/mock_foo.h\"\n#if USE_B_EXTRA\n#include \"mock_extra.h\"\n#endif\n" \
76
+ "void test_reads(void) { a_read_ExpectAndReturn(5); b_read_ExpectAndReturn(6); extra_ExpectAndReturn(1); TEST_ASSERT_EQUAL_INT(12, a_read() + b_read() + extra()); }\n" )
77
+
78
+ build( ['inc/**'], preprocessor: :all )
79
+ end
80
+ end
81
+
82
+ it "leaves a mock #include in a branch that is off out of a preprocessed build" do
83
+ in_project do
84
+ write( 'inc/x/foo.h', "int foo_read(void);\n" )
85
+ write( 'test/test_c.c', MOCK_FOLDER_PREAMBLE + "#include \"x/mock_foo.h\"\n#if 0\n#include \"../legacy/mock_old.h\"\n#endif\n" \
86
+ "void test_reads(void) { foo_read_ExpectAndReturn(5); TEST_ASSERT_EQUAL_INT(5, foo_read()); }\n" )
87
+
88
+ build( ['inc/**'], preprocessor: :all )
89
+ end
90
+ end
91
+ end
@@ -98,12 +98,14 @@ ceedling_system_tests do
98
98
 
99
99
  before { copy_dotdot_include_assets }
100
100
 
101
- it "fails clearly, naming .. as unsupported rather than a generic file-not-found" do
101
+ # GH #1370 audit (G9): a task name is relative to the working directory, as every
102
+ # collected path is, so `..` names a place outside the project, where no test exists here
103
+ it "looks for the test outside the project, and names it when none is there" do
102
104
  in_project do
103
105
  output = @c.ceedling_build_exec("test:../unit/test_dotdot_include")
104
106
  expect(@c.last_exit_status).to_not eq(0)
105
- expect(output).to match(/\.\./)
106
- expect(output).to match(/context/i)
107
+ expect(output).to include("../unit/test_dotdot_include")
108
+ expect(output).to_not match(/no file context/i)
107
109
  end
108
110
  end
109
111
 
@@ -0,0 +1,192 @@
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_system_helper'
9
+ require 'tmpdir'
10
+
11
+ ##
12
+ ## Path Handling Through Real Builds (GH #1370 and the audit around it)
13
+ ## ======================================================================
14
+ ##
15
+ ## Each example builds a project whose configuration names paths in a way the path
16
+ ## handling audit found unsafe, and names the gap it probes. The project sits at `app/`
17
+ ## within its own directory, so a `..` root reaches only that directory, never a
18
+ ## neighboring project.
19
+ ##
20
+
21
+ PROBE_TEST_PREAMBLE = "#include \"unity.h\"\nvoid setUp(void) {}\nvoid tearDown(void) {}\n"
22
+
23
+ ceedling_system_tests do
24
+ include_context "a fresh ceedling gem project", "path_probe"
25
+
26
+ # Moves the fresh project into `app/` and runs the block from there
27
+ def in_app
28
+ in_project do
29
+ FileUtils.mkdir_p( 'app' )
30
+ FileUtils.mv( Dir.children( '.' ) - ['app'], 'app' )
31
+ Dir.chdir( 'app' ) { yield File.expand_path( '..' ) }
32
+ end
33
+ end
34
+
35
+ def write(path, content)
36
+ FileUtils.mkdir_p( File.dirname( path ) )
37
+ File.write( path, content )
38
+ end
39
+
40
+ # The report's setup: a vendor SDK far above the project, beside a `..` root
41
+ it "G1 (#1370): mocks a header far outside the project beside a `..` root" do
42
+ Dir.mktmpdir do |far|
43
+ sdk = File.join( File.realpath( far ), 'deep', 'sdk', 'inc' )
44
+ write( File.join( sdk, 'sdk.h' ), "int sdk_read(void);\n" )
45
+
46
+ in_app do |parent|
47
+ write( 'test/test_m.c', PROBE_TEST_PREAMBLE + "#include \"mock_sdk.h\"\nvoid test_reads(void) { sdk_read_ExpectAndReturn(3); TEST_ASSERT_EQUAL_INT(3, sdk_read()); }\n" )
48
+ @c.merge_project_yml_for_test( { :paths => { :include => ['../**', sdk] } } )
49
+
50
+ output = @c.ceedling_build_exec( "test:all" )
51
+
52
+ expect(@c.last_exit_status).to eq(0), output
53
+ expect(output).to match(/PASSED:\s+1/)
54
+ expect(Dir.children( parent ) - ['app']).to be_empty
55
+ end
56
+ end
57
+ end
58
+
59
+ it "G4: links the source beside a header below a `./` include root" do
60
+ in_app do
61
+ write( 'include/drv/x.h', "int x_value(void);\n" )
62
+ write( 'src/drv/x.c', "#include \"x.h\"\nint x_value(void) { return 7; }\n" )
63
+ write( 'test/test_x.c', PROBE_TEST_PREAMBLE + "#include \"x.h\"\nvoid test_value(void) { TEST_ASSERT_EQUAL_INT(7, x_value()); }\n" )
64
+ @c.merge_project_yml_for_test( { :project => { :use_test_preprocessor => :all }, :paths => { :include => ['./include/**'] } } )
65
+
66
+ output = @c.ceedling_build_exec( "test:all" )
67
+
68
+ expect(@c.last_exit_status).to eq(0), output
69
+ expect(output).to match(/PASSED:\s+1/)
70
+ end
71
+ end
72
+
73
+ it "G5: compiles both of two same-named sources below two roots into a release" do
74
+ in_app do
75
+ write( 'src/foo.c', "int foo_a(void) { return 1; }\n" )
76
+ write( 'lib/foo.c', "int foo_b(void) { return 2; }\n" )
77
+ write( 'src/main.c', "int foo_a(void);\nint foo_b(void);\nint main(void) { return foo_a() + foo_b() - 3; }\n" )
78
+ @c.merge_project_yml_for_test( { :project => { :release_build => true }, :paths => { :source => ['src/**', 'lib/**'] } } )
79
+
80
+ output = @c.ceedling_build_exec( "release" )
81
+
82
+ expect(@c.last_exit_status).to eq(0), output
83
+ end
84
+ end
85
+
86
+ # The mock search path for the header's mirrored directory reaches the #include as written
87
+ it "G14: builds a mock #include that climbs with `..`, keeping the mock below its test's mocks directory" do
88
+ in_app do
89
+ write( 'inc/x/foo.h', "int foo_read(void);\n" )
90
+ write( 'test/test_c.c', PROBE_TEST_PREAMBLE + "#include \"../x/mock_foo.h\"\nvoid test_reads(void) { foo_read_ExpectAndReturn(5); TEST_ASSERT_EQUAL_INT(5, foo_read()); }\n" )
91
+ @c.merge_project_yml_for_test( { :paths => { :include => ['inc/**'] } } )
92
+
93
+ output = @c.ceedling_build_exec( "test:all" )
94
+
95
+ expect(@c.last_exit_status).to eq(0), output
96
+ expect(output).to match(/PASSED:\s+1/)
97
+ expect(Dir.glob( 'build/test/mocks/test/test_c/**/mock_foo.h' )).to_not be_empty
98
+ expect(Dir.children( 'build/test/mocks' )).to eq( ['test'] )
99
+ expect(Dir.children( 'build/test/mocks/test' )).to eq( ['test_c'] )
100
+ end
101
+ end
102
+
103
+ # A test reaches a module's static functions by #including its source, which must not be
104
+ # linked a second time from its own object
105
+ it "links a test that #includes both a module's header and its source" do
106
+ in_app do
107
+ write( 'src/foo.h', "int foo(void);\n" )
108
+ write( 'src/foo.c', "#include \"foo.h\"\nstatic int helper(void) { return 2; }\nint foo(void) { return helper() + 1; }\n" )
109
+ write( 'test/test_foo.c', PROBE_TEST_PREAMBLE + "#include \"foo.h\"\n#include \"foo.c\"\nvoid test_helper(void) { TEST_ASSERT_EQUAL_INT(2, helper()); TEST_ASSERT_EQUAL_INT(3, foo()); }\n" )
110
+
111
+ output = @c.ceedling_build_exec( "test:all" )
112
+
113
+ expect(@c.last_exit_status).to eq(0), output
114
+ expect(output).to match(/PASSED:\s+1/)
115
+ end
116
+ end
117
+
118
+ # One file collected by one spelling and configured by another is one source
119
+ it "builds with a `./` build root and Unity helper, which name files the collections spell otherwise" do
120
+ in_app do
121
+ write( 'src/calc.h', "int calc(int a);\n" )
122
+ write( 'src/calc.c', "#include \"calc.h\"\n#include \"CException.h\"\nint calc(int a) { if (a < 0) { Throw(1); } return a + 1; }\n" )
123
+ write( 'test/support/unity_helper.h', "#define UNITY_HELPER_VALUE 1\n" )
124
+ write( 'test/support/unity_helper.c', "int unity_helper_value(void) { return 1; }\n" )
125
+ write( 'test/test_calc.c', PROBE_TEST_PREAMBLE + "#include \"CException.h\"\n#include \"calc.h\"\nvoid test_calc(void) { TEST_ASSERT_EQUAL_INT(2, calc(1)); }\n" )
126
+ @c.merge_project_yml_for_test( {
127
+ :project => { :build_root => './build', :use_exceptions => true },
128
+ :paths => { :support => ['test/support'] },
129
+ :cmock => { :unity_helper_path => ['./test/support/unity_helper.h'] }
130
+ } )
131
+
132
+ output = @c.ceedling_build_exec( "test:all" )
133
+
134
+ expect(@c.last_exit_status).to eq(0), output
135
+ expect(output).to match(/PASSED:\s+1/)
136
+ end
137
+ end
138
+
139
+ # A project file's relative paths resolve against the working directory, not the project
140
+ # file's own directory
141
+ it "G22: builds a project named by --project from another directory, with paths relative to that directory" do
142
+ in_app do |parent|
143
+ write( 'src/calc.c', "#include \"calc.h\"\nint calc(int a) { return a + 1; }\n" )
144
+ write( 'src/calc.h', "int calc(int a);\n" )
145
+ write( 'test/test_calc.c', PROBE_TEST_PREAMBLE + "#include \"calc.h\"\nvoid test_calc(void) { TEST_ASSERT_EQUAL_INT(2, calc(1)); }\n" )
146
+
147
+ project = YAML.load_file( 'project.yml' )
148
+ project[:project][:build_root] = 'app/build'
149
+ project[:paths] = { :test => ['app/test/**'], :source => ['app/src/**'], :include => ['app/src/**'], :support => [] }
150
+ File.write( 'project.yml', project.to_yaml )
151
+
152
+ Dir.chdir( parent ) do
153
+ output = @c.ceedling_build_exec( "--project app/project.yml test:all" )
154
+
155
+ expect(@c.last_exit_status).to eq(0), output
156
+ expect(output).to match(/PASSED:\s+1/)
157
+ expect(Dir.exist?( 'app/build/test' )).to be true
158
+ end
159
+ end
160
+ end
161
+
162
+ # Ceedling refuses a build root holding the project's own directories
163
+ it "G16: never lets clobber empty the project's own test directory" do
164
+ in_app do
165
+ write( 'test/test_keep.c', PROBE_TEST_PREAMBLE + "void test_it(void) {}\n" )
166
+ @c.merge_project_yml_for_test( { :project => { :build_root => '.' } } )
167
+
168
+ output = @c.ceedling_build_exec( "clobber" )
169
+
170
+ expect(@c.last_exit_status).to_not eq(0)
171
+ expect(output).to match( /:build_root => '\.' is the project directory or holds it/ )
172
+ expect(File.exist?( 'test/test_keep.c' )).to be( true )
173
+ end
174
+ end
175
+
176
+ it "reports coverage of a source in a sibling directory outside the project" do
177
+ in_app do |parent|
178
+ write( File.join( parent, 'shared', 'src', 'calc.c' ), "#include \"calc.h\"\nint calc(int a) { return a + 1; }\n" )
179
+ write( File.join( parent, 'shared', 'src', 'calc.h' ), "int calc(int a);\n" )
180
+ write( 'test/test_calc.c', PROBE_TEST_PREAMBLE + "#include \"calc.h\"\nvoid test_calc(void) { TEST_ASSERT_EQUAL_INT(2, calc(1)); }\n" )
181
+ @c.merge_project_yml_for_test( {
182
+ :plugins => { :enabled => ['gcov'] },
183
+ :paths => { :source => ['../shared/src/**'], :include => ['../shared/src/**'] }
184
+ } )
185
+
186
+ output = @c.ceedling_build_exec( "gcov:all" )
187
+
188
+ expect(@c.last_exit_status).to eq(0), output
189
+ expect(output).to match(/calc\.c/)
190
+ end
191
+ end
192
+ end
@@ -164,7 +164,7 @@ ceedling_system_tests do
164
164
  @c.ceedling_build_exec
165
165
  expect(@c.last_exit_status).to eq(0)
166
166
 
167
- runner_path = 'build/test/runners/test_ptc_runner.c'
167
+ runner_path = 'build/test/runners/test/test_ptc_runner.c'
168
168
  expect(File.exist?(runner_path)).to eq(true)
169
169
  runner_contents = read_spec_file(runner_path)
170
170
 
@@ -61,8 +61,8 @@ ceedling_system_tests do
61
61
  expect(output).to match(/baz[\/\\]bar\.c/)
62
62
  expect(output).to match(/^Compiling bar\.c/)
63
63
 
64
- expect(File.exist?('build/release/out/baz/bar.o')).to be true
65
- expect(File.exist?('build/release/out/foo/bar.o')).to be false
64
+ expect(File.exist?('build/release/out/src/baz/bar.o')).to be true
65
+ expect(File.exist?('build/release/out/src/foo/bar.o')).to be false
66
66
  end
67
67
  end
68
68
 
@@ -73,8 +73,8 @@ ceedling_system_tests do
73
73
  expect(output).to match(/^Compiling bar\.c/)
74
74
  expect(output).to_not match(/^Linking /)
75
75
 
76
- expect(File.exist?('build/release/out/foo/bar.o')).to be true
77
- expect(File.exist?('build/release/out/baz/bar.o')).to be false
76
+ expect(File.exist?('build/release/out/src/foo/bar.o')).to be true
77
+ expect(File.exist?('build/release/out/src/baz/bar.o')).to be false
78
78
  end
79
79
  end
80
80
 
@@ -85,8 +85,8 @@ ceedling_system_tests do
85
85
  expect(output).to match(/^Compiling bar\.c/)
86
86
  expect(output).to_not match(/^Linking /)
87
87
 
88
- expect(File.exist?('build/release/out/baz/bar.o')).to be true
89
- expect(File.exist?('build/release/out/foo/bar.o')).to be false
88
+ expect(File.exist?('build/release/out/src/baz/bar.o')).to be true
89
+ expect(File.exist?('build/release/out/src/foo/bar.o')).to be false
90
90
  end
91
91
  end
92
92
 
@@ -113,6 +113,91 @@ ceedling_system_tests do
113
113
 
114
114
  end
115
115
 
116
+ # =========================================================================
117
+ describe "A test at its root beside same-named tests below it" do
118
+ # =========================================================================
119
+
120
+ # GH #1364: a test at its root builds beside same-named tests below it
121
+ before do
122
+ in_project do
123
+ copy_fixture("tests_with_duplicate_test_names/test_foo.c", 'test')
124
+ copy_fixture("tests_with_duplicate_test_names/unit/test_foo.c", 'test/unit')
125
+ copy_fixture("tests_with_duplicate_test_names/integration/test_foo.c", 'test/integration')
126
+ end
127
+ end
128
+
129
+ it "runs all three under test:all, and summarizes all three" do
130
+ in_project do
131
+ output = @c.ceedling_build_exec("test:all")
132
+ expect(@c.last_exit_status).to eq(0)
133
+ expect(output).to_not match(/Ambiguous/)
134
+ expect(output).to match(/TESTED:\s+3/)
135
+ expect(output).to match(/PASSED:\s+3/)
136
+ expect(output).to match(/test_this_is_the_root_directory_test_foo/)
137
+
138
+ summary = @c.ceedling_build_exec("summary")
139
+ expect(summary).to match(/TESTED:\s+3/)
140
+ end
141
+ end
142
+
143
+ it "runs exactly the test at the root when named by its full path" do
144
+ in_project do
145
+ output = @c.ceedling_build_exec("test:test/test_foo.c")
146
+ expect(@c.last_exit_status).to eq(0)
147
+ expect(output).to match(/TESTED:\s+1/)
148
+ expect(output).to match(/test_this_is_the_root_directory_test_foo/)
149
+ end
150
+ end
151
+
152
+ it "runs all three under gcov:all" do
153
+ in_project do
154
+ @c.merge_project_yml_for_test({ :plugins => { :enabled => ['gcov'] } })
155
+
156
+ output = @c.ceedling_build_exec("gcov:all")
157
+ expect(@c.last_exit_status).to eq(0)
158
+ expect(output).to_not match(/Ambiguous/)
159
+ expect(output).to match(/TESTED:\s+3/)
160
+ expect(output).to match(/PASSED:\s+3/)
161
+ end
162
+ end
163
+
164
+ end
165
+
166
+ # =========================================================================
167
+ describe "Same-named tests under more than one test root" do
168
+ # =========================================================================
169
+
170
+ # GH #1364: tests with one path below different roots keep apart
171
+ it "runs both tests when one root lies inside the other" do
172
+ in_project do
173
+ copy_fixture("tests_with_duplicate_test_names/unit/test_foo.c", 'test')
174
+ copy_fixture("tests_with_duplicate_test_names/integration/test_foo.c", 'test/unit')
175
+ @c.merge_project_yml_for_test({ :paths => { :test => ['+:test/unit/**'] } })
176
+
177
+ output = @c.ceedling_build_exec("test:all")
178
+ expect(@c.last_exit_status).to eq(0)
179
+ expect(output).to match(/TESTED:\s+2/)
180
+ expect(output).to match(/test_this_is_the_unit_directory_test_foo/)
181
+ expect(output).to match(/test_this_is_the_integration_directory_test_foo/)
182
+ end
183
+ end
184
+
185
+ it "runs both tests when two roots hold the same layout" do
186
+ in_project do
187
+ copy_fixture("tests_with_duplicate_test_names/unit/test_foo.c", 'test/foo')
188
+ copy_fixture("tests_with_duplicate_test_names/integration/test_foo.c", 'extra/foo')
189
+ @c.merge_project_yml_for_test({ :paths => { :test => ['+:extra/**'] } })
190
+
191
+ output = @c.ceedling_build_exec("test:all")
192
+ expect(@c.last_exit_status).to eq(0)
193
+ expect(output).to match(/TESTED:\s+2/)
194
+ expect(output).to match(/test_this_is_the_unit_directory_test_foo/)
195
+ expect(output).to match(/test_this_is_the_integration_directory_test_foo/)
196
+ end
197
+ end
198
+
199
+ end
200
+
116
201
  end
117
202
 
118
203
  end
@@ -0,0 +1,86 @@
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_system_helper'
9
+
10
+ ##
11
+ ## Tests Under Paths Holding Shell Characters Run (issue #1373)
12
+ ## ==============================================================
13
+ ##
14
+ ## A test's executable sits beneath its path from the project root, and tools run through
15
+ ## the system shell. The default tools that run a test executable named it unquoted, so a
16
+ ## test under `test/o'neil/` reported every case as a crash, and one under `test/my dir/`
17
+ ## stopped the build. Each runs here, with a pass, a failure, and a crash that the simple
18
+ ## backtrace reruns pin to its own case.
19
+ ##
20
+
21
+ SPECIAL_PATH_TEST_C = <<~C
22
+ #include "unity.h"
23
+
24
+ void setUp(void) {}
25
+ void tearDown(void) {}
26
+
27
+ void test_passes(void) { TEST_ASSERT_TRUE(1); }
28
+ void test_fails(void) { TEST_ASSERT_EQUAL_INT(1, 2); }
29
+ C
30
+
31
+ SPECIAL_PATH_CRASH_C = <<~C
32
+
33
+ void test_crashes(void) { volatile int *p = 0; *p = 1; }
34
+ C
35
+
36
+ ceedling_system_tests do
37
+ include_context "a fresh ceedling gem project", "special_path"
38
+
39
+ ["o'neil", "my dir"].each do |directory|
40
+ describe "A test under `test/#{directory}/`" do
41
+ before do
42
+ in_project do
43
+ FileUtils.mkdir_p( "test/#{directory}" )
44
+ File.write( "test/#{directory}/test_special.c", SPECIAL_PATH_TEST_C )
45
+ end
46
+ end
47
+
48
+ it "runs a test under `test/#{directory}/`, reporting each case's own result" do
49
+ in_project do
50
+ output = @c.ceedling_build_exec( "test:all" )
51
+
52
+ expect(@c.last_exit_status).to eq(1), output
53
+ expect(output).to_not match(/crashed/i)
54
+ expect(output).to match(/TESTED:\s+2/)
55
+ expect(output).to match(/PASSED:\s+1/)
56
+ expect(output).to match(/FAILED:\s+1/)
57
+ end
58
+ end
59
+
60
+ it "pins a crash under `test/#{directory}/` to its own case through simple backtrace reruns" do
61
+ in_project do
62
+ File.write( "test/#{directory}/test_special.c", SPECIAL_PATH_TEST_C + SPECIAL_PATH_CRASH_C )
63
+
64
+ output = @c.ceedling_build_exec( "test:all" )
65
+
66
+ expect(output).to match(/Test: test_crashes/)
67
+ expect(output).to match(/TESTED:\s+3/)
68
+ expect(output).to match(/PASSED:\s+1/)
69
+ expect(output).to match(/FAILED:\s+2/)
70
+ end
71
+ end
72
+
73
+ it "runs a test under `test/#{directory}/` with gcov" do
74
+ in_project do
75
+ @c.merge_project_yml_for_test( {:plugins => {:enabled => ['gcov']}} )
76
+
77
+ output = @c.ceedling_build_exec( "gcov:all" )
78
+
79
+ expect(output).to_not match(/crashed/i)
80
+ expect(output).to match(/PASSED:\s+1/)
81
+ expect(output).to match(/FAILED:\s+1/)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end