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
@@ -0,0 +1,292 @@
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 'config_yaml_helper'
10
+ require 'ceedling/config/configurator_paths_validator'
11
+ require 'ceedling/config/config_walkinator'
12
+ require 'ceedling/reportinator'
13
+
14
+ # Unit coverage for ConfiguratorPathsValidator through a doubled file layer. What these
15
+ # validations make of a real project tree is proven in
16
+ # spec/integration/configurator_validation_spec.rb.
17
+ describe ConfiguratorPathsValidator do
18
+ include ConfigYamlHelper
19
+
20
+ before(:each) do
21
+ @file_wrapper = double('file_wrapper')
22
+ @loginator = double('loginator', log: nil)
23
+
24
+ @validator = described_class.new(
25
+ {
26
+ config_walkinator: ConfigWalkinator.new,
27
+ file_wrapper: @file_wrapper,
28
+ loginator: @loginator,
29
+ reportinator: Reportinator.new
30
+ }
31
+ )
32
+ end
33
+
34
+ def existing(*paths)
35
+ allow(@file_wrapper).to receive(:exist?) { |path| paths.include?( path ) }
36
+ end
37
+
38
+ def directories(*paths)
39
+ allow(@file_wrapper).to receive(:directory?) { |path| paths.include?( path ) }
40
+ end
41
+
42
+ describe '#validate_path_list' do
43
+ let(:config) { config_from_yaml( ":paths:\n :test:\n - +:test/**\n - -:test/ignore\n - '**/generated'\n" ) }
44
+
45
+ it 'checks each path stripped of its aggregation decorator and glob' do
46
+ existing('test', 'test/ignore')
47
+ expect(@validator.validate_path_list( config, :paths, :test )).to be true
48
+ end
49
+
50
+ it 'skips a path that begins with a glob' do
51
+ existing('test', 'test/ignore')
52
+ @validator.validate_path_list( config, :paths, :test )
53
+ expect(@file_wrapper).to_not have_received(:exist?).with('')
54
+ end
55
+
56
+ it 'logs each path that does not exist' do
57
+ existing()
58
+ expect(@validator.validate_path_list( config, :paths, :test )).to be false
59
+ expect(@loginator).to have_received(:log).with("Config path :paths ↳ :test => 'test' does not exist in the filesystem.", Verbosity::ERRORS)
60
+ end
61
+
62
+ # The path handling audit around GH #1370: a `-:` entry may name nothing to leave out
63
+ it 'leaves a `-:` path to the entries validation' do
64
+ existing('test')
65
+ expect(@validator.validate_path_list( config, :paths, :test )).to be true
66
+ end
67
+
68
+ it 'fails a missing entry' do
69
+ expect(@validator.validate_path_list( config, :paths, :source )).to be false
70
+ end
71
+ end
72
+
73
+ # An entry naming no path, or wrapping its path in quotes, is rejected before any
74
+ # filesystem check. Both usually come from quoting only the path after a +: or -:
75
+ # decoration, so each rejection carries a hint about quoting.
76
+ shared_examples 'an entry that names no usable path' do |walk|
77
+ {
78
+ 'a bare subtractive decoration' => " - '-:'\n",
79
+ 'a bare additive decoration' => " - '+:'\n",
80
+ 'an empty string' => " - ''\n",
81
+ 'whitespace alone' => " - ' '\n",
82
+ 'a YAML null' => " -\n",
83
+ }.each_pair do |label, yaml|
84
+ it "rejects #{label} as naming no path, with a quoting hint" do
85
+ expect(validate( yaml )).to be false
86
+ expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '.*' names no path/, Verbosity::ERRORS)
87
+ expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
88
+ end
89
+ end
90
+
91
+ # YAML reads an unquoted decoration with nothing after it as a one-key mapping
92
+ it 'rejects an entry YAML read as something other than a path, with a quoting hint' do
93
+ expect(validate( " - -:\n" )).to be false
94
+ expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '.*' is not a path \(YAML read it as a Hash\)/, Verbosity::ERRORS)
95
+ expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
96
+ end
97
+
98
+ it 'rejects a path wrapped in quotes after its decoration, with a quoting hint' do
99
+ expect(validate( " - '-:\"src/a.c\"'\n" )).to be false
100
+ expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '-:"src\/a.c"' wraps its path in quotes/, Verbosity::ERRORS)
101
+ expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
102
+ end
103
+ end
104
+
105
+ describe '#validate_paths_entries' do
106
+ def validate(yaml_list)
107
+ @validator.validate_paths_entries( config_from_yaml( ":paths:\n :source:\n#{yaml_list}" ), :source )
108
+ end
109
+
110
+ it 'accepts a glob that yields directories' do
111
+ existing; directories('src', 'src/a')
112
+ allow(@file_wrapper).to receive(:directory_listing).with('src/**/**').and_return(['src', 'src/a', 'src/a/x.c'])
113
+
114
+ expect(validate( " - src/**\n" )).to be true
115
+ end
116
+
117
+ it 'warns about and skips a path naming a file' do
118
+ existing('src/main.c'); directories
119
+
120
+ expect(validate( " - src/main.c\n" )).to be true
121
+ expect(@loginator).to have_received(:log).with(/'src\/main.c' is a filepath and will be ignored/, Verbosity::COMPLAIN)
122
+ end
123
+
124
+ it 'accepts a subdirectory glob of a directory that has no subdirectories' do
125
+ existing; directories
126
+ allow(@file_wrapper).to receive(:directory_listing).and_return([])
127
+
128
+ expect(validate( " - src/*\n" )).to be true
129
+ end
130
+
131
+ it 'logs a path that yields no directories' do
132
+ existing; directories
133
+ allow(@file_wrapper).to receive(:directory_listing).and_return([])
134
+
135
+ expect(validate( " - +:src/missing\n" )).to be false
136
+ expect(@loginator).to have_received(:log).with(/'src\/missing' yielded no directories/, Verbosity::ERRORS)
137
+ end
138
+
139
+ # The path handling audit around GH #1370: a `-:` entry names what a build leaves out
140
+ it 'accepts a `-:` path that names nothing, warning of it' do
141
+ existing; directories
142
+ allow(@file_wrapper).to receive(:directory_listing).and_return([])
143
+
144
+ expect(validate( " - -:src/missing\n" )).to be true
145
+ expect(@loginator).to have_received(:log).with(/'-:src\/missing' leaves out nothing; no directory matches it/, Verbosity::COMPLAIN)
146
+ end
147
+
148
+ it 'warns of a `-:` subdirectories glob whose directory does not exist' do
149
+ existing; directories
150
+ allow(@file_wrapper).to receive(:directory_listing).and_return([])
151
+
152
+ expect(validate( " - -:src/typo/**\n" )).to be true
153
+ expect(@loginator).to have_received(:log).with(/'-:src\/typo\/\*\*' leaves out nothing; no directory matches it/, Verbosity::COMPLAIN)
154
+ end
155
+
156
+ it 'warns of a `-:` glob that matches nothing below a directory that exists' do
157
+ existing( 'src' ); directories( 'src' )
158
+ allow(@file_wrapper).to receive(:directory_listing).and_return([])
159
+
160
+ expect(validate( " - -:src/nomatch*\n" )).to be true
161
+ expect(@loginator).to have_received(:log).with(/'-:src\/nomatch\*' leaves out nothing/, Verbosity::COMPLAIN)
162
+ end
163
+
164
+ it 'accepts a `-:` subdirectories glob of an existing directory without a word' do
165
+ existing( 'src/legacy' ); directories( 'src/legacy' )
166
+ allow(@file_wrapper).to receive(:directory_listing).and_return([])
167
+
168
+ expect(validate( " - -:src/legacy/**\n" )).to be true
169
+ expect(@loginator).to_not have_received(:log)
170
+ end
171
+
172
+ it 'accepts a `-:` path below the build root that names nothing, without a word' do
173
+ existing; directories
174
+ allow(@file_wrapper).to receive(:directory_listing).and_return([])
175
+
176
+ config = config_from_yaml( ":project:\n :build_root: build\n:paths:\n :source:\n - -:build/gen\n" )
177
+ expect(@validator.validate_paths_entries( config, :source )).to be true
178
+ expect(@loginator).to_not have_received(:log)
179
+ end
180
+
181
+ it 'escapes literal brackets before globbing' do
182
+ existing; directories('src/[legacy]')
183
+ allow(@file_wrapper).to receive(:directory_listing).with('src/\[legacy\]').and_return(['src/[legacy]'])
184
+
185
+ expect(validate( " - 'src/[legacy]'\n" )).to be true
186
+ end
187
+
188
+ it 'fails a missing entry' do
189
+ expect(@validator.validate_paths_entries( { paths: {} }, :source )).to be false
190
+ end
191
+
192
+ it_behaves_like 'an entry that names no usable path', ':paths ↳ :source'
193
+ end
194
+
195
+ describe '#validate_files_entries' do
196
+ def validate(yaml_list)
197
+ @validator.validate_files_entries( config_from_yaml( ":files:\n :source:\n#{yaml_list}" ), :source )
198
+ end
199
+
200
+ it 'accepts a glob that yields files' do
201
+ existing; directories
202
+ allow(@file_wrapper).to receive(:instantiate_file_list).with('src/*.c').and_return(['src/a.c'])
203
+
204
+ expect(validate( " - +:src/*.c\n" )).to be true
205
+ end
206
+
207
+ it 'warns about and skips a path naming a directory' do
208
+ existing('src'); directories('src')
209
+
210
+ expect(validate( " - src\n" )).to be true
211
+ expect(@loginator).to have_received(:log).with(/'src' is a directory path and will be ignored/, Verbosity::COMPLAIN)
212
+ end
213
+
214
+ it 'logs a glob that yields no files' do
215
+ existing; directories
216
+ allow(@file_wrapper).to receive(:instantiate_file_list).and_return([])
217
+
218
+ expect(validate( " - src/*.x\n" )).to be false
219
+ expect(@loginator).to have_received(:log).with(/'src\/\*.x' yielded no files/, Verbosity::ERRORS)
220
+ end
221
+
222
+ it 'accepts a `-:` glob that names no files, warning of it' do
223
+ existing; directories
224
+ allow(@file_wrapper).to receive(:instantiate_file_list).and_return([])
225
+
226
+ expect(validate( " - -:src/*.x\n" )).to be true
227
+ expect(@loginator).to have_received(:log).with(/'-:src\/\*.x' leaves out nothing; no file matches it/, Verbosity::COMPLAIN)
228
+ end
229
+
230
+ it 'escapes literal brackets before globbing' do
231
+ existing; directories
232
+ allow(@file_wrapper).to receive(:instantiate_file_list).with('src/\[legacy\]/*.c').and_return(['src/[legacy]/a.c'])
233
+
234
+ expect(validate( " - 'src/[legacy]/*.c'\n" )).to be true
235
+ end
236
+
237
+ it 'fails a missing entry' do
238
+ expect(@validator.validate_files_entries( { files: {} }, :source )).to be false
239
+ end
240
+
241
+ it_behaves_like 'an entry that names no usable path', ':files ↳ :source'
242
+ end
243
+
244
+ # The path handling audit around GH #1370: clobber empties the build root's test and
245
+ # release trees
246
+ describe '#validate_build_root' do
247
+ def validate(build_root, paths: " :source:\n - src/**\n", files: '')
248
+ yaml = ":project:\n :build_root: '#{build_root}'\n:paths:\n#{paths}"
249
+ yaml += ":files:\n#{files}" unless files.empty?
250
+ @validator.validate_build_root( config_from_yaml( yaml ) )
251
+ end
252
+
253
+ it 'accepts a build root of its own' do
254
+ expect(validate( 'build' )).to be true
255
+ end
256
+
257
+ {
258
+ '' => 'names no directory',
259
+ '.' => 'is the project directory or holds it',
260
+ '..' => 'is the project directory or holds it',
261
+ '/' => 'is the project directory or holds it'
262
+ }.each do |root, problem|
263
+ it "refuses a build root of '#{root}', which #{problem}" do
264
+ expect(validate( root )).to be false
265
+ expect(@loginator).to have_received(:log).with( ":project ↳ :build_root => '#{root}' #{problem}. Give the build its own directory, such as 'build'.", Verbosity::ERRORS )
266
+ end
267
+ end
268
+
269
+ it 'accepts a build root holding :paths and :files entries that add to a build, warning of each' do
270
+ expect(validate( 'gen', paths: " :source:\n - src/**\n - gen/**\n", files: " :source:\n - gen/out/a.c\n" )).to be true
271
+ expect(@loginator).to have_received(:log).with( ":paths ↳ :source => 'gen/**' lies in the build root 'gen'. Ceedling leaves out the directories it creates there.", Verbosity::COMPLAIN )
272
+ expect(@loginator).to have_received(:log).with( ":files ↳ :source => 'gen/out/a.c' lies in the build root 'gen'. Ceedling leaves out the directories it creates there.", Verbosity::COMPLAIN )
273
+ end
274
+
275
+ it 'accepts a build root holding only what `-:` entries name' do
276
+ expect(validate( 'build', paths: " :source:\n - src/**\n - -:build/gen\n" )).to be true
277
+ end
278
+ end
279
+
280
+ describe '#validate_filepath_simple' do
281
+ it 'accepts an existing path' do
282
+ existing('helper.h')
283
+ expect(@validator.validate_filepath_simple( 'helper.h', :cmock, :unity_helper_path )).to be true
284
+ end
285
+
286
+ it 'logs a missing path with the configuration walk it came from' do
287
+ existing
288
+ expect(@validator.validate_filepath_simple( 'helper.h', :cmock, :unity_helper_path )).to be false
289
+ expect(@loginator).to have_received(:log).with("Config path 'helper.h' associated with :cmock ↳ :unity_helper_path does not exist in the filesystem.", Verbosity::ERRORS)
290
+ end
291
+ end
292
+ end
@@ -20,6 +20,7 @@ describe ConfiguratorSetup do
20
20
  before(:each) do
21
21
  @configurator_builder = double('ConfiguratorBuilder')
22
22
  @configurator_validator = double('ConfiguratorValidator')
23
+ @paths_validator = double('ConfiguratorPathsValidator')
23
24
  @loginator = double('Loginator')
24
25
  @reportinator = Reportinator.new
25
26
  @file_wrapper = double('FileWrapper')
@@ -30,6 +31,7 @@ describe ConfiguratorSetup do
30
31
  {
31
32
  configurator_builder: @configurator_builder,
32
33
  configurator_validator: @configurator_validator,
34
+ configurator_paths_validator: @paths_validator,
33
35
  loginator: @loginator,
34
36
  reportinator: @reportinator,
35
37
  file_wrapper: @file_wrapper,
@@ -177,54 +179,6 @@ describe ConfiguratorSetup do
177
179
  end
178
180
  end
179
181
 
180
- # Issue #1292: a vendor destination (build/vendor/unity/src, etc.) occasionally turns
181
- # up as the wrong file/directory type, crashing the copy that populates it. These
182
- # examples cover the two fixes: unconditional copying (never skipped just because the
183
- # destination looks already populated -- an errant edit there must be overwritten, not
184
- # left standing) and self-healing a wrong-typed destination before that copy runs.
185
- context "#heal_vendor_path" do
186
- it "does nothing when neither the destination nor the marker file exist yet" do
187
- allow(@file_wrapper).to receive(:exist?).and_return(false)
188
-
189
- @setup.heal_vendor_path('/build/vendor/unity/src', 'unity.c')
190
-
191
- expect(@file_wrapper).to_not receive(:rm_rf)
192
- end
193
-
194
- it "does nothing when the destination is a directory and the marker is a plain file inside it" do
195
- allow(@file_wrapper).to receive(:exist?).with('/build/vendor/unity/src').and_return(true)
196
- allow(@file_wrapper).to receive(:directory?).with('/build/vendor/unity/src').and_return(true)
197
- allow(@file_wrapper).to receive(:exist?).with('/build/vendor/unity/src/unity.c').and_return(true)
198
- allow(@file_wrapper).to receive(:directory?).with('/build/vendor/unity/src/unity.c').and_return(false)
199
-
200
- @setup.heal_vendor_path('/build/vendor/unity/src', 'unity.c')
201
-
202
- expect(@file_wrapper).to_not receive(:rm_rf)
203
- end
204
-
205
- it "removes and logs a NOTICE when the destination itself is the wrong type (a file, not a directory)" do
206
- allow(@file_wrapper).to receive(:exist?).with('/build/vendor/unity/src').and_return(true)
207
- allow(@file_wrapper).to receive(:directory?).with('/build/vendor/unity/src').and_return(false)
208
- expect(@file_wrapper).to receive(:rm_rf).with('/build/vendor/unity/src')
209
- expect(@loginator).to receive(:log)
210
- .with(a_string_including('/build/vendor/unity/src'), Verbosity::COMPLAIN, LogLabels::NOTICE)
211
-
212
- @setup.heal_vendor_path('/build/vendor/unity/src', 'unity.c')
213
- end
214
-
215
- it "removes and logs a NOTICE when the marker file inside an otherwise-fine destination is the wrong type (Issue #1292's own reported shape: unity.c itself became a directory)" do
216
- allow(@file_wrapper).to receive(:exist?).with('/build/vendor/unity/src').and_return(true)
217
- allow(@file_wrapper).to receive(:directory?).with('/build/vendor/unity/src').and_return(true)
218
- allow(@file_wrapper).to receive(:exist?).with('/build/vendor/unity/src/unity.c').and_return(true)
219
- allow(@file_wrapper).to receive(:directory?).with('/build/vendor/unity/src/unity.c').and_return(true)
220
- expect(@file_wrapper).to receive(:rm_rf).with('/build/vendor/unity/src')
221
- expect(@loginator).to receive(:log)
222
- .with(a_string_including('/build/vendor/unity/src'), Verbosity::COMPLAIN, LogLabels::NOTICE)
223
-
224
- @setup.heal_vendor_path('/build/vendor/unity/src', 'unity.c')
225
- end
226
- end
227
-
228
182
  # Only a build populates build/vendor, so a command that only reads the project, such as
229
183
  # files:test or dumpconfig, leaves a concurrent build's files alone (GH #1361)
230
184
  context "#vendor_frameworks_and_support_files" do
@@ -313,16 +267,6 @@ describe ConfiguratorSetup do
313
267
  expect(@file_wrapper).to_not have_received(:sync_file)
314
268
  expect(@file_wrapper).to_not have_received(:rm_rf)
315
269
  end
316
-
317
- it "heals a corrupted (wrong-typed) vendor destination before copying" do
318
- allow(@file_wrapper).to receive(:exist?).with('/build/vendor/unity/src').and_return(true)
319
- allow(@file_wrapper).to receive(:directory?).with('/build/vendor/unity/src').and_return(false)
320
- allow(@loginator).to receive(:log)
321
-
322
- vendor( test_build: true )
323
-
324
- expect(@file_wrapper).to have_received(:rm_rf).with('/build/vendor/unity/src')
325
- end
326
270
  end
327
271
 
328
272
  context "configuration validation" do
@@ -370,19 +314,19 @@ describe ConfiguratorSetup do
370
314
  end
371
315
 
372
316
  it "checks helper paths, plugin load paths, and every :paths and :files entry" do
373
- allow(@configurator_validator).to receive_messages(
317
+ allow(@paths_validator).to receive_messages(
374
318
  validate_filepath_simple: true, validate_path_list: true, validate_paths_entries: true, validate_files_entries: true
375
319
  )
376
320
 
377
321
  expect(@setup.validate_paths( config )).to be true
378
- expect(@configurator_validator).to have_received(:validate_filepath_simple).with('helper.h', :cmock, :unity_helper_path)
379
- expect(@configurator_validator).to have_received(:validate_filepath_simple).with('plugins', :plugins, :load_paths)
380
- expect(@configurator_validator).to have_received(:validate_paths_entries).with(config, :source)
381
- expect(@configurator_validator).to have_received(:validate_files_entries).with(config, :support)
322
+ expect(@paths_validator).to have_received(:validate_filepath_simple).with('helper.h', :cmock, :unity_helper_path)
323
+ expect(@paths_validator).to have_received(:validate_filepath_simple).with('plugins', :plugins, :load_paths)
324
+ expect(@paths_validator).to have_received(:validate_paths_entries).with(config, :source)
325
+ expect(@paths_validator).to have_received(:validate_files_entries).with(config, :support)
382
326
  end
383
327
 
384
328
  it "fails when any check fails" do
385
- allow(@configurator_validator).to receive_messages(
329
+ allow(@paths_validator).to receive_messages(
386
330
  validate_filepath_simple: true, validate_path_list: true, validate_paths_entries: true, validate_files_entries: false
387
331
  )
388
332
 
@@ -751,7 +695,7 @@ describe ConfiguratorSetup do
751
695
  context "#build_project_collections" do
752
696
  it "merges every path and file collection" do
753
697
  collections = [
754
- :expand_all_path_globs, :collect_vendor_paths, :collect_source_and_include_paths, :collect_source_include_vendor_paths,
698
+ :expand_all_path_globs, :collect_mirror_roots, :collect_vendor_paths, :collect_source_and_include_paths, :collect_source_include_vendor_paths,
755
699
  :collect_test_support_source_include_paths, :collect_test_support_source_include_vendor_paths, :collect_assembly,
756
700
  :collect_headers, :collect_release_build_input, :collect_existing_test_build_input,
757
701
  :collect_release_artifact_extra_link_objects, :collect_test_fixture_extra_link_objects, :collect_vendor_framework_sources
@@ -606,20 +606,42 @@ describe Configurator do
606
606
  expect( @configurator.get_cmock_config[:plugins] ).to eq( ['ignore', :ignore, 'expect_any_args'] )
607
607
  end
608
608
 
609
- it "normalizes plugins, helper paths, includes, and the mock prefix define when mocks are on" do
609
+ it "normalizes plugins and the mock prefix define when mocks are on" do
610
610
  config = cmock_config(true)
611
611
 
612
612
  @configurator.populate_cmock_config( config )
613
613
 
614
614
  expect( @configurator.get_cmock_config ).to include(
615
- plugins: [:ignore, :expect_any_args],
616
- unity_helper_path: ['support/unity_helper.h'],
617
- includes: ['unity_helper.h'],
618
- defines: ['CMOCK_MOCK_PREFIX=mock_']
615
+ plugins: [:ignore, :expect_any_args],
616
+ defines: ['CMOCK_MOCK_PREFIX=mock_']
619
617
  )
620
618
  end
621
619
  end
622
620
 
621
+ # The path handling audit around GH #1370: a helper's filename is taken from its path
622
+ # as standardized, so this runs after path standardizing
623
+ describe "#populate_cmock_helpers" do
624
+ def helper_config(use_mocks, helper)
625
+ { project: { use_mocks: use_mocks }, cmock: { unity_helper_path: helper, includes: ['unity_helper.h'] } }
626
+ end
627
+
628
+ it "lists a single helper path and includes each helper in every mock, once, by its filename" do
629
+ config = helper_config( true, 'support/unity_helper.h' )
630
+
631
+ @configurator.populate_cmock_helpers( config )
632
+
633
+ expect( config[:cmock] ).to include( unity_helper_path: ['support/unity_helper.h'], includes: ['unity_helper.h'] )
634
+ end
635
+
636
+ it "leaves the helpers alone when mocks are off" do
637
+ config = helper_config( false, 'support/unity_helper.h' )
638
+
639
+ @configurator.populate_cmock_helpers( config )
640
+
641
+ expect( config[:cmock][:unity_helper_path] ).to eq( 'support/unity_helper.h' )
642
+ end
643
+ end
644
+
623
645
  describe "#populate_exceptions_config" do
624
646
  it "enables exceptions when CMock uses its CException plugin" do
625
647
  config = { project: { use_exceptions: false }, cmock: { plugins: [:cexception] }, cexception: {} }
@@ -11,21 +11,17 @@ require 'ceedling/config/configurator_validator'
11
11
  require 'ceedling/config/config_walkinator'
12
12
  require 'ceedling/reportinator'
13
13
 
14
- # Unit coverage for ConfiguratorValidator through a doubled file layer. What these
15
- # validations make of a real project tree is proven in
16
- # spec/integration/configurator_validation_spec.rb.
14
+ # Unit coverage for ConfiguratorValidator's checks of required entries, tools, and matchers
17
15
  describe ConfiguratorValidator do
18
16
  include ConfigYamlHelper
19
17
 
20
18
  before(:each) do
21
- @file_wrapper = double('file_wrapper')
22
19
  @loginator = double('loginator', log: nil)
23
20
  @tool_validator = double('tool_validator')
24
21
 
25
22
  @validator = described_class.new(
26
23
  {
27
24
  config_walkinator: ConfigWalkinator.new,
28
- file_wrapper: @file_wrapper,
29
25
  loginator: @loginator,
30
26
  reportinator: Reportinator.new,
31
27
  tool_validator: @tool_validator
@@ -33,14 +29,6 @@ describe ConfiguratorValidator do
33
29
  )
34
30
  end
35
31
 
36
- def existing(*paths)
37
- allow(@file_wrapper).to receive(:exist?) { |path| paths.include?( path ) }
38
- end
39
-
40
- def directories(*paths)
41
- allow(@file_wrapper).to receive(:directory?) { |path| paths.include?( path ) }
42
- end
43
-
44
32
  describe '#exists?' do
45
33
  let(:config) { config_from_yaml( ":project:\n :build_root: build\n :use_mocks: false\n" ) }
46
34
 
@@ -58,165 +46,6 @@ describe ConfiguratorValidator do
58
46
  end
59
47
  end
60
48
 
61
- describe '#validate_path_list' do
62
- let(:config) { config_from_yaml( ":paths:\n :test:\n - +:test/**\n - -:test/ignore\n - '**/generated'\n" ) }
63
-
64
- it 'checks each path stripped of its aggregation decorator and glob' do
65
- existing('test', 'test/ignore')
66
- expect(@validator.validate_path_list( config, :paths, :test )).to be true
67
- end
68
-
69
- it 'skips a path that begins with a glob' do
70
- existing('test', 'test/ignore')
71
- @validator.validate_path_list( config, :paths, :test )
72
- expect(@file_wrapper).to_not have_received(:exist?).with('')
73
- end
74
-
75
- it 'logs each path that does not exist' do
76
- existing('test')
77
- expect(@validator.validate_path_list( config, :paths, :test )).to be false
78
- expect(@loginator).to have_received(:log).with("Config path :paths ↳ :test => 'test/ignore' does not exist in the filesystem.", Verbosity::ERRORS)
79
- end
80
-
81
- it 'fails a missing entry' do
82
- expect(@validator.validate_path_list( config, :paths, :source )).to be false
83
- end
84
- end
85
-
86
- # An entry naming no path, or wrapping its path in quotes, is rejected before any
87
- # filesystem check. Both usually come from quoting only the path after a +: or -:
88
- # decoration, so each rejection carries a hint about quoting.
89
- shared_examples 'an entry that names no usable path' do |walk|
90
- {
91
- 'a bare subtractive decoration' => " - '-:'\n",
92
- 'a bare additive decoration' => " - '+:'\n",
93
- 'an empty string' => " - ''\n",
94
- 'whitespace alone' => " - ' '\n",
95
- 'a YAML null' => " -\n",
96
- }.each_pair do |label, yaml|
97
- it "rejects #{label} as naming no path, with a quoting hint" do
98
- expect(validate( yaml )).to be false
99
- expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '.*' names no path/, Verbosity::ERRORS)
100
- expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
101
- end
102
- end
103
-
104
- # YAML reads an unquoted decoration with nothing after it as a one-key mapping
105
- it 'rejects an entry YAML read as something other than a path, with a quoting hint' do
106
- expect(validate( " - -:\n" )).to be false
107
- expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '.*' is not a path \(YAML read it as a Hash\)/, Verbosity::ERRORS)
108
- expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
109
- end
110
-
111
- it 'rejects a path wrapped in quotes after its decoration, with a quoting hint' do
112
- expect(validate( " - '-:\"src/a.c\"'\n" )).to be false
113
- expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '-:"src\/a.c"' wraps its path in quotes/, Verbosity::ERRORS)
114
- expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
115
- end
116
- end
117
-
118
- describe '#validate_paths_entries' do
119
- def validate(yaml_list)
120
- @validator.validate_paths_entries( config_from_yaml( ":paths:\n :source:\n#{yaml_list}" ), :source )
121
- end
122
-
123
- it 'accepts a glob that yields directories' do
124
- existing; directories('src', 'src/a')
125
- allow(@file_wrapper).to receive(:directory_listing).with('src/**/**').and_return(['src', 'src/a', 'src/a/x.c'])
126
-
127
- expect(validate( " - src/**\n" )).to be true
128
- end
129
-
130
- it 'warns about and skips a path naming a file' do
131
- existing('src/main.c'); directories
132
-
133
- expect(validate( " - src/main.c\n" )).to be true
134
- expect(@loginator).to have_received(:log).with(/'src\/main.c' is a filepath and will be ignored/, Verbosity::COMPLAIN)
135
- end
136
-
137
- it 'accepts a subdirectory glob of a directory that has no subdirectories' do
138
- existing; directories
139
- allow(@file_wrapper).to receive(:directory_listing).and_return([])
140
-
141
- expect(validate( " - src/*\n" )).to be true
142
- end
143
-
144
- it 'logs a path that yields no directories' do
145
- existing; directories
146
- allow(@file_wrapper).to receive(:directory_listing).and_return([])
147
-
148
- expect(validate( " - -:src/missing\n" )).to be false
149
- expect(@loginator).to have_received(:log).with(/'src\/missing' yielded no directories/, Verbosity::ERRORS)
150
- end
151
-
152
- it 'escapes literal brackets before globbing' do
153
- existing; directories('src/[legacy]')
154
- allow(@file_wrapper).to receive(:directory_listing).with('src/\[legacy\]').and_return(['src/[legacy]'])
155
-
156
- expect(validate( " - 'src/[legacy]'\n" )).to be true
157
- end
158
-
159
- it 'fails a missing entry' do
160
- expect(@validator.validate_paths_entries( { paths: {} }, :source )).to be false
161
- end
162
-
163
- it_behaves_like 'an entry that names no usable path', ':paths ↳ :source'
164
- end
165
-
166
- describe '#validate_files_entries' do
167
- def validate(yaml_list)
168
- @validator.validate_files_entries( config_from_yaml( ":files:\n :source:\n#{yaml_list}" ), :source )
169
- end
170
-
171
- it 'accepts a glob that yields files' do
172
- existing; directories
173
- allow(@file_wrapper).to receive(:instantiate_file_list).with('src/*.c').and_return(['src/a.c'])
174
-
175
- expect(validate( " - +:src/*.c\n" )).to be true
176
- end
177
-
178
- it 'warns about and skips a path naming a directory' do
179
- existing('src'); directories('src')
180
-
181
- expect(validate( " - src\n" )).to be true
182
- expect(@loginator).to have_received(:log).with(/'src' is a directory path and will be ignored/, Verbosity::COMPLAIN)
183
- end
184
-
185
- it 'logs a glob that yields no files' do
186
- existing; directories
187
- allow(@file_wrapper).to receive(:instantiate_file_list).and_return([])
188
-
189
- expect(validate( " - src/*.x\n" )).to be false
190
- expect(@loginator).to have_received(:log).with(/'src\/\*.x' yielded no files/, Verbosity::ERRORS)
191
- end
192
-
193
- it 'escapes literal brackets before globbing' do
194
- existing; directories
195
- allow(@file_wrapper).to receive(:instantiate_file_list).with('src/\[legacy\]/*.c').and_return(['src/[legacy]/a.c'])
196
-
197
- expect(validate( " - 'src/[legacy]/*.c'\n" )).to be true
198
- end
199
-
200
- it 'fails a missing entry' do
201
- expect(@validator.validate_files_entries( { files: {} }, :source )).to be false
202
- end
203
-
204
- it_behaves_like 'an entry that names no usable path', ':files ↳ :source'
205
- end
206
-
207
- describe '#validate_filepath_simple' do
208
- it 'accepts an existing path' do
209
- existing('helper.h')
210
- expect(@validator.validate_filepath_simple( 'helper.h', :cmock, :unity_helper_path )).to be true
211
- end
212
-
213
- it 'logs a missing path with the configuration walk it came from' do
214
- existing
215
- expect(@validator.validate_filepath_simple( 'helper.h', :cmock, :unity_helper_path )).to be false
216
- expect(@loginator).to have_received(:log).with("Config path 'helper.h' associated with :cmock ↳ :unity_helper_path does not exist in the filesystem.", Verbosity::ERRORS)
217
- end
218
- end
219
-
220
49
  describe '#validate_tool' do
221
50
  let(:config) { { tools: { test_compiler: { executable: 'gcc' } }, extension: { executable: '.out' } } }
222
51