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.
- checksums.yaml +4 -4
- data/GIT_COMMIT_SHA +1 -1
- data/README.md +11 -9
- data/Rakefile +2 -1
- data/assets/features/ceedling +1 -1
- data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_typo.c +14 -0
- data/assets/fixtures/tests_with_duplicate_test_names/test_foo.c +21 -0
- data/bin/actionator.rb +6 -12
- data/bin/app_cfg.rb +14 -1
- data/bin/ceedling +13 -3
- data/bin/cli.rb +25 -6
- data/bin/cli_handler.rb +113 -73
- data/bin/cli_helper.rb +51 -78
- data/bin/installation_selector.rb +81 -0
- data/bin/launchinator.rb +69 -0
- data/bin/mixin_resolvinator.rb +26 -36
- data/bin/objects.yml +13 -0
- data/bin/path_validator.rb +25 -29
- data/bin/versionator.rb +47 -48
- data/ceedling.gemspec +19 -15
- data/docs/BreakingChanges.md +70 -1
- data/docs/Changelog.md +74 -3
- data/docs/KnownIssues.md +90 -4
- data/docs/ReleaseNotes.md +13 -0
- data/lib/ceedling/build_log_writer.rb +33 -0
- data/lib/ceedling/config/build_root_policy.rb +70 -0
- data/lib/ceedling/config/configurator.rb +14 -16
- data/lib/ceedling/config/configurator_builder.rb +58 -28
- data/lib/ceedling/config/configurator_paths_validator.rb +179 -0
- data/lib/ceedling/config/configurator_plugins.rb +1 -1
- data/lib/ceedling/config/configurator_setup.rb +15 -28
- data/lib/ceedling/config/configurator_validator.rb +1 -110
- data/lib/ceedling/defaults.rb +4 -4
- data/lib/ceedling/dependencies/README.md +18 -16
- data/lib/ceedling/dependencies/dependency_cache_store.rb +20 -3
- data/lib/ceedling/dependencies/dependency_hasher.rb +35 -1
- data/lib/ceedling/filename_extension.rb +7 -1
- data/lib/ceedling/filesystem/FILE_TREE.md +253 -0
- data/lib/ceedling/filesystem/PATH_HANDLING.md +304 -0
- data/lib/ceedling/filesystem/README.md +41 -0
- data/lib/ceedling/filesystem/build_subpath.rb +102 -0
- data/lib/ceedling/filesystem/destination_collision.rb +25 -0
- data/lib/ceedling/{file_finder.rb → filesystem/file_finder.rb} +159 -104
- data/lib/ceedling/{file_finder_helper.rb → filesystem/file_finder_helper.rb} +36 -31
- data/lib/ceedling/filesystem/file_path_collection_utils.rb +183 -0
- data/lib/ceedling/{file_path_utils.rb → filesystem/file_path_utils.rb} +108 -97
- data/lib/ceedling/{file_system_wrapper.rb → filesystem/file_system_wrapper.rb} +6 -5
- data/lib/ceedling/filesystem/file_tree.rb +241 -0
- data/lib/ceedling/{file_wrapper.rb → filesystem/file_wrapper.rb} +45 -38
- data/lib/ceedling/filesystem/path_exclusions.rb +30 -0
- data/lib/ceedling/{path_matcher.rb → filesystem/path_matcher.rb} +27 -23
- data/lib/ceedling/{path_mirror.rb → filesystem/path_mirror.rb} +19 -18
- data/lib/ceedling/filesystem/path_spellings.rb +55 -0
- data/lib/ceedling/filesystem/project_paths.rb +184 -0
- data/lib/ceedling/filesystem/working_dir.rb +40 -0
- data/lib/ceedling/generators/generator.rb +5 -6
- data/lib/ceedling/generators/generator_partials.rb +1 -1
- data/lib/ceedling/generators/generator_test_results_backtrace.rb +7 -7
- data/lib/ceedling/handoff.rb +121 -0
- data/lib/ceedling/includes/include_factory.rb +3 -3
- data/lib/ceedling/includes/include_pathinator.rb +67 -10
- data/lib/ceedling/includes/includes.rb +1 -1
- data/lib/ceedling/installation.rb +92 -0
- data/lib/ceedling/library_resolver.rb +99 -0
- data/lib/ceedling/objects.yml +23 -2
- data/lib/ceedling/partials/partializer.rb +4 -4
- data/lib/ceedling/partials/partializer_config.rb +3 -1
- data/lib/ceedling/plugins/report_log_writer_plugin.rb +3 -5
- data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +1 -1
- data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +1 -1
- data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +1 -1
- data/lib/ceedling/rake_app/rakefile_component_resolver.rb +10 -17
- data/lib/ceedling/rakefile.rb +15 -1
- data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
- data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
- data/lib/ceedling/release_invoker/release_build_executor.rb +33 -44
- data/lib/ceedling/release_invoker/release_build_planner.rb +14 -6
- data/lib/ceedling/reportinator.rb +3 -4
- data/lib/ceedling/setupinator.rb +94 -90
- data/lib/ceedling/test_context_extractor.rb +5 -1
- data/lib/ceedling/test_invoker/PIPELINE.md +9 -7
- data/lib/ceedling/test_invoker/mock_locator.rb +60 -2
- data/lib/ceedling/test_invoker/partials_manager.rb +12 -0
- data/lib/ceedling/test_invoker/standin_headerinator.rb +22 -13
- data/lib/ceedling/test_invoker/test_build_executor.rb +24 -40
- data/lib/ceedling/test_invoker/test_build_planner.rb +37 -18
- data/lib/ceedling/test_invoker/test_build_setup.rb +17 -12
- data/lib/ceedling/test_invoker/test_build_validations.rb +16 -31
- data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +1 -1
- data/lib/ceedling/test_invoker/test_invoker.rb +6 -1
- data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +1 -1
- data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +40 -20
- data/lib/ceedling/tool_executor.rb +9 -3
- data/lib/ceedling/yaml_wrapper.rb +3 -2
- data/lib/version.rb +1 -1
- data/plugins/bullseye/config/defaults_bullseye.rb +1 -1
- data/plugins/bullseye/lib/bullseye.rb +9 -7
- data/plugins/cppcheck/config/defaults_cppcheck.rb +1 -1
- data/plugins/dependencies/config/defaults.yml +6 -6
- data/plugins/dependencies/dependencies.rake +4 -1
- data/plugins/dependencies/lib/dependencies.rb +18 -8
- data/plugins/dependencies/lib/dependency_spec.rb +17 -5
- data/plugins/fff/lib/fff.rb +45 -39
- data/plugins/fff/spec/fff_cmock_wrapper_spec.rb +128 -0
- data/plugins/gcov/config/defaults_gcov.rb +1 -1
- data/plugins/gcov/lib/console_reportinator.rb +4 -18
- data/plugins/gcov/lib/gcov.rb +9 -2
- data/plugins/gcov/lib/gcovr_reportinator.rb +8 -40
- data/plugins/gcov/lib/gcovr_thresholds.rb +74 -0
- data/plugins/gcov/lib/reportgenerator_reportinator.rb +1 -1
- data/plugins/module_generator/lib/module_generator.rb +3 -3
- data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +53 -80
- data/plugins/sanitize/lib/sanitize_records.rb +3 -6
- data/plugins/valgrind/lib/valgrind.rb +14 -7
- data/site-local/configuration/reference/cmock.html +2 -1
- data/site-local/configuration/reference/files.html +9 -3
- data/site-local/configuration/reference/libraries.html +21 -3
- data/site-local/configuration/reference/paths.html +29 -6
- data/site-local/configuration/reference/project.html +17 -7
- data/site-local/configuration/reference/release-build.html +2 -0
- data/site-local/configuration/reference/tools.html +9 -0
- data/site-local/configuration/which-ceedling.html +377 -17
- data/site-local/development/releases.html +5 -1
- data/site-local/development/workflow.html +48 -43
- data/site-local/getting-started/builds.html +2 -0
- data/site-local/getting-started/command-line.html +56 -4
- data/site-local/plugins/dependencies.html +6 -3
- data/site-local/plugins/fff.html +42 -11
- data/site-local/plugins/gcov/gcovr.html +15 -12
- data/site-local/plugins/gcov/setup.html +2 -1
- data/site-local/plugins/report-tests-raw-output-log.html +3 -1
- data/site-local/plugins/report-tests-teamcity-stdout.html +6 -3
- data/site-local/plugins/sanitize.html +7 -6
- data/site-local/plugins/valgrind.html +8 -7
- data/site-local/project/upgrade.html +3 -0
- data/site-local/reference/command-line.html +9 -2
- data/site-local/sitemap.xml.gz +0 -0
- data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +1 -1
- data/site-local/snapshot/plugins/gcov/config/defaults_gcov.rb +1 -1
- data/site-local/testing-guide/conventions.html +53 -0
- data/spec/integration/actionator_file_operations_spec.rb +91 -1
- data/spec/integration/compile_commands_json_db_spec.rb +1 -1
- data/spec/integration/configurator_validation_spec.rb +1 -1
- data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +26 -0
- data/spec/integration/dependencies/dependency_tracker_core_spec.rb +22 -0
- data/spec/integration/launcher_handoff_spec.rb +297 -0
- data/spec/integration/mixin_loading_spec.rb +1 -1
- data/spec/integration/module_generator_spec.rb +3 -3
- data/spec/integration/nested_test_artifacts_spec.rb +99 -0
- data/spec/integration/partials_module_resolution_spec.rb +7 -4
- data/spec/integration/path_intake_scenarios_spec.rb +101 -0
- data/spec/integration/path_scenarios_spec.rb +322 -0
- data/spec/integration/quote_include_isolator_spec.rb +1 -1
- data/spec/integration/report_build_warnings_log_spec.rb +1 -1
- data/spec/integration/report_tests_log_factory_spec.rb +1 -1
- data/spec/integration/test_executable_manifest_spec.rb +1 -1
- data/spec/integration/test_includes_extractinator_spec.rb +2 -1
- data/spec/integration/test_naming_spec.rb +198 -0
- data/spec/integration/test_source_file_checks_spec.rb +166 -0
- data/spec/integration/tool_validator_spec.rb +1 -1
- data/spec/integration/upgrade_docs_spec.rb +84 -0
- data/spec/integration/vendor_copy_transient_io_retry_spec.rb +74 -5
- data/spec/support/file_tree_helper.rb +88 -0
- data/spec/support/integration/configurator_integration_helper.rb +6 -6
- data/spec/support/integration/dependency_tracker_integration_helper.rb +1 -1
- data/spec/support/integration/partials_generation_integration_helper.rb +2 -2
- data/spec/support/integration/path_scenario_harness.rb +173 -0
- data/spec/support/integration/spec_integration_helper.rb +1 -1
- data/spec/support/integration/test_includes_harness.rb +13 -2
- data/spec/support/spec_helper.rb +2 -0
- data/spec/support/system/spec_system_helper.rb +7 -6
- data/spec/support/system/system_context.rb +21 -3
- data/spec/support/working_dir_tracking.rb +49 -0
- data/spec/system/build_output_mirroring_spec.rb +2 -2
- data/spec/system/conditional_mock_includes_spec.rb +1 -1
- data/spec/system/delta_builds_spec.rb +137 -11
- data/spec/system/gcov_deployment_spec.rb +1 -0
- data/spec/system/header_include_path_validation_spec.rb +4 -4
- data/spec/system/launcher_handoff_spec.rb +82 -0
- data/spec/system/mock_include_folders_spec.rb +91 -0
- data/spec/system/parent_directory_reference_spec.rb +5 -3
- data/spec/system/path_handling_probes_spec.rb +192 -0
- data/spec/system/preprocessing_parameterized_tests_spec.rb +1 -1
- data/spec/system/rake_release_task_path_disambiguation_spec.rb +6 -6
- data/spec/system/rake_test_task_path_disambiguation_spec.rb +85 -0
- data/spec/system/special_path_characters_spec.rb +86 -0
- data/spec/system/support/common_test_cases.rb +23 -21
- data/spec/system/support/gcov_common_test_cases.rb +37 -9
- data/spec/system/support/sanitize_common_test_cases.rb +2 -2
- data/spec/system/support/valgrind_common_test_cases.rb +12 -12
- data/spec/system/test_pipeline_stop_points_spec.rb +4 -4
- data/spec/system/test_runner_system_include_spec.rb +1 -1
- data/spec/system/test_source_file_directive_spec.rb +34 -5
- data/spec/units/bin/actionator_spec.rb +14 -17
- data/spec/units/bin/app_cfg_spec.rb +37 -0
- data/spec/units/bin/cli_handler_spec.rb +282 -6
- data/spec/units/bin/cli_helper_spec.rb +116 -45
- data/spec/units/bin/installation_selector_spec.rb +114 -0
- data/spec/units/bin/launchinator_spec.rb +171 -0
- data/spec/units/bin/path_validator_spec.rb +10 -0
- data/spec/units/bin/versionator_spec.rb +38 -6
- data/spec/units/build_log_writer_spec.rb +57 -0
- data/spec/units/config/build_root_policy_spec.rb +61 -0
- data/spec/units/config/configurator_builder_spec.rb +37 -6
- data/spec/units/config/configurator_paths_validator_spec.rb +292 -0
- data/spec/units/config/configurator_setup_spec.rb +9 -65
- data/spec/units/config/configurator_spec.rb +27 -5
- data/spec/units/config/configurator_validator_spec.rb +1 -172
- data/spec/units/default_tools_quoting_spec.rb +83 -0
- data/spec/units/dependencies/dependency_cache_store_spec.rb +33 -2
- data/spec/units/dependencies/dependency_debug_tree_spec.rb +1 -1
- data/spec/units/dependencies/dependency_hasher_spec.rb +42 -1
- data/spec/units/dependencies/dependency_path_normalizer_spec.rb +1 -1
- data/spec/units/dependencies/dependency_tracker_spec.rb +3 -1
- data/spec/units/filename_extension_spec.rb +11 -0
- data/spec/units/filesystem/build_subpath_spec.rb +122 -0
- data/spec/units/filesystem/destination_collision_spec.rb +30 -0
- data/spec/units/{file_finder_helper_spec.rb → filesystem/file_finder_helper_spec.rb} +46 -1
- data/spec/units/{file_finder_spec.rb → filesystem/file_finder_spec.rb} +188 -22
- data/spec/units/{file_path_collection_utils_spec.rb → filesystem/file_path_collection_utils_spec.rb} +181 -1
- data/spec/units/{file_path_utils_spec.rb → filesystem/file_path_utils_spec.rb} +204 -87
- data/spec/units/filesystem/file_system_wrapper_spec.rb +33 -0
- data/spec/units/filesystem/file_tree_spec.rb +511 -0
- data/spec/units/filesystem/file_tree_windows_spec.rb +78 -0
- data/spec/units/{file_wrapper_spec.rb → filesystem/file_wrapper_spec.rb} +95 -12
- data/spec/units/{path_matcher_spec.rb → filesystem/path_matcher_spec.rb} +12 -1
- data/spec/units/{path_mirror_spec.rb → filesystem/path_mirror_spec.rb} +32 -4
- data/spec/units/filesystem/project_paths_spec.rb +147 -0
- data/spec/units/filesystem/working_dir_spec.rb +71 -0
- data/spec/units/generators/generator_spec.rb +12 -6
- data/spec/units/generators/generator_test_results_backtrace_spec.rb +50 -46
- data/spec/units/generators/generator_test_results_spec.rb +1 -1
- data/spec/units/handoff_spec.rb +205 -0
- data/spec/units/includes/include_factory_spec.rb +3 -3
- data/spec/units/includes/include_pathinator_spec.rb +46 -0
- data/spec/units/installation_spec.rb +228 -0
- data/spec/units/library_resolver_spec.rb +157 -0
- data/spec/units/mock_locator_spec.rb +76 -1
- data/spec/units/partials/partializer_config_spec.rb +7 -0
- data/spec/units/partials/partializer_spec.rb +1 -0
- data/spec/units/partials_manager_spec.rb +17 -0
- data/spec/units/plugins/bullseye_spec.rb +15 -2
- data/spec/units/plugins/console_reportinator_spec.rb +18 -20
- data/spec/units/plugins/dependencies_spec.rb +33 -7
- data/spec/units/plugins/dependency_spec_spec.rb +17 -0
- data/spec/units/plugins/gcov_spec.rb +28 -3
- data/spec/units/plugins/gcovr_reportinator_spec.rb +19 -47
- data/spec/units/plugins/gcovr_thresholds_spec.rb +95 -0
- data/spec/units/plugins/module_generator_spec.rb +5 -5
- data/spec/units/plugins/report_build_warnings_log_spec.rb +3 -3
- data/spec/units/plugins/report_log_writer_plugin_spec.rb +10 -1
- data/spec/units/plugins/report_tests_raw_output_log_spec.rb +13 -2
- data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +77 -3
- data/spec/units/plugins/reportgenerator_reportinator_spec.rb +1 -1
- data/spec/units/plugins/sanitize_records_spec.rb +3 -1
- data/spec/units/plugins/sanitize_spec.rb +1 -1
- data/spec/units/plugins/valgrind_spec.rb +23 -8
- data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +1 -1
- data/spec/units/rake_app/rakefile_component_resolver_spec.rb +21 -0
- data/spec/units/release_build_executor_spec.rb +53 -14
- data/spec/units/release_build_planner_spec.rb +15 -3
- data/spec/units/reportinator_spec.rb +5 -5
- data/spec/units/standin_headerinator_spec.rb +31 -1
- data/spec/units/test_build_executor_spec.rb +65 -3
- data/spec/units/test_build_planner_spec.rb +104 -2
- data/spec/units/test_build_setup_spec.rb +96 -12
- data/spec/units/test_context_extractor_spec.rb +25 -0
- data/spec/units/test_file_preprocessinator_spec.rb +17 -1
- data/spec/units/test_includes_extractinator_spec.rb +5 -1
- data/spec/units/test_invoker/objects_wiring_spec.rb +6 -3
- data/spec/units/test_invoker_spec.rb +14 -1
- data/spec/units/test_source_file_directive_resolver_spec.rb +38 -7
- data/spec/units/tool_executor_spec.rb +26 -0
- data/spec/units/yaml_wrapper_spec.rb +11 -0
- metadata +109 -25
- data/lib/ceedling/file_path_collection_utils.rb +0 -164
|
@@ -29,7 +29,9 @@ class TestBuildExecutor
|
|
|
29
29
|
:dependinator,
|
|
30
30
|
:gcc_dependency_parser,
|
|
31
31
|
:quote_include_isolator,
|
|
32
|
-
:generator_helper
|
|
32
|
+
:generator_helper,
|
|
33
|
+
:library_resolver,
|
|
34
|
+
:mock_locator
|
|
33
35
|
)
|
|
34
36
|
|
|
35
37
|
# Stage 9: Preprocess header files to be mocked.
|
|
@@ -148,9 +150,10 @@ class TestBuildExecutor
|
|
|
148
150
|
details = mock.details
|
|
149
151
|
testable = mock.testable
|
|
150
152
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
placement = @mock_locator.placement( mocks_root: testable.paths[:mocks], subdir: details.path, include_path: details.include_path )
|
|
154
|
+
output_path = placement.directory
|
|
155
|
+
# The compiler reaches a climbing folder's mock only through CMock's root
|
|
156
|
+
@mock_locator.search_directories( placement ).each { |dir| @file_wrapper.mkdir( dir ) }
|
|
154
157
|
|
|
155
158
|
# `details.input` -- not the stage 9 preprocessed target -- is the
|
|
156
159
|
# correct antecedent here: it's exactly what CMock reads, whether or not
|
|
@@ -191,7 +194,8 @@ class TestBuildExecutor
|
|
|
191
194
|
test: testable.name,
|
|
192
195
|
input_filepath: details.input,
|
|
193
196
|
output_path: output_path,
|
|
194
|
-
|
|
197
|
+
mock_root: placement.root,
|
|
198
|
+
folder: placement.folder,
|
|
195
199
|
overrides: overrides
|
|
196
200
|
}
|
|
197
201
|
|
|
@@ -278,7 +282,8 @@ class TestBuildExecutor
|
|
|
278
282
|
# Stage 16: Link test executables.
|
|
279
283
|
def stage_build_executables(state)
|
|
280
284
|
lib_args = convert_libraries_to_arguments()
|
|
281
|
-
lib_paths =
|
|
285
|
+
lib_paths = @library_resolver.search_path_arguments()
|
|
286
|
+
libraries = @library_resolver.link_files( test_library_entries() )
|
|
282
287
|
skipped = 0
|
|
283
288
|
|
|
284
289
|
@batchinator.exec(workload: :compile, things: state.testables) do |_, testable|
|
|
@@ -287,10 +292,14 @@ class TestBuildExecutor
|
|
|
287
292
|
link_flags = testable.link_flags
|
|
288
293
|
tool, link_flags = resolve_link_tool( context: state.context, tool: @configurator.tools_test_linker, flags: link_flags, executable: testable.executable )
|
|
289
294
|
|
|
295
|
+
# Staleness checks only the files registered here, so an object or library dropped from
|
|
296
|
+
# the link (a source deleted, excluded, or moved out of the configured paths) changes
|
|
297
|
+
# nothing they see. The object and library lists as meta do change.
|
|
298
|
+
objects = testable.objects.to_a
|
|
290
299
|
@dependinator.register(
|
|
291
300
|
testable.executable,
|
|
292
|
-
files:
|
|
293
|
-
meta: { flags: link_flags, lib_args: lib_args, lib_paths: lib_paths, tools: [tool] }
|
|
301
|
+
files: objects + libraries,
|
|
302
|
+
meta: { flags: link_flags, lib_args: lib_args, lib_paths: lib_paths, tools: [tool], objects: objects, libraries: libraries }
|
|
294
303
|
)
|
|
295
304
|
stale = @dependinator.stale?( testable.executable )
|
|
296
305
|
|
|
@@ -380,11 +389,9 @@ class TestBuildExecutor
|
|
|
380
389
|
|
|
381
390
|
@batchinator.exec(workload: :test, things: state.testables) do |_, testable|
|
|
382
391
|
begin
|
|
383
|
-
# `paths[:results]` is
|
|
384
|
-
#
|
|
385
|
-
#
|
|
386
|
-
# must be test-specific too, matching clean_test_results' own `test + '.*'`
|
|
387
|
-
# naming below.
|
|
392
|
+
# `paths[:results]` is the directory of the test's name, which every test beside
|
|
393
|
+
# it shares, so the marker's own filename must be test-specific too, matching
|
|
394
|
+
# clean_test_results' own `test + '.*'` naming below.
|
|
388
395
|
fixture_target = File.join( testable.paths[:results], "#{File.basename( testable.name )}.fixture_run" )
|
|
389
396
|
|
|
390
397
|
fixture_tool = resolve_fixture_tool( context: state.context, tool: @configurator.tools_test_fixture, test_name: testable.name, target: fixture_target )
|
|
@@ -546,41 +553,18 @@ class TestBuildExecutor
|
|
|
546
553
|
end
|
|
547
554
|
|
|
548
555
|
def convert_libraries_to_arguments()
|
|
549
|
-
args = (
|
|
556
|
+
args = test_library_entries()
|
|
550
557
|
if (defined? LIBRARIES_FLAG)
|
|
551
558
|
args.map! { |v| LIBRARIES_FLAG.gsub( /\$\{1\}/, v ) }
|
|
552
559
|
end
|
|
553
560
|
return args
|
|
554
561
|
end
|
|
555
562
|
|
|
556
|
-
def get_library_paths_to_arguments()
|
|
557
|
-
paths = (defined? PATHS_LIBRARIES) ? (PATHS_LIBRARIES || []).clone : []
|
|
558
|
-
if (defined? LIBRARIES_PATH_FLAG)
|
|
559
|
-
paths.map! { |v| LIBRARIES_PATH_FLAG.gsub( /\$\{1\}/, v ) }
|
|
560
|
-
end
|
|
561
|
-
return paths
|
|
562
|
-
end
|
|
563
|
-
|
|
564
563
|
private
|
|
565
564
|
|
|
566
|
-
#
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
# its calls by the same #include. Two same-named mocks stay distinct only if the folder
|
|
570
|
-
# reaches CMock. CMock writes below its own root at that folder, so the folder must end the
|
|
571
|
-
# mock's directory. A folder trailing the mirrored location keeps that location. An #include
|
|
572
|
-
# spelling more path than the mirror holds moves its mock below the per-test root at the
|
|
573
|
-
# written path, which the root search path still reaches. A bare #include has no folder.
|
|
574
|
-
# Without :mock_name_include_folder no folder is passed, and CMock names by filename alone.
|
|
575
|
-
def mock_folder_and_path(mocks_root, output_path, include_path)
|
|
576
|
-
return [nil, output_path] unless @configurator.cmock_mock_name_include_folder
|
|
577
|
-
|
|
578
|
-
folder = File.dirname( include_path.to_s ).sub( %r{\A(?:\./)+}, '' )
|
|
579
|
-
|
|
580
|
-
return [nil, output_path] if folder.empty? || folder == '.'
|
|
581
|
-
return [folder, output_path] if output_path.end_with?( File.join( '', folder ) )
|
|
582
|
-
|
|
583
|
-
return [folder, File.join( mocks_root, folder )]
|
|
565
|
+
# The :libraries entries a test links, whatever form each takes
|
|
566
|
+
def test_library_entries()
|
|
567
|
+
return ((@configurator.project_config_hash[:libraries_test] || []) + ((defined? LIBRARIES_SYSTEM) ? LIBRARIES_SYSTEM : [])).flatten
|
|
584
568
|
end
|
|
585
569
|
|
|
586
570
|
# Compile a single C or assembly source file into an object file. Returns
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
|
+
require 'ceedling/filesystem/project_paths'
|
|
9
10
|
require 'ceedling/test_invoker/test_invoker_types'
|
|
10
11
|
require 'ceedling/test_invoker/test_pipeline_helpers'
|
|
11
12
|
require 'ceedling/test_invoker/test_build_validations'
|
|
@@ -48,6 +49,10 @@ class TestBuildPlanner
|
|
|
48
49
|
mocks = {}
|
|
49
50
|
_mocks = @context_extractor.lookup_mock_header_includes_list( filepath )
|
|
50
51
|
|
|
52
|
+
# Built at the first real mock and shared by the rest, since nothing here changes
|
|
53
|
+
# this test's search paths
|
|
54
|
+
collection = nil
|
|
55
|
+
|
|
51
56
|
_mocks.each do |include|
|
|
52
57
|
name = File.basename( include.filename ).ext()
|
|
53
58
|
source = nil
|
|
@@ -60,7 +65,8 @@ class TestBuildPlanner
|
|
|
60
65
|
input = source
|
|
61
66
|
subdir = partial_mock_subdir( include )
|
|
62
67
|
else
|
|
63
|
-
|
|
68
|
+
collection ||= ordered_mock_header_collection( testable )
|
|
69
|
+
source, subdir = @mock_locator.locate( include, collection: collection )
|
|
64
70
|
preprocessed_input = @file_path_utils.form_preprocessed_file_filepath( source, test )
|
|
65
71
|
input = (@configurator.project_use_test_preprocessor_mocks ? preprocessed_input : source)
|
|
66
72
|
end
|
|
@@ -72,11 +78,11 @@ class TestBuildPlanner
|
|
|
72
78
|
# the mock stays findable by the compiler regardless
|
|
73
79
|
# of how much path the #include itself happened to spell out.
|
|
74
80
|
#
|
|
75
|
-
# Keyed by
|
|
76
|
-
# two modules, each needing its own mock, and a key of the
|
|
77
|
-
# second displace the first. `name` stays bare: it is the
|
|
78
|
-
# written under,
|
|
79
|
-
mocks[mock_key( name, subdir )] = MockDetails.new(
|
|
81
|
+
# Keyed by the directory the mock is written to alongside the name. Two modules
|
|
82
|
+
# sharing a basename are two modules, each needing its own mock, and a key of the
|
|
83
|
+
# name alone lets the second displace the first. `name` stays bare: it is the
|
|
84
|
+
# filename the mock is written under, at generation.
|
|
85
|
+
mocks[mock_key( name, partial ? subdir : placed_subdir( testable, subdir, include ) )] = MockDetails.new(
|
|
80
86
|
name: name,
|
|
81
87
|
filepath: source,
|
|
82
88
|
path: subdir,
|
|
@@ -185,7 +191,7 @@ class TestBuildPlanner
|
|
|
185
191
|
test_no_link_objects =
|
|
186
192
|
@file_path_utils.form_test_build_objects_filelist(
|
|
187
193
|
testable.paths[:build],
|
|
188
|
-
fetch_shallow_source_includes( filepath ),
|
|
194
|
+
fetch_shallow_source_includes( filepath, state.context, testable.name ),
|
|
189
195
|
extra_roots: generated_roots
|
|
190
196
|
)
|
|
191
197
|
|
|
@@ -237,10 +243,11 @@ class TestBuildPlanner
|
|
|
237
243
|
sources << File.join( PROJECT_BUILD_VENDOR_CEXCEPTION_PATH, CEXCEPTION_C_FILE ) if @configurator.project_use_exceptions
|
|
238
244
|
|
|
239
245
|
if @configurator.project_use_mocks
|
|
246
|
+
# :unity_helper_path names a helper's header, or its path without an extension. The
|
|
247
|
+
# source beside it is what compiles.
|
|
240
248
|
@configurator.cmock_unity_helper_path.each do |helper|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
end
|
|
249
|
+
source = helper.ext( EXTENSION_SOURCE.primary )
|
|
250
|
+
sources << source if @file_wrapper.exist?( source )
|
|
244
251
|
end
|
|
245
252
|
end
|
|
246
253
|
|
|
@@ -313,8 +320,12 @@ class TestBuildPlanner
|
|
|
313
320
|
)
|
|
314
321
|
end
|
|
315
322
|
|
|
316
|
-
|
|
317
|
-
|
|
323
|
+
# The sources a test #includes, which it must not link a second time. Each is the file its
|
|
324
|
+
# #include names, since that file's object sits at its own path, not the #include's.
|
|
325
|
+
def fetch_shallow_source_includes(test_filepath, context, test_name)
|
|
326
|
+
return @test_context_extractor.lookup_source_includes_list( test_filepath ).map do |include|
|
|
327
|
+
@file_finder.find_build_input_file( filepath: include.filepath, complain: :ignore, context: context, test: test_name ) || include.filepath
|
|
328
|
+
end
|
|
318
329
|
end
|
|
319
330
|
|
|
320
331
|
# Every stage resolving a mock's real header must agree on the same winner, or a
|
|
@@ -323,6 +334,16 @@ class TestBuildPlanner
|
|
|
323
334
|
@mock_locator.header_collection( testable.search_paths, testable.mock_search_paths )
|
|
324
335
|
end
|
|
325
336
|
|
|
337
|
+
# The mock's directory below its test's mock root, where generation writes it. Two
|
|
338
|
+
# same-named headers may mirror alike and differ only by the folders their #includes name.
|
|
339
|
+
def placed_subdir(testable, subdir, include)
|
|
340
|
+
root = testable.paths[:mocks]
|
|
341
|
+
return subdir if root.nil?
|
|
342
|
+
|
|
343
|
+
placement = @mock_locator.placement( mocks_root: root, subdir: subdir, include_path: include.filepath )
|
|
344
|
+
return ProjectPaths.subdir_below( root, placement.directory ) || subdir
|
|
345
|
+
end
|
|
346
|
+
|
|
326
347
|
# One mock's identity within its test. A mock directly in the mock root keeps the bare
|
|
327
348
|
# name it has always had, so nothing changes for a project without same-named mocks.
|
|
328
349
|
def mock_key(name, subdir)
|
|
@@ -331,8 +352,8 @@ class TestBuildPlanner
|
|
|
331
352
|
return File.join( subdir, name ).to_sym
|
|
332
353
|
end
|
|
333
354
|
|
|
334
|
-
# Each mock's own generated source, below this test's mock root
|
|
335
|
-
#
|
|
355
|
+
# Each mock's own generated source, below this test's mock root where mock generation
|
|
356
|
+
# writes it (MockLocator#placement)
|
|
336
357
|
#
|
|
337
358
|
# Named by its own path rather than its basename so two same-named mocks in one test
|
|
338
359
|
# stay distinct, and so each one's object mirrors that subdirectory too.
|
|
@@ -342,10 +363,8 @@ class TestBuildPlanner
|
|
|
342
363
|
return [] if root.nil?
|
|
343
364
|
|
|
344
365
|
testable.mocks.each_value.map do |details|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
details.name + EXTENSION_CORE_SOURCE
|
|
348
|
-
)
|
|
366
|
+
placement = @mock_locator.placement( mocks_root: root, subdir: details.path, include_path: details.include_path )
|
|
367
|
+
File.join( placement.directory, details.name + EXTENSION_CORE_SOURCE )
|
|
349
368
|
end
|
|
350
369
|
end
|
|
351
370
|
|
|
@@ -13,7 +13,6 @@ require 'ceedling/partials/partials'
|
|
|
13
13
|
require 'ceedling/test_invoker/test_invoker_types'
|
|
14
14
|
require 'ceedling/test_invoker/test_pipeline_helpers'
|
|
15
15
|
require 'ceedling/test_invoker/test_build_validations'
|
|
16
|
-
require 'ceedling/path_mirror'
|
|
17
16
|
|
|
18
17
|
class TestBuildSetup
|
|
19
18
|
|
|
@@ -36,7 +35,8 @@ class TestBuildSetup
|
|
|
36
35
|
:test_runner_manager,
|
|
37
36
|
:dependinator,
|
|
38
37
|
:test_search_paths,
|
|
39
|
-
:mock_locator
|
|
38
|
+
:mock_locator,
|
|
39
|
+
:test_source_file_directive_resolver
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
def setup()
|
|
@@ -44,14 +44,15 @@ class TestBuildSetup
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# Stage 1: Create per-test build/results/mock/partial directory structure
|
|
47
|
-
# and populate the testables hash with initial entries.
|
|
47
|
+
# and populate the testables hash with initial entries. Stops first if two
|
|
48
|
+
# tests in the build share a name.
|
|
48
49
|
def stage_prepare_build_paths(state)
|
|
49
|
-
|
|
50
|
+
validate_unique_test_names!( tests: state.tests )
|
|
50
51
|
|
|
51
52
|
@batchinator.exec(workload: :compile, things: state.tests) do |filepath|
|
|
52
53
|
filepath = filepath.to_s
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
name = @file_path_utils.form_test_name( filepath )
|
|
55
|
+
key = name.to_sym
|
|
55
56
|
|
|
56
57
|
state.lock.synchronize do
|
|
57
58
|
state.testables[key] = Testable.new(
|
|
@@ -114,8 +115,10 @@ class TestBuildSetup
|
|
|
114
115
|
filepath = testable.filepath
|
|
115
116
|
filename = File.basename( filepath )
|
|
116
117
|
|
|
118
|
+
# Only a scan without test preprocessing finds TEST_SOURCE_FILE() entries, so a cache
|
|
119
|
+
# from the other mode is stale
|
|
117
120
|
cache_target = @file_path_utils.form_test_build_directives_cache_filepath( filepath, testable.name )
|
|
118
|
-
@dependinator.register( cache_target, files: [filepath] )
|
|
121
|
+
@dependinator.register( cache_target, files: [filepath], meta: { source_files_scanned: !@configurator.project_use_test_preprocessor_tests } )
|
|
119
122
|
directives_stale = @dependinator.stale?( cache_target )
|
|
120
123
|
|
|
121
124
|
contexts = [TestContextExtractor::Context::INCLUDES]
|
|
@@ -167,6 +170,8 @@ class TestBuildSetup
|
|
|
167
170
|
state.lock.synchronize { skipped += 1 }
|
|
168
171
|
end
|
|
169
172
|
|
|
173
|
+
validate_source_file_directives( testable, state.context )
|
|
174
|
+
|
|
170
175
|
validate_mocks_in_use(
|
|
171
176
|
filename: filename,
|
|
172
177
|
mocks: @context_extractor.lookup_mock_header_includes_list( filepath )
|
|
@@ -321,12 +326,12 @@ class TestBuildSetup
|
|
|
321
326
|
|
|
322
327
|
private
|
|
323
328
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
329
|
+
# Without test preprocessing, stage 11 never runs, and only stage 2's scan finds a test's
|
|
330
|
+
# TEST_SOURCE_FILE() entries
|
|
331
|
+
def validate_source_file_directives(testable, context)
|
|
332
|
+
return if @configurator.project_use_test_preprocessor_tests
|
|
328
333
|
|
|
329
|
-
|
|
334
|
+
@test_source_file_directive_resolver.validate!( test: testable.name, test_filepath: testable.filepath, context: context )
|
|
330
335
|
end
|
|
331
336
|
|
|
332
337
|
end
|
|
@@ -5,15 +5,29 @@
|
|
|
5
5
|
# SPDX-License-Identifier: MIT
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
|
+
require 'ceedling/filesystem/destination_collision'
|
|
9
|
+
|
|
8
10
|
# Test-build configuration validators shared by more than one test pipeline stage
|
|
9
11
|
# class -- each raises CeedlingException on a real, user-facing mistake it's
|
|
10
|
-
# positioned to catch (a project using mocking
|
|
11
|
-
#
|
|
12
|
+
# positioned to catch (a project using mocking or Partials without configuring for
|
|
13
|
+
# it, a header that doesn't actually resolve, or two tests sharing one name).
|
|
12
14
|
# Relies on whichever including class's own constructor DI already provides the
|
|
13
15
|
# collaborators a given validator needs, the same way TestPipelineHelpers is
|
|
14
16
|
# mixed in without any DI wiring of its own.
|
|
15
17
|
module TestBuildValidations
|
|
16
18
|
|
|
19
|
+
# A name is its test's path without its extension, so two tests share one only when they
|
|
20
|
+
# differ in extension alone (`test_a.c` and `test_a.cpp`). Sharing would silently drop one
|
|
21
|
+
# test, so a build with them in it stops. A build without them is unaffected.
|
|
22
|
+
def validate_unique_test_names!(tests:)
|
|
23
|
+
shared = DestinationCollision.find( @configurator.collection_all_tests.map( &:to_s ) ) { |test| @file_path_utils.form_test_name( test ) }
|
|
24
|
+
|
|
25
|
+
tests.each do |test|
|
|
26
|
+
name = @file_path_utils.form_test_name( test )
|
|
27
|
+
DestinationCollision.raise_for( name, shared[name], 'share the build name' ) if shared.key?( name )
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
17
31
|
def validate_mocks_in_use(filename:, mocks:)
|
|
18
32
|
if !@configurator.project_use_mocks and !mocks.empty?
|
|
19
33
|
_mocks = mocks.map { |include| include.filename }
|
|
@@ -70,33 +84,4 @@ module TestBuildValidations
|
|
|
70
84
|
end
|
|
71
85
|
end
|
|
72
86
|
|
|
73
|
-
# A TEST_SOURCE_FILE() entry must name a real, recognized file whether it
|
|
74
|
-
# adds or removes -- a typo or a nonexistent path is worth failing loudly
|
|
75
|
-
# on either side of the +:/-: convention, the same way a missing file has
|
|
76
|
-
# always been treated for a plain, additive entry.
|
|
77
|
-
def validate!(test:, filepath:)
|
|
78
|
-
sources = @test_context_extractor.lookup_build_directive_sources_list( filepath )
|
|
79
|
-
|
|
80
|
-
ext_message = @configurator.extension_source.to_s
|
|
81
|
-
ext_message += " or #{@configurator.extension_assembly}" if @configurator.test_build_use_assembly
|
|
82
|
-
|
|
83
|
-
sources.each do |raw_source|
|
|
84
|
-
source = FilePathUtils.no_aggregation_decorators( raw_source )
|
|
85
|
-
valid_extension =
|
|
86
|
-
if @configurator.test_build_use_assembly
|
|
87
|
-
@configurator.extension_assembly.match?( source ) || @configurator.extension_source.match?( source )
|
|
88
|
-
else
|
|
89
|
-
@configurator.extension_source.match?( source )
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
unless valid_extension
|
|
93
|
-
raise CeedlingException.new( "File '#{source}' specified with TEST_SOURCE_FILE() in #{test} is not a #{ext_message} source file" )
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
if @file_finder.find_build_input_file( filepath: source, complain: :ignore, context: TEST_SYM ).nil?
|
|
97
|
-
raise CeedlingException.new( "File '#{source}' specified with TEST_SOURCE_FILE() in #{test} cannot be found in the source file collection" )
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
87
|
end
|
|
@@ -50,7 +50,7 @@ class TestFilePreprocessinator
|
|
|
50
50
|
state.lock.synchronize { skipped += 1 } unless stale
|
|
51
51
|
|
|
52
52
|
stale ? scan_source_directives( testable ) : recall_source_directives( testable )
|
|
53
|
-
|
|
53
|
+
@test_source_file_directive_resolver.validate!( test: testable.name, test_filepath: testable.filepath, context: state.context )
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
log_skip_summary( task: "test file preprocessing", count: skipped, noun: "test files" )
|
|
@@ -22,7 +22,8 @@ class TestInvoker
|
|
|
22
22
|
:dependinator,
|
|
23
23
|
:loginator,
|
|
24
24
|
:verbosinator,
|
|
25
|
-
:test_pipeline_manager
|
|
25
|
+
:test_pipeline_manager,
|
|
26
|
+
:include_pathinator
|
|
26
27
|
)
|
|
27
28
|
|
|
28
29
|
def setup
|
|
@@ -40,6 +41,10 @@ class TestInvoker
|
|
|
40
41
|
timestamp_s = SystemWrapper.time_stopwatch_s()
|
|
41
42
|
@plugin_manager.pre_test_build( context, timestamp_s )
|
|
42
43
|
|
|
44
|
+
# After the hook, so a header it writes is listed, and once per run, so a later run in
|
|
45
|
+
# the same process lists every search path afresh
|
|
46
|
+
@include_pathinator.forget_header_listings
|
|
47
|
+
|
|
43
48
|
# `identifier: context` isolates this run's own cache file (see Dependinator#open) --
|
|
44
49
|
# a plugin building its own variant of the test pipeline under a distinct context
|
|
45
50
|
# (:gcov, :valgrind, ...) gets its own cache automatically, never sharing one with
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# SPDX-License-Identifier: MIT
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
|
-
require 'ceedling/path_mirror'
|
|
8
|
+
require 'ceedling/filesystem/path_mirror'
|
|
9
9
|
|
|
10
10
|
# Small helpers shared by more than one test pipeline stage class. Relies on
|
|
11
11
|
# `@reportinator`/`@loginator` already being present via whichever including
|
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
9
|
require 'ceedling/exceptions'
|
|
10
|
-
require 'ceedling/file_path_utils'
|
|
11
|
-
require 'ceedling/path_matcher'
|
|
12
|
-
require 'ceedling/test_invoker/test_build_validations'
|
|
10
|
+
require 'ceedling/filesystem/file_path_utils'
|
|
11
|
+
require 'ceedling/filesystem/path_matcher'
|
|
13
12
|
|
|
14
13
|
# Owns everything about the TEST_SOURCE_FILE() build directive's own path
|
|
15
14
|
# content: collecting a test's raw directive strings, telling additive
|
|
@@ -20,8 +19,6 @@ require 'ceedling/test_invoker/test_build_validations'
|
|
|
20
19
|
# becomes a real filepath.
|
|
21
20
|
class TestSourceFileDirectiveResolver
|
|
22
21
|
|
|
23
|
-
include TestBuildValidations
|
|
24
|
-
|
|
25
22
|
constructor :test_context_extractor, :file_finder, :configurator, :loginator
|
|
26
23
|
|
|
27
24
|
# Splits a test's TEST_SOURCE_FILE() entries into files to add and files to
|
|
@@ -33,31 +30,33 @@ class TestSourceFileDirectiveResolver
|
|
|
33
30
|
def resolve(test_filepath, context)
|
|
34
31
|
raw = @test_context_extractor.lookup_build_directive_sources_list( test_filepath )
|
|
35
32
|
additive, subtractive = raw.partition { |source| FilePathUtils.add_path?( source ) }
|
|
36
|
-
|
|
37
|
-
# A directive's own text is written directly in the test file, so its `..`, if
|
|
38
|
-
# any, is anchored to that same test file's own directory -- exactly as a
|
|
39
|
-
# directory-relative #include would be.
|
|
40
33
|
anchor = File.dirname( test_filepath )
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
stripped = FilePathUtils.no_aggregation_decorators( source )
|
|
44
|
-
@file_finder.find_build_input_file(
|
|
45
|
-
filepath: PathMatcher.resolve_relative( stripped, anchor: anchor ),
|
|
46
|
-
complain: :ignore,
|
|
47
|
-
context: context
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
additive_sources = additive.map(&find).compact
|
|
35
|
+
additive_sources = additive.filter_map { |source| locate( source, anchor: anchor, context: context ) }
|
|
52
36
|
|
|
53
37
|
subtractive_sources = subtractive.each_with_object({}) do |source, hash|
|
|
54
|
-
resolved =
|
|
38
|
+
resolved = locate( source, anchor: anchor, context: context )
|
|
55
39
|
hash[resolved] = source unless resolved.nil?
|
|
56
40
|
end
|
|
57
41
|
|
|
58
42
|
return [additive_sources, subtractive_sources]
|
|
59
43
|
end
|
|
60
44
|
|
|
45
|
+
# A TEST_SOURCE_FILE() entry must name a real, recognized file whether it adds or removes.
|
|
46
|
+
# A typo fails loudly on either side of the +:/-: convention, naming the test that holds
|
|
47
|
+
# it. Entries are found exactly as `resolve` finds them, so any entry a build uses passes.
|
|
48
|
+
def validate!(test:, test_filepath:, context:)
|
|
49
|
+
anchor = File.dirname( test_filepath )
|
|
50
|
+
|
|
51
|
+
@test_context_extractor.lookup_build_directive_sources_list( test_filepath ).each do |entry|
|
|
52
|
+
source = FilePathUtils.no_aggregation_decorators( entry )
|
|
53
|
+
validate_extension!( test, source )
|
|
54
|
+
next unless locate( entry, anchor: anchor, context: context ).nil?
|
|
55
|
+
|
|
56
|
+
raise CeedlingException.new( "File '#{source}' specified with TEST_SOURCE_FILE() in #{test} cannot be found in the source file collection" )
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
61
60
|
# Applies this test's TEST_SOURCE_FILE("-:...") entries against the fully
|
|
62
61
|
# assembled source list, regardless of how each removed file originally got
|
|
63
62
|
# there -- the implicit header/source convention, a positive directive, or
|
|
@@ -75,4 +74,25 @@ class TestSourceFileDirectiveResolver
|
|
|
75
74
|
return sources - subtractive.keys
|
|
76
75
|
end
|
|
77
76
|
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
# An entry's text is written in its test file, so its `..`, if any, is anchored to that
|
|
80
|
+
# test file's directory, as a directory-relative #include is
|
|
81
|
+
def locate(entry, anchor:, context:)
|
|
82
|
+
stripped = FilePathUtils.no_aggregation_decorators( entry )
|
|
83
|
+
return @file_finder.find_build_input_file(
|
|
84
|
+
filepath: PathMatcher.resolve_relative( stripped, anchor: anchor ), complain: :ignore, context: context
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def validate_extension!(test, source)
|
|
89
|
+
assembly = @configurator.test_build_use_assembly
|
|
90
|
+
return if @configurator.extension_source.match?( source )
|
|
91
|
+
return if assembly && @configurator.extension_assembly.match?( source )
|
|
92
|
+
|
|
93
|
+
extensions = @configurator.extension_source.to_s
|
|
94
|
+
extensions += " or #{@configurator.extension_assembly}" if assembly
|
|
95
|
+
raise CeedlingException.new( "File '#{source}' specified with TEST_SOURCE_FILE() in #{test} is not a #{extensions} source file" )
|
|
96
|
+
end
|
|
97
|
+
|
|
78
98
|
end
|
|
@@ -189,8 +189,8 @@ class ToolExecutor
|
|
|
189
189
|
|
|
190
190
|
# Handle array or anything else passed into method to be expanded in place of replacement operators
|
|
191
191
|
case (to_process)
|
|
192
|
-
when Array then to_process.each {|value| build_string.concat( "#{element
|
|
193
|
-
else build_string.concat( element
|
|
192
|
+
when Array then to_process.each {|value| build_string.concat( "#{substitute( element, match, value )} " ) } if (to_process.size > 0)
|
|
193
|
+
else build_string.concat( substitute( element, match, to_process ) )
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
# Handle inline ruby string substitution
|
|
@@ -256,7 +256,7 @@ class ToolExecutor
|
|
|
256
256
|
# expand elements (whether string or array) into substitution string & replace escaped '\$'
|
|
257
257
|
elements.flatten!
|
|
258
258
|
elements.each do |element|
|
|
259
|
-
build_string.concat( substitution
|
|
259
|
+
build_string.concat( substitute( substitution, /(?<!\\)\$/, element ) ) # don't replace escaped '\$' but allow us to replace just a lonesome '$'
|
|
260
260
|
build_string.gsub!(/\\\$/, '$')
|
|
261
261
|
build_string.concat(' ')
|
|
262
262
|
end
|
|
@@ -264,6 +264,12 @@ class ToolExecutor
|
|
|
264
264
|
return build_string.strip
|
|
265
265
|
end
|
|
266
266
|
|
|
267
|
+
# Replaces the first match of pattern in template with value, taken literally. A
|
|
268
|
+
# replacement string would read a path's `\0`, `\1` or `\\` as a back-reference.
|
|
269
|
+
def substitute(template, pattern, value)
|
|
270
|
+
return template.sub( pattern ) { value.to_s }
|
|
271
|
+
end
|
|
272
|
+
|
|
267
273
|
def pretty_tool_name(command)
|
|
268
274
|
# Titleize command's name -- each word capitalized plus underscores replaced with spaces
|
|
269
275
|
name = "#{command[:name].split(/ |\_/).map(&:capitalize).join(" ")}"
|
|
@@ -82,8 +82,9 @@ class YamlWrapper
|
|
|
82
82
|
# already picks the right calling convention for the installed Psych, so this should be
|
|
83
83
|
# unreachable in practice; it exists as a last-resort safety net for an unanticipated
|
|
84
84
|
# Psych version/interface mismatch, reported distinctly so it isn't mistaken for a user
|
|
85
|
-
# YAML-authoring error.
|
|
86
|
-
|
|
85
|
+
# YAML-authoring error. `::ArgumentError` names Ruby's own class, which the constructor
|
|
86
|
+
# gem's same-named class would otherwise shadow here.
|
|
87
|
+
rescue ::ArgumentError => e
|
|
87
88
|
raise YamlLoadException.new(
|
|
88
89
|
reason: :incompatible, source: source_label, original_error: e,
|
|
89
90
|
message: "Installed Psych YAML library (#{Psych::VERSION}) does not support a safe-loading feature Ceedling requires ⏩️ #{e.message}"
|
data/lib/version.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Ceedling
|
|
|
21
21
|
# Target version for the current release cycle. Maintained by hand, one edit
|
|
22
22
|
# per minor or major cycle. Never edited to match a release tag. The release
|
|
23
23
|
# pipeline rewrites this line from the tag that triggered it.
|
|
24
|
-
BASE = '1.2.
|
|
24
|
+
BASE = '1.2.2'
|
|
25
25
|
|
|
26
26
|
# Marker for a build the release pipeline did not produce. That pipeline
|
|
27
27
|
# empties this line, so a published gem reports a bare version while a local
|
|
@@ -51,7 +51,7 @@ DEFAULT_BULLSEYE_LINKER_TOOL = {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
DEFAULT_BULLSEYE_FIXTURE_TOOL = {
|
|
54
|
-
:executable => '${1}'.freeze,
|
|
54
|
+
:executable => '"${1}"'.freeze, # Test executable, quoted as a path
|
|
55
55
|
:name => 'default_bullseye_fixture'.freeze,
|
|
56
56
|
:optional => false.freeze,
|
|
57
57
|
:arguments => [].freeze
|
|
@@ -220,7 +220,7 @@ class Bullseye < Plugin
|
|
|
220
220
|
end
|
|
221
221
|
|
|
222
222
|
header = "Untested source files not in the coverage report (:untested_sources is :list):"
|
|
223
|
-
@loginator.log_list( untested_sources.sort, header, Verbosity::COMPLAIN
|
|
223
|
+
@loginator.log_list( untested_sources.sort, header, Verbosity::COMPLAIN )
|
|
224
224
|
|
|
225
225
|
when BULLSEYE_UNTESTED_SOURCES_COMPILE
|
|
226
226
|
untested_sources = collect_untested_sources( sources )
|
|
@@ -236,7 +236,7 @@ class Bullseye < Plugin
|
|
|
236
236
|
untested_sources.each do |filepath|
|
|
237
237
|
filename = File.basename(filepath)
|
|
238
238
|
object = @ceedling[:file_path_utils].form_test_object_filepath( filepath, context: BULLSEYE_SYM )
|
|
239
|
-
dependencies = @ceedling[:file_path_utils].form_test_dependencies_filepath(
|
|
239
|
+
dependencies = @ceedling[:file_path_utils].form_test_dependencies_filepath( object, context: BULLSEYE_SYM )
|
|
240
240
|
search_paths = @configurator.collection_paths_include
|
|
241
241
|
# Defines and flags resolve as a tested source's do, against this source's filepath
|
|
242
242
|
flags = @ceedling[:test_build_setup].flags( context: BULLSEYE_SYM, operation: OPERATION_COMPILE_SYM, filepath: filepath )
|
|
@@ -263,6 +263,9 @@ class Bullseye < Plugin
|
|
|
263
263
|
next
|
|
264
264
|
end
|
|
265
265
|
|
|
266
|
+
@file_wrapper.mkdir( File.dirname( object ) )
|
|
267
|
+
@file_wrapper.mkdir( File.dirname( dependencies ) )
|
|
268
|
+
|
|
266
269
|
begin
|
|
267
270
|
@ceedling[:generator].generate_object_file_c(
|
|
268
271
|
tool: TOOLS_BULLSEYE_COMPILER,
|
|
@@ -559,11 +562,10 @@ class Bullseye < Plugin
|
|
|
559
562
|
coverage_sources = []
|
|
560
563
|
@test_invoker.each_test_with_sources { |_, srcs| coverage_sources.concat( srcs ) }
|
|
561
564
|
coverage_sources.uniq!
|
|
562
|
-
# Every configured source extension is a valid ending for a mock/ignored-source name
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
coverage_sources.delete_if {|item| item =~
|
|
566
|
-
coverage_sources.delete_if {|item| item =~ /(?:#{BULLSEYE_IGNORE_SOURCES.join('|')})(?:#{source_extensions})$/}
|
|
565
|
+
# Every configured source extension is a valid ending for a mock/ignored-source name
|
|
566
|
+
source_extensions = EXTENSION_SOURCE.pattern
|
|
567
|
+
coverage_sources.delete_if {|item| item =~ /#{@configurator.cmock_mock_prefix}.+#{source_extensions}$/}
|
|
568
|
+
coverage_sources.delete_if {|item| item =~ /(?:#{BULLSEYE_IGNORE_SOURCES.join('|')})#{source_extensions}$/}
|
|
567
569
|
|
|
568
570
|
coverage_sources.each do |source|
|
|
569
571
|
command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_REPORT_COVFN, [], source)
|