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
|
@@ -129,10 +129,9 @@ class Reportinator
|
|
|
129
129
|
# Sanitze -- ensure it's a string and strip any filename extension
|
|
130
130
|
_module_name = module_name.to_s().ext('')
|
|
131
131
|
|
|
132
|
-
# If filename is the module name, don't add the module label. A
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
# own last segment is weighed against filename's bare basename.
|
|
132
|
+
# If filename is the module name, don't add the module label. A test's name is
|
|
133
|
+
# its path from the project root (e.g. `test/adc/TestFoo`), so only its last
|
|
134
|
+
# segment is weighed against filename's bare basename.
|
|
136
135
|
label = (File.basename(filename).ext('') == File.basename(_module_name)) ? '' : "#{_module_name}::"
|
|
137
136
|
return generate_progress("#{operation} #{label}#{filename}")
|
|
138
137
|
end
|
data/lib/ceedling/setupinator.rb
CHANGED
|
@@ -7,6 +7,29 @@
|
|
|
7
7
|
|
|
8
8
|
class Setupinator
|
|
9
9
|
|
|
10
|
+
# Configurator steps that fill out the configuration from user configuration and defaults,
|
|
11
|
+
# in the order they run:
|
|
12
|
+
# - Unity and CMock values that tie vendor tool configurations together
|
|
13
|
+
# - The Partials configuration reference for dependency-tracker meta
|
|
14
|
+
# - Test runner generation settings
|
|
15
|
+
# - Exceptions, enabled automagically by CMock settings
|
|
16
|
+
# - Environment variables again, before configuration that may reference them by inline
|
|
17
|
+
# Ruby string expansion
|
|
18
|
+
# - Paths, flags, and defines expanded, then paths standardized
|
|
19
|
+
# - Unity helpers, included in mocks by their standardized filenames
|
|
20
|
+
COMPLETION_STEPS = %i[populate_unity_config populate_cmock_config populate_partials_config populate_test_runner_generation_config
|
|
21
|
+
populate_exceptions_config eval_environment_variables eval_paths eval_flags eval_defines standardize_paths populate_cmock_helpers].freeze
|
|
22
|
+
|
|
23
|
+
# Configurator settings taken from the command line, each by its application
|
|
24
|
+
# configuration key: test case filters, whether the requested tasks build tests or a
|
|
25
|
+
# release (which decides what build/vendor needs), and forced test re-execution
|
|
26
|
+
COMMAND_LINE_SETTINGS = { include_test_case: :include_test_case, exclude_test_case: :exclude_test_case,
|
|
27
|
+
test_build_tasks: :test_build_tasks?, release_build_tasks: :release_build_tasks?, force_test_rerun: :force_test_rerun }.freeze
|
|
28
|
+
|
|
29
|
+
# The application objects setup uses, taken from the object hash rather than a DIY
|
|
30
|
+
# constructor, which validates aspects of setup
|
|
31
|
+
COLLABORATORS = %i[configurator loginator reportinator plugin_manager plugin_reportinator test_runner_manager].freeze
|
|
32
|
+
|
|
10
33
|
attr_reader :config_hash
|
|
11
34
|
|
|
12
35
|
def setup
|
|
@@ -26,36 +49,40 @@ class Setupinator
|
|
|
26
49
|
def ceedling=(value)
|
|
27
50
|
# Capture application objects hash as instance variable
|
|
28
51
|
@ceedling = value
|
|
29
|
-
|
|
30
|
-
# Get our dependencies from object hash rather than DIY constructor
|
|
31
|
-
# This is a shortcut / validates aspects of our setup
|
|
32
|
-
@configurator = value[:configurator]
|
|
33
|
-
@loginator = value[:loginator]
|
|
34
|
-
@reportinator = value[:reportinator]
|
|
35
|
-
@plugin_manager = value[:plugin_manager]
|
|
36
|
-
@plugin_reportinator = value[:plugin_reportinator]
|
|
37
|
-
@test_runner_manager = value[:test_runner_manager]
|
|
52
|
+
COLLABORATORS.each { |name| instance_variable_set( "@#{name}", value[name] ) }
|
|
38
53
|
end
|
|
39
54
|
|
|
40
55
|
|
|
41
56
|
# Load up all the constants and accessors our rake files, objects, & external scripts will need.
|
|
57
|
+
# Each numbered step's order matters.
|
|
42
58
|
def do_setup( app_cfg )
|
|
43
59
|
@config_hash = app_cfg[:project_config]
|
|
44
60
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
apply_command_line( app_cfg ) # 1.
|
|
62
|
+
prepare_essential_configuration() # 1.
|
|
63
|
+
plugins_paths_hash = handle_base_configuration( app_cfg ) # 2.
|
|
64
|
+
handle_plugins( plugins_paths_hash ) # 3.
|
|
65
|
+
assemble_defaults( plugins_paths_hash ) # 4.
|
|
66
|
+
complete_configuration( app_cfg ) # 5.
|
|
67
|
+
validate_final_configuration() # 6.
|
|
68
|
+
|
|
69
|
+
# 7. Partially flatten config + build Configurator accessors and globals
|
|
70
|
+
@configurator.build( app_cfg[:ceedling_lib_path], app_cfg[:logging_path], config_hash, :environment )
|
|
71
|
+
|
|
72
|
+
load_plugins() # 8.
|
|
73
|
+
end
|
|
74
|
+
|
|
48
75
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
76
|
+
### Private
|
|
77
|
+
|
|
78
|
+
private
|
|
52
79
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
80
|
+
##
|
|
81
|
+
## 1. Miscellaneous handling and essential configuration prep
|
|
82
|
+
##
|
|
56
83
|
|
|
57
|
-
|
|
58
|
-
@configurator.
|
|
84
|
+
def apply_command_line(app_cfg)
|
|
85
|
+
COMMAND_LINE_SETTINGS.each { |setting, key| @configurator.public_send( "#{setting}=", app_cfg[key] ) }
|
|
59
86
|
|
|
60
87
|
# Verbosity handling
|
|
61
88
|
@configurator.set_verbosity()
|
|
@@ -63,7 +90,9 @@ class Setupinator
|
|
|
63
90
|
# Logging configuration
|
|
64
91
|
@loginator.set_logfile( app_cfg[:log_filepath] )
|
|
65
92
|
@configurator.project_logging = @loginator.project_logging
|
|
93
|
+
end
|
|
66
94
|
|
|
95
|
+
def prepare_essential_configuration
|
|
67
96
|
log_step( 'Validating configuration contains minimum required sections', heading: false )
|
|
68
97
|
|
|
69
98
|
# Complain early about anything essential that's missing
|
|
@@ -72,39 +101,44 @@ class Setupinator
|
|
|
72
101
|
# Merge any needed runtime settings into user configuration
|
|
73
102
|
@configurator.merge_ceedling_runtime_config( config_hash, CEEDLING_RUNTIME_CONFIG.deep_clone )
|
|
74
103
|
|
|
75
|
-
|
|
76
|
-
log_step( 'Processing Partials configuration', heading: false, verbosity: Verbosity::NORMAL )
|
|
77
|
-
# Set configuration settings derived from enabling partials
|
|
78
|
-
@configurator.set_partials_derived_config( config_hash )
|
|
79
|
-
end
|
|
104
|
+
return unless config_hash[:project][:use_partials]
|
|
80
105
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
106
|
+
log_step( 'Processing Partials configuration', heading: false, verbosity: Verbosity::NORMAL )
|
|
107
|
+
# Set configuration settings derived from enabling partials
|
|
108
|
+
@configurator.set_partials_derived_config( config_hash )
|
|
109
|
+
end
|
|
84
110
|
|
|
111
|
+
##
|
|
112
|
+
## 2. Handle basic configuration
|
|
113
|
+
##
|
|
114
|
+
|
|
115
|
+
def handle_base_configuration(app_cfg)
|
|
85
116
|
log_step( 'Base configuration handling', heading: false )
|
|
86
117
|
|
|
87
118
|
# Evaluate environment vars before plugin configurations that might reference with inline Ruby string expansion
|
|
88
119
|
@configurator.eval_environment_variables( config_hash )
|
|
89
120
|
|
|
90
121
|
# Standardize paths and add to Ruby load paths
|
|
91
|
-
|
|
122
|
+
return @configurator.prepare_plugins_load_paths( app_cfg[:ceedling_plugins_path], config_hash )
|
|
123
|
+
end
|
|
92
124
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
125
|
+
##
|
|
126
|
+
## 3. Plugin Handling
|
|
127
|
+
##
|
|
96
128
|
|
|
129
|
+
def handle_plugins(plugins_paths_hash)
|
|
97
130
|
log_step( 'Plugin Handling' )
|
|
98
131
|
|
|
99
|
-
# Plugin handling
|
|
100
132
|
@configurator.discover_plugins( plugins_paths_hash, config_hash )
|
|
101
133
|
@configurator.merge_config_plugins( config_hash )
|
|
102
134
|
@configurator.populate_plugins_config( plugins_paths_hash, config_hash )
|
|
135
|
+
end
|
|
103
136
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
137
|
+
##
|
|
138
|
+
## 4. Collect and apply defaults to user configuration
|
|
139
|
+
##
|
|
107
140
|
|
|
141
|
+
def assemble_defaults(plugins_paths_hash)
|
|
108
142
|
log_step( 'Assembling Default Settings' )
|
|
109
143
|
|
|
110
144
|
# Assemble defaults
|
|
@@ -115,37 +149,20 @@ class Setupinator
|
|
|
115
149
|
|
|
116
150
|
# Set any missing essential or plugin values in configuration with assembled default values
|
|
117
151
|
@configurator.populate_with_defaults( config_hash, defaults_hash )
|
|
152
|
+
end
|
|
118
153
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
154
|
+
##
|
|
155
|
+
## 5. Fill out / modify remaining configuration from user configuration + defaults
|
|
156
|
+
##
|
|
122
157
|
|
|
158
|
+
def complete_configuration(app_cfg)
|
|
123
159
|
log_step( 'Completing Project Configuration' )
|
|
124
160
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# Populate CMock configuration with values to tie vendor tool configurations together
|
|
129
|
-
@configurator.populate_cmock_config( config_hash )
|
|
130
|
-
|
|
131
|
-
# Populate Partials configuration reference for dependency-tracker meta
|
|
132
|
-
@configurator.populate_partials_config( config_hash )
|
|
133
|
-
|
|
134
|
-
# Configure test runner generation
|
|
135
|
-
@configurator.populate_test_runner_generation_config( config_hash )
|
|
136
|
-
|
|
137
|
-
# Automagically enable use of exceptions based on CMock settings
|
|
138
|
-
@configurator.populate_exceptions_config( config_hash )
|
|
139
|
-
|
|
140
|
-
# Evaluate environment vars again before subsequent configurations that might reference with inline Ruby string expansion
|
|
141
|
-
@configurator.eval_environment_variables( config_hash )
|
|
142
|
-
|
|
143
|
-
# Standardize values and expand inline Ruby string substitutions
|
|
144
|
-
@configurator.eval_paths( config_hash )
|
|
145
|
-
@configurator.eval_flags( config_hash )
|
|
146
|
-
@configurator.eval_defines( config_hash )
|
|
147
|
-
@configurator.standardize_paths( config_hash )
|
|
161
|
+
COMPLETION_STEPS.each { |step| @configurator.public_send( step, config_hash ) }
|
|
162
|
+
complete_tools_and_runners( app_cfg )
|
|
163
|
+
end
|
|
148
164
|
|
|
165
|
+
def complete_tools_and_runners(app_cfg)
|
|
149
166
|
# Fill out any missing tool config value
|
|
150
167
|
@configurator.populate_tools_config( config_hash )
|
|
151
168
|
|
|
@@ -163,57 +180,44 @@ class Setupinator
|
|
|
163
180
|
# Configure test runner build & runtime options
|
|
164
181
|
@test_runner_manager.configure_build_options( config_hash )
|
|
165
182
|
@test_runner_manager.configure_runtime_options( app_cfg[:include_test_case], app_cfg[:exclude_test_case] )
|
|
183
|
+
end
|
|
166
184
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
185
|
+
##
|
|
186
|
+
## 6. Validate configuration
|
|
187
|
+
##
|
|
170
188
|
|
|
189
|
+
def validate_final_configuration
|
|
171
190
|
log_step( 'Validating final project configuration', heading: false )
|
|
172
191
|
|
|
173
192
|
@configurator.validate_final( config_hash )
|
|
193
|
+
end
|
|
174
194
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
# Skip logging this step as the end user doesn't care about this internal preparation
|
|
180
|
-
|
|
181
|
-
# Partially flatten config + build Configurator accessors and globals
|
|
182
|
-
@configurator.build( app_cfg[:ceedling_lib_path], app_cfg[:logging_path], config_hash, :environment )
|
|
183
|
-
|
|
184
|
-
##
|
|
185
|
-
## 8. Final plugins handling
|
|
186
|
-
##
|
|
195
|
+
##
|
|
196
|
+
## 8. Final plugins handling
|
|
197
|
+
##
|
|
187
198
|
|
|
199
|
+
def load_plugins
|
|
188
200
|
# Detailed logging already happend for plugin processing
|
|
189
201
|
log_step( 'Loading Plugins' )
|
|
190
202
|
|
|
191
203
|
@configurator.insert_rake_plugins( @configurator.rake_plugins )
|
|
192
|
-
|
|
204
|
+
|
|
193
205
|
# Merge in any environment variables that plugins specify after the main build
|
|
194
206
|
@plugin_manager.load_programmatic_plugins( @configurator.programmatic_plugins, @ceedling ) do |env|
|
|
195
207
|
# Evaluate environment vars that plugins may have added
|
|
196
208
|
@configurator.eval_environment_variables( env )
|
|
197
209
|
@configurator.build_supplement( config_hash, env )
|
|
198
210
|
end
|
|
199
|
-
|
|
211
|
+
|
|
200
212
|
# Inject dependencies for plugin needs
|
|
201
213
|
@plugin_reportinator.set_system_objects( @ceedling )
|
|
202
214
|
end
|
|
203
215
|
|
|
204
|
-
|
|
205
|
-
### Private
|
|
206
|
-
|
|
207
|
-
private
|
|
208
|
-
|
|
209
216
|
# Neaten up a build step with progress message and some scope encapsulation
|
|
210
217
|
def log_step(msg, heading: true, verbosity: Verbosity::OBNOXIOUS )
|
|
211
|
-
@loginator.lazy( verbosity ) do
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
else # Progress message
|
|
215
|
-
"\n" + @reportinator.generate_progress( @loginator.decorate( msg, LogLabels::CONSTRUCT ) )
|
|
216
|
-
end
|
|
218
|
+
@loginator.lazy( verbosity ) do
|
|
219
|
+
decorated = @loginator.decorate( msg, LogLabels::CONSTRUCT )
|
|
220
|
+
heading ? @reportinator.generate_heading( decorated ) : "\n" + @reportinator.generate_progress( decorated )
|
|
217
221
|
end
|
|
218
222
|
end
|
|
219
223
|
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
require 'ceedling/exceptions'
|
|
9
9
|
require 'ceedling/partials/partials'
|
|
10
|
-
require 'ceedling/file_path_utils'
|
|
10
|
+
require 'ceedling/filesystem/file_path_utils'
|
|
11
11
|
require 'ceedling/generators/generator_test_runner' # From lib/ not vendor/unity/auto
|
|
12
12
|
require 'ceedling/encodinator'
|
|
13
|
+
require 'ceedling/filesystem/project_paths'
|
|
13
14
|
|
|
14
15
|
class TestContextExtractor
|
|
15
16
|
|
|
@@ -304,9 +305,12 @@ class TestContextExtractor
|
|
|
304
305
|
end
|
|
305
306
|
end
|
|
306
307
|
|
|
308
|
+
# Each path is recorded in the one spelling collections use, so its headers are never
|
|
309
|
+
# collected a second time under another
|
|
307
310
|
def ingest_build_directive_include_paths(filepath, include_paths)
|
|
308
311
|
return if include_paths.empty?
|
|
309
312
|
|
|
313
|
+
include_paths = include_paths.map { |path| ProjectPaths.canonical( path ) }
|
|
310
314
|
key = form_file_key( filepath )
|
|
311
315
|
|
|
312
316
|
@lock.synchronize do
|
|
@@ -23,14 +23,14 @@ The seven stage classes never call each other. `TestPipelineManager` alone seque
|
|
|
23
23
|
Three collaborators hold logic more than one stage needs, so the stages cannot drift apart:
|
|
24
24
|
|
|
25
25
|
- **`TestSearchPaths`** composes a test's search paths in the order the compiler searches them, and sets a test's mock search paths (stages 2, 3, and 4).
|
|
26
|
-
- **`MockLocator`** resolves a mock's real header and the
|
|
26
|
+
- **`MockLocator`** resolves a mock's real header and places the mock: its directory below the test's mock root, the folder and root CMock writes it by, and the directory its `#include` as written reaches it from (stages 2, 4, 5, and 10).
|
|
27
27
|
- **`StandinHeaderinator`** places stand-in headers for mocks and Partials (stage 4).
|
|
28
28
|
|
|
29
29
|
## `PipelineState` and `Testable`
|
|
30
30
|
|
|
31
31
|
`PipelineState` exists once for the whole run, and a `Testable` exists once per test file. Between them they hold everything a stage reads or writes:
|
|
32
32
|
|
|
33
|
-
- **Identity**: a `Testable`'s `filepath` and `name`, set in the first stage and never changed.
|
|
33
|
+
- **Identity**: a `Testable`'s `filepath` and `name`, set in the first stage and never changed. The name is the test's path from the project root without its extension (`FilePathUtils#form_test_name`), unique in every build, and it keys `PipelineState#testables` and places every per-test directory. A path outside the project writes each `..` as `_up_`, so no name reaches outside the build directory. `FileFinder` maps a name back to its test file exactly, never by search.
|
|
34
34
|
- **Paths and preprocessing scratch state**: where this test's build output, mocks, Partials, and preprocessed files live, and the bookkeeping preprocessing needs along the way. These stay plain Hashes because their keys are sparse and conditional. A project with mocking disabled has no `:mocks` path at all, which a Hash tolerates better than a struct field with no meaningful default.
|
|
35
35
|
- **Flags, defines, and search paths**: the compiler, linker, and preprocessor arguments resolved once per test and reused by every stage that runs a tool. `mock_search_paths` holds the part of `search_paths` that points at this test's mirrored mock directories (see [Mock search paths](#mock-search-paths)), so a stage can take them back out when it needs the ordering without them.
|
|
36
36
|
- **Generated-content records**: `runner` (a `RunnerInfo`), each resolved mock in `mocks` (a `MockDetails`), and `partials` (a `TestablePartials`, holding a config map and the two lists of module names Partials generation has produced so far). These have a fixed shape every instance shares, which is what a struct is for: a mistyped field name fails loudly instead of silently doing nothing.
|
|
@@ -55,8 +55,8 @@ Stages 2 and 3 run before stage 4, so anything they derive from the `#include`s
|
|
|
55
55
|
|
|
56
56
|
**Context collection (stages 1-4)** finds out what a test needs, without generating or compiling anything.
|
|
57
57
|
|
|
58
|
-
- **Stage 1**
|
|
59
|
-
- **Stage 2** scans the test file as text: its `#include`s, its include path build directives (cached between runs), and its Partials configuration. With test preprocessing off, it also scans `TEST_SOURCE_FILE()` directives and test case names, since nothing later will. It checks that the test uses mocks or Partials only where the project enables them, and it collects the test's first mock search paths from the text-scan list.
|
|
58
|
+
- **Stage 1** names each test, creates its build directories, and creates its `Testable`. It first stops a build that includes a test whose name another test maps onto, which only two paths differing in extension alone, or a path outside the project mapping onto a real `_up_` or `_abs_` directory, can cause.
|
|
59
|
+
- **Stage 2** scans the test file as text: its `#include`s, its include path build directives (cached between runs), and its Partials configuration. With test preprocessing off, it also scans `TEST_SOURCE_FILE()` directives and test case names, since nothing later will, and checks this test's `TEST_SOURCE_FILE()` entries. It checks that the test uses mocks or Partials only where the project enables them, and it collects the test's first mock search paths from the text-scan list.
|
|
60
60
|
- **Stage 3** resolves the flags, defines, and search paths every later tool call for this test uses.
|
|
61
61
|
- **Stage 4** runs only with test preprocessing on. It extracts the test file's `#include`s through the real preprocessor in three passes, described below, ends by replacing the text-scan list with the reconciled one, and narrows the mock search paths to the mocks that remain.
|
|
62
62
|
|
|
@@ -66,9 +66,9 @@ Stages 2 and 3 run before stage 4, so anything they derive from the `#include`s
|
|
|
66
66
|
|
|
67
67
|
**Mocks (stages 9-10)** run only when the project uses mocks and this run has any. A transform flattens every test's planned mocks into one list, as the Partials transform does. Stage 9, with mock preprocessing on (`:mocks` or `:all`), preprocesses each header to be mocked. Stage 10 generates each mock's source and header with CMock, into a directory that mirrors its real header's location below the test's mock root. The `:mocking` stop point ends the run here.
|
|
68
68
|
|
|
69
|
-
Two same-named headers mocked by directory stay distinct through `:cmock` ↳ `:mock_name_include_folder`, on by default. CMock names a mock's include guard and lifecycle functions by the folder its `#include` names, and the runner names its calls by the same `#include`, so the two always agree. `
|
|
69
|
+
Two same-named headers mocked by directory stay distinct through `:cmock` ↳ `:mock_name_include_folder`, on by default. CMock names a mock's include guard and lifecycle functions by the folder its `#include` names, and the runner names its calls by the same `#include`, so the two always agree. `MockLocator#placement` decides where each mock goes, and generation, the planner's mock sources, the stand-ins, and the mock search paths all use it. When the folder ends the header's mirrored subdirectory, the mock stays in the mirrored directory. An `#include` spelling more path than the mirror holds puts its mock at the written path below the test's mock root instead, and one climbing with `..` stays below the mock root with an `_up_` directory for each `..`. The directory the `#include` as written reaches the mock from joins the mock search paths.
|
|
70
70
|
|
|
71
|
-
**Test file preprocessing and runners (stages 11-13)** work on the test file itself. Stages 11 and 12 run only with test preprocessing on. Stage 11 preprocesses the test file
|
|
71
|
+
**Test file preprocessing and runners (stages 11-13)** work on the test file itself. Stages 11 and 12 run only with test preprocessing on. Stage 11 preprocesses the test file, extracts its `TEST_SOURCE_FILE()` directives from the result, and checks them. Each test checks only its own entries, once, under its own name. Stage 12 parses test case names from that output. Stage 13 always runs and generates the Unity test runner, from the preprocessed test file when there is one and the original otherwise. The `:test_runner` stop point ends the run here.
|
|
72
72
|
|
|
73
73
|
Each of these stages is skipped when nothing its output is built from has changed, which takes in more than the test file. Stage 11's full expansion reads every header the test reaches, so the project headers named in its line markers are among stage 11's dependencies, as they are for stage 4's second pass. Editing the macro in a header that enables a test case therefore reruns stage 11. When stage 11 is skipped, its `TEST_SOURCE_FILE()` directives are recalled from a cache. Stages 12 and 13 check one runner target. It depends on the test file, the file test case names are parsed from, the runner and Unity configuration, and the test's mock and include lists. With test preprocessing, those lists come from stage 4's reconciliation, so a header that changes which mocks a test has regenerates its runner although the test file is unchanged.
|
|
74
74
|
|
|
@@ -110,7 +110,7 @@ Pass 1 places stand-ins whether its list was just extracted or recalled from cac
|
|
|
110
110
|
|
|
111
111
|
### Mock search paths
|
|
112
112
|
|
|
113
|
-
A mock is generated into a directory mirroring its real header's location, and the compiler finds it only if that directory is on the search path. C's `#include` resolution has no recursive search path. So each test's search paths carry
|
|
113
|
+
A mock is generated into a directory mirroring its real header's location, and the compiler finds it only if that directory is on the search path. C's `#include` resolution has no recursive search path. So each test's search paths carry each mock's directory, and the directory its `#include` reaches it from when that differs, after the flat mock root. `mock_search_paths` records which entries those are.
|
|
114
114
|
|
|
115
115
|
Where the paths come from follows which `#include` list drives the build:
|
|
116
116
|
|
|
@@ -120,6 +120,8 @@ Where the paths come from follows which `#include` list drives the build:
|
|
|
120
120
|
|
|
121
121
|
Every stage that resolves a mock's header does so through `MockLocator`, against the test's search paths minus its `mock_search_paths`, so stages 2, 4, and 5 resolve each mock identically.
|
|
122
122
|
|
|
123
|
+
Resolving needs every header on those search paths, in search order. `IncludePathinator#ordered_header_files` builds that list from each search path's own listing. A directory outside the build root keeps its listing for the whole test build: the build never writes there, and every stage asks for the same directories for every test. A directory under the build root, such as a mock or Partials directory, is listed on every call, since the build fills it as it runs. Stage 5 builds the list once per test and shares it across the test's mocks. `TestInvoker` forgets the listings at the start of each test build, after the `pre_test_build` hook.
|
|
124
|
+
|
|
123
125
|
## Stop points
|
|
124
126
|
|
|
125
127
|
A run can stop early by including one of four mutually exclusive Symbols in `PipelineState#options`. Each names a different place to stop, so supplying more than one is rejected.
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
|
+
require 'ceedling/filesystem/build_subpath'
|
|
10
|
+
require 'ceedling/filesystem/path_matcher'
|
|
9
11
|
require 'ceedling/test_invoker/test_pipeline_helpers'
|
|
10
12
|
|
|
11
13
|
# Where a test's mocks come from and where they go. A mock's real header resolves
|
|
@@ -16,6 +18,11 @@ class MockLocator
|
|
|
16
18
|
|
|
17
19
|
include TestPipelineHelpers
|
|
18
20
|
|
|
21
|
+
# Where a mock is written (`directory`), the `folder` and `root` CMock writes it by (CMock
|
|
22
|
+
# writes below its root at the folder), and the directory the #include as written reaches
|
|
23
|
+
# the mock from (`reach`), which a search path must name
|
|
24
|
+
MockPlacement = Struct.new( :folder, :directory, :root, :reach, keyword_init: true )
|
|
25
|
+
|
|
19
26
|
constructor :configurator, :include_pathinator, :file_finder, :file_path_utils
|
|
20
27
|
|
|
21
28
|
# The headers a test's mocks resolve against: those on its search paths, in search
|
|
@@ -40,10 +47,61 @@ class MockLocator
|
|
|
40
47
|
source, subdir = locate( include, collection: collection, complain: complain )
|
|
41
48
|
next if source.nil?
|
|
42
49
|
|
|
43
|
-
|
|
50
|
+
search_directories( placement( mocks_root: mocks_root, subdir: subdir, include_path: include.filepath ) )
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
return dirs.flatten.uniq
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# A mock's directory, and the directory its #include as written reaches it from
|
|
57
|
+
def search_directories(placement)
|
|
58
|
+
return [placement.directory, placement.reach].uniq
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Where a mock of the header mirrored at `subdir` is written, for the #include that
|
|
62
|
+
# names it as `include_path`.
|
|
63
|
+
#
|
|
64
|
+
# CMock names a mock's guard and lifecycle functions by the folder its #include names, and
|
|
65
|
+
# the runner names its calls by the same #include, so the folder reaches CMock as written.
|
|
66
|
+
# A folder that ends the mirrored subdirectory keeps that directory. One spelling more
|
|
67
|
+
# path than the mirror holds places the mock at the written path below the mock root. One
|
|
68
|
+
# that climbs stays below the mock root too: each `..` it begins with becomes an `_up_`
|
|
69
|
+
# directory, and the #include reaches the mock from that many levels deeper still.
|
|
70
|
+
# Without :mock_name_include_folder no folder is passed, and CMock names by filename
|
|
71
|
+
# alone, writing into the mock's directory itself.
|
|
72
|
+
def placement(mocks_root:, subdir:, include_path:)
|
|
73
|
+
written = written_folder( include_path )
|
|
74
|
+
spot = written.nil? ? mirrored_spot( mocks_root, subdir ) : written_spot( mocks_root, subdir.to_s, written )
|
|
75
|
+
folder = @configurator.cmock_mock_name_include_folder ? written : nil
|
|
76
|
+
|
|
77
|
+
return MockPlacement.new( folder: folder, directory: spot[:directory], root: (folder ? spot[:reach] : spot[:directory]), reach: spot[:reach] )
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# The folder of a mock's #include as written, without a leading ./, or nil for none
|
|
83
|
+
def written_folder(include_path)
|
|
84
|
+
folder = File.dirname( include_path.to_s ).sub( %r{\A(?:\./)+}, '' )
|
|
85
|
+
return (folder.empty? || folder == '.') ? nil : folder
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def mirrored_spot(mocks_root, subdir)
|
|
89
|
+
directory = @file_path_utils.form_mock_output_path( mocks_root, subdir )
|
|
90
|
+
return { directory: directory, reach: directory }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# The mock's directory for a #include written with `written`, and the directory that
|
|
94
|
+
# folder leads down or climbs from to it
|
|
95
|
+
def written_spot(mocks_root, subdir, written)
|
|
96
|
+
if subdir == written or subdir.end_with?( "/#{written}" )
|
|
97
|
+
return { directory: File.join( mocks_root, subdir ), reach: File.join( mocks_root, subdir.delete_suffix( written ) ).chomp( '/' ) }
|
|
44
98
|
end
|
|
45
99
|
|
|
46
|
-
|
|
100
|
+
segments = PathMatcher.resolve_relative( written, anchor: '' ).split( '/' )
|
|
101
|
+
climbs = segments.take_while { |segment| segment == '..' }.length
|
|
102
|
+
ups = [BuildSubpath::PARENT_SEGMENT] * climbs
|
|
103
|
+
|
|
104
|
+
return { directory: File.join( mocks_root, *ups, *segments.drop( climbs ) ), reach: File.join( mocks_root, *ups, *ups ) }
|
|
47
105
|
end
|
|
48
106
|
|
|
49
107
|
end
|
|
@@ -269,6 +269,8 @@ class PartialsManager
|
|
|
269
269
|
end
|
|
270
270
|
end
|
|
271
271
|
|
|
272
|
+
order_partials( partials.map { |partial| partial[:testable] }.uniq )
|
|
273
|
+
|
|
272
274
|
log_skip_summary( task: "Partial types generation", count: skipped_types, noun: "types headers" )
|
|
273
275
|
log_skip_summary( task: "Partial implementation generation", count: skipped_impl, noun: "implementations" )
|
|
274
276
|
log_skip_summary( task: "Partial interface generation", count: skipped_interface, noun: "interfaces" )
|
|
@@ -296,6 +298,16 @@ class PartialsManager
|
|
|
296
298
|
# and `config.includes` is recalled from the on-disk list a prior stale run wrote
|
|
297
299
|
# -- so `config` ends up populated identically either way, and stage 8 (which
|
|
298
300
|
# reads only `config`) needs no knowledge of which path produced it.
|
|
301
|
+
# Build threads finish in any order. Each test's Partial modules return to its configuration
|
|
302
|
+
# order, which its link and mock lists follow, so an unchanged build sees unchanged lists.
|
|
303
|
+
def order_partials(testables)
|
|
304
|
+
testables.each do |testable|
|
|
305
|
+
order = testable.partials.configs.values.map( &:module )
|
|
306
|
+
testable.partials.tests.sort_by! { |_module| order.index( _module ) }
|
|
307
|
+
testable.partials.mocks.sort_by! { |_module| order.index( _module ) }
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
299
311
|
def preprocess_partials(items:, kind:, noun:, preserve_macros_method:, expand_macros_method:)
|
|
300
312
|
directives_only = @configurator.test_build_preprocess_directives_only_available
|
|
301
313
|
skipped = 0
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
9
|
require 'ceedling/includes/includes'
|
|
10
10
|
require 'ceedling/test_invoker/test_pipeline_helpers'
|
|
11
|
+
require 'ceedling/filesystem/project_paths'
|
|
11
12
|
|
|
12
13
|
# Stand-in headers: files placed where a test's mocks and Partials will be generated, so
|
|
13
14
|
# the preprocessor finds something at each of their #includes before stage 8 or stage 10
|
|
@@ -46,7 +47,7 @@ class StandinHeaderinator
|
|
|
46
47
|
mock_dirs = place_mocks( testable, mocks, complain )
|
|
47
48
|
place_partials( testable, Includes.filter( includes, /^#{PARTIAL_FILENAME_PREFIX}/ ) )
|
|
48
49
|
|
|
49
|
-
return mock_dirs.uniq
|
|
50
|
+
return mock_dirs.flatten.uniq
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
private
|
|
@@ -67,18 +68,25 @@ class StandinHeaderinator
|
|
|
67
68
|
end
|
|
68
69
|
end
|
|
69
70
|
|
|
70
|
-
# Gives the
|
|
71
|
-
# the test has no mock root
|
|
71
|
+
# Gives the search paths that reach the mock, or nil when its missing header is tolerated
|
|
72
|
+
# or the test has no mock root
|
|
72
73
|
def place_mock(testable, include, collection, complain)
|
|
74
|
+
return nil if testable.paths[:mocks].nil?
|
|
75
|
+
|
|
73
76
|
source, subdir = @mock_locator.locate( include, collection: collection, complain: complain )
|
|
74
77
|
return nil if source.nil?
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
placement = @mock_locator.placement( mocks_root: testable.paths[:mocks], subdir: subdir, include_path: include.filepath )
|
|
80
|
+
write_placed_mock( testable.name, placement, include, source )
|
|
78
81
|
|
|
79
|
-
return
|
|
82
|
+
return @mock_locator.search_directories( placement )
|
|
83
|
+
end
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
# The test's #include reaches a climbing folder's mock only from the directory it climbs
|
|
86
|
+
# from, so that is made too
|
|
87
|
+
def write_placed_mock(test, placement, include, source)
|
|
88
|
+
@file_wrapper.mkdir( placement.reach ) unless ProjectPaths.contains?( placement.reach, placement.directory )
|
|
89
|
+
write_mock( test, File.join( placement.directory, include.filename.ext( EXTENSION_CORE_HEADER ) ), include, source, placement.folder )
|
|
82
90
|
end
|
|
83
91
|
|
|
84
92
|
# A Partial's generated #include names whatever directory its module was named by, and
|
|
@@ -97,8 +105,8 @@ class StandinHeaderinator
|
|
|
97
105
|
@file_wrapper.write_blank_file( filepath )
|
|
98
106
|
end
|
|
99
107
|
|
|
100
|
-
def write_mock(test, filepath, include, header)
|
|
101
|
-
contents = "#{MARKER}\n#{header_include( header )}\n"
|
|
108
|
+
def write_mock(test, filepath, include, header, folder)
|
|
109
|
+
contents = "#{MARKER}\n#{header_include( header, folder )}\n"
|
|
102
110
|
return if current?( filepath, contents )
|
|
103
111
|
|
|
104
112
|
log_placement( test, include )
|
|
@@ -106,11 +114,12 @@ class StandinHeaderinator
|
|
|
106
114
|
@file_wrapper.write( filepath, contents )
|
|
107
115
|
end
|
|
108
116
|
|
|
109
|
-
# The line CMock opens a mock with: its :orig_header_include_fmt around the header's name
|
|
110
|
-
#
|
|
111
|
-
def header_include( header )
|
|
117
|
+
# The line CMock opens a mock with: its :orig_header_include_fmt around the header's name,
|
|
118
|
+
# below the folder CMock is given, if any
|
|
119
|
+
def header_include( header, folder )
|
|
112
120
|
format = @configurator.get_cmock_config[:orig_header_include_fmt] || '#include "%s"'
|
|
113
|
-
|
|
121
|
+
name = folder.nil? ? File.basename( header ) : File.join( folder, File.basename( header ) )
|
|
122
|
+
return format.gsub( '%s', name )
|
|
114
123
|
end
|
|
115
124
|
|
|
116
125
|
# A file that is not a stand-in, such as a real mock, counts as current. Only its first
|