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
|
@@ -42,7 +42,7 @@ describe Valgrind do
|
|
|
42
42
|
let(:plugin_manager) { double('plugin_manager', register_build_failure: nil) }
|
|
43
43
|
let(:plugin_reportinator) { double('plugin_reportinator') }
|
|
44
44
|
let(:dependinator) { double('dependinator', register: nil) }
|
|
45
|
-
let(:file_wrapper) { double('file_wrapper',
|
|
45
|
+
let(:file_wrapper) { double('file_wrapper', exist_with_retry?: true, read: '', mkdir: nil) }
|
|
46
46
|
let(:system_wrapper) { double('system_wrapper', windows?: false) }
|
|
47
47
|
let(:ceedling) do
|
|
48
48
|
{
|
|
@@ -207,13 +207,28 @@ describe Valgrind do
|
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
describe '#pre_test_fixture_register' do
|
|
210
|
-
|
|
210
|
+
before(:each) do
|
|
211
|
+
allow(file_wrapper).to receive(:mkdir_for) { |path| path }
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def register(project_config, context: VALGRIND_SYM, test_name: 'test_thing')
|
|
211
215
|
valgrind = build_valgrind(project_config)
|
|
212
|
-
arg_hash = { context: context, test_name:
|
|
216
|
+
arg_hash = { context: context, test_name: test_name, target: 'build/out/test_thing.out', tool: { name: 'original' } }
|
|
213
217
|
valgrind.pre_test_fixture_register(arg_hash)
|
|
214
218
|
[valgrind, arg_hash]
|
|
215
219
|
end
|
|
216
220
|
|
|
221
|
+
# GH #1364: Valgrind writes its reports but makes no directories of its own
|
|
222
|
+
it "makes the directories a nested test's reports go in" do
|
|
223
|
+
expect(file_wrapper).to receive(:mkdir_for).with('artifacts/valgrind/test/unit/test_thing.log')
|
|
224
|
+
expect(file_wrapper).to receive(:mkdir_for).with('artifacts/valgrind/test/unit/test_thing.xml')
|
|
225
|
+
|
|
226
|
+
_valgrind, arg_hash = register({ valgrind_xml_report: true }, test_name: 'test/unit/test_thing')
|
|
227
|
+
|
|
228
|
+
expect(arg_hash[:tool][:arguments]).to include('--log-file="artifacts/valgrind/test/unit/test_thing.log"')
|
|
229
|
+
expect(arg_hash[:tool][:arguments]).to include('--xml-file="artifacts/valgrind/test/unit/test_thing.xml"')
|
|
230
|
+
end
|
|
231
|
+
|
|
217
232
|
it 'leaves a non-valgrind context untouched' do
|
|
218
233
|
original = { name: 'original' }
|
|
219
234
|
valgrind = build_valgrind({})
|
|
@@ -232,10 +247,10 @@ describe Valgrind do
|
|
|
232
247
|
expect(arg_hash[:tool][:arguments]).to include('--log-file="artifacts/valgrind/test_thing.log"')
|
|
233
248
|
end
|
|
234
249
|
|
|
235
|
-
it 'appends the executable substitution token last' do
|
|
250
|
+
it 'appends the executable substitution token last, quoted as a path' do
|
|
236
251
|
_valgrind, arg_hash = register({ valgrind_arguments: ['--leak-check=full'] })
|
|
237
252
|
|
|
238
|
-
expect(arg_hash[:tool][:arguments].last).to eq('${1}')
|
|
253
|
+
expect(arg_hash[:tool][:arguments].last).to eq('"${1}"')
|
|
239
254
|
end
|
|
240
255
|
|
|
241
256
|
it 'places user arguments after the plugin-managed ones' do
|
|
@@ -315,7 +330,7 @@ describe Valgrind do
|
|
|
315
330
|
end
|
|
316
331
|
|
|
317
332
|
def explain(report, project_config: {}, context: VALGRIND_SYM, crash_notice: true, exists: true)
|
|
318
|
-
wrapper = double('file_wrapper',
|
|
333
|
+
wrapper = double('file_wrapper', exist_with_retry?: exists, read: report)
|
|
319
334
|
valgrind = build_valgrind(project_config, file_wrapper: wrapper)
|
|
320
335
|
arg_hash = { context: context, test_name: 'test_thing', crash_notice: crash_notice, explanation: nil }
|
|
321
336
|
valgrind.explain_test_crash( arg_hash )
|
|
@@ -384,7 +399,7 @@ describe Valgrind do
|
|
|
384
399
|
|
|
385
400
|
describe '#post_test_fixture_execute' do
|
|
386
401
|
def execute(project_config, log_contents, exists: true, result_file: File.join('build', 'valgrind', 'results', 'test_thing.pass'))
|
|
387
|
-
wrapper = double('file_wrapper',
|
|
402
|
+
wrapper = double('file_wrapper', exist_with_retry?: exists, read: log_contents)
|
|
388
403
|
valgrind = build_valgrind(project_config, file_wrapper: wrapper)
|
|
389
404
|
valgrind.post_test_fixture_execute(
|
|
390
405
|
{ context: VALGRIND_SYM, test_name: 'test_thing', result_file: result_file }
|
|
@@ -451,7 +466,7 @@ describe Valgrind do
|
|
|
451
466
|
|
|
452
467
|
# A silent skip reads exactly like a clean result. It is not one.
|
|
453
468
|
it 'warns and records nothing when no report was written' do
|
|
454
|
-
expect(loginator).to receive(:log).with(/wrote no report for test_thing/,
|
|
469
|
+
expect(loginator).to receive(:log).with(/wrote no report for test_thing/, Verbosity::COMPLAIN)
|
|
455
470
|
|
|
456
471
|
valgrind = execute({}, '', exists: false)
|
|
457
472
|
|
|
@@ -9,7 +9,7 @@ require 'spec_helper'
|
|
|
9
9
|
require 'ceedling/preprocess/c_comment_scanner'
|
|
10
10
|
require 'ceedling/preprocess/preprocessinator_comment_stripper'
|
|
11
11
|
require 'ceedling/preprocess/preprocessinator_code_finder'
|
|
12
|
-
require 'ceedling/file_wrapper'
|
|
12
|
+
require 'ceedling/filesystem/file_wrapper'
|
|
13
13
|
|
|
14
14
|
RSpec.describe PreprocessinatorCommentStripper do
|
|
15
15
|
|
|
@@ -33,6 +33,18 @@ describe RakefileComponentResolver do
|
|
|
33
33
|
|
|
34
34
|
expect(result).to eq(['ceedling/plugins'])
|
|
35
35
|
end
|
|
36
|
+
|
|
37
|
+
# The path handling audit around GH #1370: bin/ reads :load_paths before the
|
|
38
|
+
# configuration pipeline, so it must expand and standardize them as that pipeline does
|
|
39
|
+
it 'expands and standardizes each configured load path, leaving the configuration as written' do
|
|
40
|
+
config = { plugins: { load_paths: ["\#{'my'}\\plugins\\", '~/plugins'] } }
|
|
41
|
+
expand = ->(path) { path.sub( "\#{'my'}", 'my' ) }
|
|
42
|
+
|
|
43
|
+
result = described_class.prepare_plugin_load_paths(config, 'ceedling/plugins', expand: expand)
|
|
44
|
+
|
|
45
|
+
expect(result).to eq(['my/plugins', File.join( Dir.home, 'plugins' ), 'ceedling/plugins'])
|
|
46
|
+
expect(config[:plugins][:load_paths].first).to eq( "\#{'my'}\\plugins\\" )
|
|
47
|
+
end
|
|
36
48
|
end
|
|
37
49
|
|
|
38
50
|
describe '.gather_rakefiles' do
|
|
@@ -125,6 +137,15 @@ describe RakefileComponentResolver do
|
|
|
125
137
|
File.join('ceedling/plugins', 'gcov', 'gcov.rake'),
|
|
126
138
|
])
|
|
127
139
|
end
|
|
140
|
+
|
|
141
|
+
it 'finds a plugin below a load path that needs expanding' do
|
|
142
|
+
config = { project: { release_build: false }, plugins: { enabled: ['mine'], load_paths: ["\#{'my'}/plugins"] } }
|
|
143
|
+
allow(File).to receive(:exist?).with(File.join('my/plugins', 'mine', 'mine.rake')).and_return(true)
|
|
144
|
+
|
|
145
|
+
result = described_class.resolve(config, 'lib', 'ceedling/plugins', expand: ->(path) { path.sub( "\#{'my'}", 'my' ) })
|
|
146
|
+
|
|
147
|
+
expect(result.last).to eq( File.join('my/plugins', 'mine', 'mine.rake') )
|
|
148
|
+
end
|
|
128
149
|
end
|
|
129
150
|
|
|
130
151
|
describe '.plugin_rake_files' do
|
|
@@ -23,6 +23,7 @@ describe ReleaseBuildExecutor do
|
|
|
23
23
|
@file_wrapper = double( "FileWrapper" )
|
|
24
24
|
@file_path_utils = double( "FilePathUtils" )
|
|
25
25
|
@dependinator = double( "Dependinator" )
|
|
26
|
+
@library_resolver = double( "LibraryResolver" )
|
|
26
27
|
|
|
27
28
|
@tools_release_compiler = { name: 'fake compiler' }
|
|
28
29
|
@tools_release_assembler = { name: 'fake assembler' }
|
|
@@ -56,6 +57,8 @@ describe ReleaseBuildExecutor do
|
|
|
56
57
|
allow(@dependinator).to receive(:register_gcc_deps_file)
|
|
57
58
|
allow(@dependinator).to receive(:stale?).and_return( true )
|
|
58
59
|
allow(@dependinator).to receive(:mark_fresh)
|
|
60
|
+
allow(@library_resolver).to receive(:link_files).and_return( [] )
|
|
61
|
+
allow(@library_resolver).to receive(:search_path_arguments).and_return( [] )
|
|
59
62
|
|
|
60
63
|
@executor = described_class.new(
|
|
61
64
|
{
|
|
@@ -67,7 +70,8 @@ describe ReleaseBuildExecutor do
|
|
|
67
70
|
:file_finder => @file_finder,
|
|
68
71
|
:file_wrapper => @file_wrapper,
|
|
69
72
|
:file_path_utils => @file_path_utils,
|
|
70
|
-
:dependinator => @dependinator
|
|
73
|
+
:dependinator => @dependinator,
|
|
74
|
+
:library_resolver => @library_resolver
|
|
71
75
|
}
|
|
72
76
|
)
|
|
73
77
|
|
|
@@ -278,6 +282,18 @@ describe ReleaseBuildExecutor do
|
|
|
278
282
|
@executor.link( @state )
|
|
279
283
|
end
|
|
280
284
|
|
|
285
|
+
it "separates every configured library extension, and a subproject's, from plain objects" do
|
|
286
|
+
stub_const( "EXTENSION_LIBRARIES", FilenameExtension.new( ['.a', '.so'] ) )
|
|
287
|
+
stub_const( "EXTENSION_SUBPROJECTS", '.lib' )
|
|
288
|
+
@state.objects = ['build/release/out/foo.o', 'vendor/libbar.a', 'vendor/libbaz.so', 'sub/x.lib', 'build/release/out/so.o']
|
|
289
|
+
|
|
290
|
+
expect(@generator).to receive(:generate_executable_file) do |_tool, _sym, objects, *_rest|
|
|
291
|
+
expect(objects).to eq( ['build/release/out/foo.o', 'build/release/out/so.o'] )
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
@executor.link( @state )
|
|
295
|
+
end
|
|
296
|
+
|
|
281
297
|
it "formats a separated library as a linker argument via the configured flag template" do
|
|
282
298
|
stub_const( "EXTENSION_LIBRARIES", FilenameExtension.new('.a') )
|
|
283
299
|
stub_const( "LIBRARIES_FLAG", '-l${1}' )
|
|
@@ -302,9 +318,8 @@ describe ReleaseBuildExecutor do
|
|
|
302
318
|
@executor.link( @state )
|
|
303
319
|
end
|
|
304
320
|
|
|
305
|
-
it "
|
|
306
|
-
|
|
307
|
-
stub_const( "LIBRARIES_PATH_FLAG", '-L${1}' )
|
|
321
|
+
it "links with the library search path arguments the resolver gives" do
|
|
322
|
+
allow(@library_resolver).to receive(:search_path_arguments).and_return( ['-Lvendor/lib'] )
|
|
308
323
|
|
|
309
324
|
expect(@generator).to receive(:generate_executable_file) do |_tool, _sym, _objects, _flags, _target, _map, _lib_args, lib_paths|
|
|
310
325
|
expect(lib_paths).to eq( ['-Lvendor/lib'] )
|
|
@@ -313,14 +328,12 @@ describe ReleaseBuildExecutor do
|
|
|
313
328
|
@executor.link( @state )
|
|
314
329
|
end
|
|
315
330
|
|
|
316
|
-
#
|
|
317
|
-
it "
|
|
318
|
-
|
|
319
|
-
stub_const( "LIBRARIES_PATH_FLAG", DEFAULT_CEEDLING_PROJECT_CONFIG[:libraries][:path_flag] )
|
|
331
|
+
# A target named by an absolute :output may sit in a directory no build made
|
|
332
|
+
it "makes the target's directory before linking" do
|
|
333
|
+
allow(@configurator).to receive(:project_release_build_target).and_return( '/elsewhere/out/app.elf' )
|
|
320
334
|
|
|
321
|
-
expect(@
|
|
322
|
-
|
|
323
|
-
end
|
|
335
|
+
expect(@file_wrapper).to receive(:mkdir).with( '/elsewhere/out' ).ordered
|
|
336
|
+
expect(@generator).to receive(:generate_executable_file).ordered
|
|
324
337
|
|
|
325
338
|
@executor.link( @state )
|
|
326
339
|
end
|
|
@@ -338,14 +351,40 @@ describe ReleaseBuildExecutor do
|
|
|
338
351
|
it "registers the resolved link flags and library arguments, not just the object files, as meta" do
|
|
339
352
|
stub_const( "LIBRARIES_SYSTEM", ['m'] )
|
|
340
353
|
stub_const( "LIBRARIES_FLAG", '-l${1}' )
|
|
341
|
-
|
|
342
|
-
stub_const( "LIBRARIES_PATH_FLAG", '-L${1}' )
|
|
354
|
+
allow(@library_resolver).to receive(:search_path_arguments).and_return( ['-Lvendor/lib'] )
|
|
343
355
|
@state.link_flags = ['-Wall']
|
|
344
356
|
|
|
345
357
|
expect(@dependinator).to receive(:register).with(
|
|
346
358
|
'build/release/out/project.out',
|
|
347
359
|
files: ['build/release/out/foo.o'],
|
|
348
|
-
meta: { flags: ['-Wall'], lib_args: ['-lm'], lib_paths: ['-Lvendor/lib'], tools: [@tools_release_linker] }
|
|
360
|
+
meta: { flags: ['-Wall'], lib_args: ['-lm'], lib_paths: ['-Lvendor/lib'], tools: [@tools_release_linker], objects: ['build/release/out/foo.o'], libraries: [] }
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
@executor.link( @state )
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
# A source dropped from the build leaves every remaining object as it was, so only the
|
|
367
|
+
# object list, as meta, relinks an artifact that would otherwise keep the dropped code
|
|
368
|
+
it "registers the objects it links as meta" do
|
|
369
|
+
expect(@dependinator).to receive(:register).with(
|
|
370
|
+
'build/release/out/project.out', files: ['build/release/out/foo.o'], meta: hash_including( objects: ['build/release/out/foo.o'] )
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
@executor.link( @state )
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# GH #1368: a library rebuilt under the same name changed nothing a link registered
|
|
377
|
+
it "registers the library files its libraries resolve to, including those named by path, as files and as meta" do
|
|
378
|
+
@state.objects = ['build/release/out/foo.o', 'vendor/prebuilt/libp.a']
|
|
379
|
+
stub_const( 'EXTENSION_LIBRARIES', FilenameExtension.new( ['.a'] ) )
|
|
380
|
+
stub_const( 'LIBRARIES_SYSTEM', ['m'] )
|
|
381
|
+
stub_const( 'LIBRARIES_RELEASE', ['x'] )
|
|
382
|
+
|
|
383
|
+
expect(@library_resolver).to receive(:link_files).with( ['vendor/prebuilt/libp.a', 'm', 'x'] ).and_return( ['vendor/prebuilt/libp.a', 'vendor/lib/libx.a', 'build/deps/libfusion.a'] )
|
|
384
|
+
expect(@dependinator).to receive(:register).with(
|
|
385
|
+
'build/release/out/project.out',
|
|
386
|
+
files: ['build/release/out/foo.o', 'vendor/prebuilt/libp.a', 'vendor/lib/libx.a', 'build/deps/libfusion.a'],
|
|
387
|
+
meta: hash_including( libraries: ['vendor/prebuilt/libp.a', 'vendor/lib/libx.a', 'build/deps/libfusion.a'] )
|
|
349
388
|
)
|
|
350
389
|
|
|
351
390
|
@executor.link( @state )
|
|
@@ -51,9 +51,21 @@ describe ReleaseBuildPlanner do
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it "includes extra link-only objects alongside the compiled sources" do
|
|
54
|
-
allow(@configurator).to receive(:collection_release_artifact_extra_link_objects).and_return( ['
|
|
55
|
-
expect(@file_path_utils).to receive(:form_release_build_objects_filelist).with( ['src/Foo.c', 'vendor/cexception/CException.o'] ).and_return( [] )
|
|
54
|
+
allow(@configurator).to receive(:collection_release_artifact_extra_link_objects).and_return( ['CException.o'] )
|
|
56
55
|
@planner.plan( @state, files: nil )
|
|
56
|
+
expect( @state.objects ).to eq( ['build/release/out/Foo.o', 'build/release/out/CException.o'] )
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# A link-only name is no source of its own, so naming the object a compiled source builds
|
|
60
|
+
# to is no collision between two sources
|
|
61
|
+
it "places link-only objects apart from the compiled sources, adding a shared object once" do
|
|
62
|
+
allow(@configurator).to receive(:collection_release_build_input).and_return( ['build/vendor/c_exception/lib/CException.c'] )
|
|
63
|
+
allow(@configurator).to receive(:collection_release_artifact_extra_link_objects).and_return( ['CException.o'] )
|
|
64
|
+
expect(@file_path_utils).to receive(:form_release_build_objects_filelist).with( ['build/vendor/c_exception/lib/CException.c'] ).and_return( ['build/release/out/CException.o'] )
|
|
65
|
+
expect(@file_path_utils).to receive(:form_release_build_objects_filelist).with( ['CException.o'] ).and_return( ['build/release/out/CException.o'] )
|
|
66
|
+
|
|
67
|
+
@planner.plan( @state, files: nil )
|
|
68
|
+
expect( @state.objects ).to eq( ['build/release/out/CException.o'] )
|
|
57
69
|
end
|
|
58
70
|
|
|
59
71
|
it "scopes the object list to just the given file when files is provided, ignoring the full source collection" do
|
|
@@ -124,7 +136,7 @@ describe ReleaseBuildPlanner do
|
|
|
124
136
|
|
|
125
137
|
expect( compiler[:arguments] ).to include( '-fPIC' )
|
|
126
138
|
expect( linker[:executable] ).to eq( 'ar' )
|
|
127
|
-
expect( linker[:arguments] ).to eq( ['rcs', '${2}', '${1}'] )
|
|
139
|
+
expect( linker[:arguments] ).to eq( ['rcs', '"${2}"', '"${1}"'] )
|
|
128
140
|
end
|
|
129
141
|
|
|
130
142
|
it "does nothing when the project has configured its own compiler tool (not the Ceedling default)" do
|
|
@@ -225,14 +225,14 @@ describe Reportinator do
|
|
|
225
225
|
expect(result).to eq("Compiling bar::baz.c...")
|
|
226
226
|
end
|
|
227
227
|
|
|
228
|
-
it 'omits module label when filename matches only the last segment of a
|
|
229
|
-
result = @rp.generate_module_progress(module_name: 'adc/TestFoo', filename: 'TestFoo.c', operation: 'Compiling')
|
|
228
|
+
it 'omits module label when filename matches only the last segment of a multi-segment module name' do
|
|
229
|
+
result = @rp.generate_module_progress(module_name: 'test/adc/TestFoo', filename: 'TestFoo.c', operation: 'Compiling')
|
|
230
230
|
expect(result).to eq("Compiling TestFoo.c...")
|
|
231
231
|
end
|
|
232
232
|
|
|
233
|
-
it 'prepends the full
|
|
234
|
-
result = @rp.generate_module_progress(module_name: 'adc/TestFoo', filename: 'MockBar.c', operation: 'Generating mock for')
|
|
235
|
-
expect(result).to eq("Generating mock for adc/TestFoo::MockBar.c...")
|
|
233
|
+
it 'prepends the full module name when filename differs from its last segment' do
|
|
234
|
+
result = @rp.generate_module_progress(module_name: 'test/adc/TestFoo', filename: 'MockBar.c', operation: 'Generating mock for')
|
|
235
|
+
expect(result).to eq("Generating mock for test/adc/TestFoo::MockBar.c...")
|
|
236
236
|
end
|
|
237
237
|
end
|
|
238
238
|
|
|
@@ -10,6 +10,7 @@ require 'ceedling/constants'
|
|
|
10
10
|
require 'ceedling/includes/includes'
|
|
11
11
|
require 'ceedling/test_invoker/test_invoker_types'
|
|
12
12
|
require 'ceedling/test_invoker/standin_headerinator'
|
|
13
|
+
require 'ceedling/test_invoker/mock_locator'
|
|
13
14
|
|
|
14
15
|
describe StandinHeaderinator do
|
|
15
16
|
before(:each) do
|
|
@@ -33,6 +34,11 @@ describe StandinHeaderinator do
|
|
|
33
34
|
end
|
|
34
35
|
allow(@mock_locator).to receive(:header_collection).and_return( ['src/drivers/foo.h'] )
|
|
35
36
|
allow(@mock_locator).to receive(:locate).and_return( ['src/drivers/foo.h', 'drivers'] )
|
|
37
|
+
allow(@mock_locator).to receive(:placement) do |mocks_root:, subdir:, **|
|
|
38
|
+
dir = subdir.empty? ? mocks_root : File.join( mocks_root, subdir )
|
|
39
|
+
MockLocator::MockPlacement.new( folder: nil, directory: dir, root: dir, reach: dir )
|
|
40
|
+
end
|
|
41
|
+
allow(@mock_locator).to receive(:search_directories) { |placement| [placement.directory] }
|
|
36
42
|
|
|
37
43
|
@standins = described_class.new(
|
|
38
44
|
configurator: @configurator, loginator: @loginator, reportinator: @reportinator,
|
|
@@ -110,9 +116,33 @@ describe StandinHeaderinator do
|
|
|
110
116
|
expect(dirs).to eq( ['build/test/mocks/a_test/drivers'] )
|
|
111
117
|
end
|
|
112
118
|
|
|
113
|
-
|
|
119
|
+
# The test's #include reaches the stand-in only from the directory the folder climbs from, so it must exist
|
|
120
|
+
it "writes a climbing folder's stand-in where its mock will be, giving and making the directory it is reached from" do
|
|
121
|
+
climbing = MockLocator::MockPlacement.new( folder: '../x', directory: 'build/test/mocks/a_test/_up_/x', root: 'build/test/mocks/a_test/_up_/_up_', reach: 'build/test/mocks/a_test/_up_/_up_' )
|
|
122
|
+
allow(@mock_locator).to receive(:placement).with( mocks_root: 'build/test/mocks/a_test', subdir: 'drivers', include_path: '../x/MockFoo.h' ).and_return( climbing )
|
|
123
|
+
allow(@mock_locator).to receive(:search_directories).with( climbing ).and_return( [climbing.directory, climbing.root] )
|
|
124
|
+
|
|
125
|
+
expect(@file_wrapper).to receive(:mkdir).with( 'build/test/mocks/a_test/_up_/_up_' )
|
|
126
|
+
expect(@file_wrapper).to receive(:write).with( 'build/test/mocks/a_test/_up_/x/MockFoo.h', anything )
|
|
127
|
+
|
|
128
|
+
expect(@standins.place( @testable, [Include.new( '../x/MockFoo.h' )] ))
|
|
129
|
+
.to eq( ['build/test/mocks/a_test/_up_/x', 'build/test/mocks/a_test/_up_/_up_'] )
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# The real mock opens with the header as CMock names it, by the folder CMock is given
|
|
133
|
+
it "includes the header by the folder its mock is named by" do
|
|
134
|
+
named = MockLocator::MockPlacement.new( folder: 'drivers', directory: 'build/test/mocks/a_test/drivers', root: 'build/test/mocks/a_test', reach: 'build/test/mocks/a_test' )
|
|
135
|
+
allow(@mock_locator).to receive(:placement).and_return( named )
|
|
136
|
+
|
|
137
|
+
expect(@file_wrapper).to receive(:write).with( 'build/test/mocks/a_test/drivers/MockFoo.h', "#{StandinHeaderinator::MARKER}\n#include \"drivers/foo.h\"\n" )
|
|
138
|
+
|
|
139
|
+
@standins.place( @testable, [Include.new( 'drivers/MockFoo.h' )] )
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "places no stand-in and gives no directories when the test has no mock root" do
|
|
114
143
|
@testable.paths = {}
|
|
115
144
|
|
|
145
|
+
expect(@file_wrapper).to_not receive(:write)
|
|
116
146
|
expect(@standins.place( @testable, [Include.new( 'MockFoo.h' )] )).to eq( [] )
|
|
117
147
|
end
|
|
118
148
|
|
|
@@ -9,6 +9,7 @@ require 'spec_helper'
|
|
|
9
9
|
require 'ceedling/filename_extension'
|
|
10
10
|
require 'rake'
|
|
11
11
|
require 'ceedling/test_invoker/test_build_executor'
|
|
12
|
+
require 'ceedling/test_invoker/mock_locator'
|
|
12
13
|
require 'ceedling/test_invoker/test_invoker_types'
|
|
13
14
|
require 'ceedling/partials/partials'
|
|
14
15
|
require 'ceedling/test_context_extractor'
|
|
@@ -35,6 +36,7 @@ describe TestBuildExecutor do
|
|
|
35
36
|
@gcc_dependency_parser = double( "GccDependencyParser" )
|
|
36
37
|
@quote_include_isolator = double( "QuoteIncludeIsolator" )
|
|
37
38
|
@generator_helper = double( "GeneratorHelper" )
|
|
39
|
+
@library_resolver = double( "LibraryResolver" )
|
|
38
40
|
|
|
39
41
|
@tools_test_compiler = { name: 'fake compiler' }
|
|
40
42
|
@tools_test_assembler = { name: 'fake assembler' }
|
|
@@ -107,6 +109,8 @@ describe TestBuildExecutor do
|
|
|
107
109
|
allow(@dependinator).to receive(:stale?).and_return( true )
|
|
108
110
|
allow(@dependinator).to receive(:mark_fresh)
|
|
109
111
|
allow(@test_source_file_directive_resolver).to receive(:validate!)
|
|
112
|
+
allow(@library_resolver).to receive(:link_files).and_return( [] )
|
|
113
|
+
allow(@library_resolver).to receive(:search_path_arguments).and_return( [] )
|
|
110
114
|
|
|
111
115
|
@executor = described_class.new(
|
|
112
116
|
{
|
|
@@ -123,7 +127,11 @@ describe TestBuildExecutor do
|
|
|
123
127
|
:dependinator => @dependinator,
|
|
124
128
|
:gcc_dependency_parser => @gcc_dependency_parser,
|
|
125
129
|
:quote_include_isolator => @quote_include_isolator,
|
|
126
|
-
:generator_helper => @generator_helper
|
|
130
|
+
:generator_helper => @generator_helper,
|
|
131
|
+
:library_resolver => @library_resolver,
|
|
132
|
+
:mock_locator => MockLocator.new(
|
|
133
|
+
configurator: @configurator, include_pathinator: double( 'include_pathinator' ), file_finder: @file_finder, file_path_utils: @file_path_utils
|
|
134
|
+
)
|
|
127
135
|
}
|
|
128
136
|
)
|
|
129
137
|
|
|
@@ -1059,12 +1067,42 @@ describe TestBuildExecutor do
|
|
|
1059
1067
|
expect(@dependinator).to receive(:register).with(
|
|
1060
1068
|
'build/a_test.out',
|
|
1061
1069
|
files: ['build/foo.o'],
|
|
1062
|
-
meta: { flags: [], lib_args: [], lib_paths: [], tools: [@tools_test_linker] }
|
|
1070
|
+
meta: { flags: [], lib_args: [], lib_paths: [], tools: [@tools_test_linker], objects: ['build/foo.o'], libraries: [] }
|
|
1063
1071
|
)
|
|
1064
1072
|
|
|
1065
1073
|
@executor.stage_build_executables( @state )
|
|
1066
1074
|
end
|
|
1067
1075
|
|
|
1076
|
+
# GH #1368: a library rebuilt under the same name changed nothing a link registered
|
|
1077
|
+
it "registers the library files its libraries resolve to, as files and as meta" do
|
|
1078
|
+
allow(@dependinator).to receive(:stale?).and_return( false )
|
|
1079
|
+
allow(@configurator).to receive(:project_config_hash).and_return( { libraries_test: ['x'] } )
|
|
1080
|
+
stub_const( 'LIBRARIES_SYSTEM', ['m', 'fusion'] )
|
|
1081
|
+
|
|
1082
|
+
expect(@library_resolver).to receive(:link_files).with( ['x', 'm', 'fusion'] ).and_return( ['vendor/lib/libx.a', 'build/deps/libfusion.so.1'] )
|
|
1083
|
+
expect(@dependinator).to receive(:register).with(
|
|
1084
|
+
'build/a_test.out',
|
|
1085
|
+
files: ['build/foo.o', 'vendor/lib/libx.a', 'build/deps/libfusion.so.1'],
|
|
1086
|
+
meta: hash_including( libraries: ['vendor/lib/libx.a', 'build/deps/libfusion.so.1'] )
|
|
1087
|
+
)
|
|
1088
|
+
|
|
1089
|
+
@executor.stage_build_executables( @state )
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
# Staleness checks only the objects registered this build, so an object dropped from the
|
|
1093
|
+
# link changes nothing they see. The list itself, as meta, does change (a source deleted,
|
|
1094
|
+
# excluded, or moved out of the configured paths).
|
|
1095
|
+
it "registers the objects it links as meta, as a plain list" do
|
|
1096
|
+
allow(@dependinator).to receive(:stale?).and_return( false )
|
|
1097
|
+
@testable.objects = FileList.new.tap { |list| list << 'build/foo.o' }
|
|
1098
|
+
|
|
1099
|
+
expect(@dependinator).to receive(:register).with( 'build/a_test.out', files: ['build/foo.o'], meta: hash_including( objects: ['build/foo.o'] ) ) do |_, files:, meta:|
|
|
1100
|
+
expect(meta[:objects]).to be_an_instance_of( Array )
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
@executor.stage_build_executables( @state )
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1068
1106
|
it "logs a summary line stating how many executables were recalled from cache" do
|
|
1069
1107
|
allow(@dependinator).to receive(:stale?).and_return( false )
|
|
1070
1108
|
|
|
@@ -1658,7 +1696,7 @@ describe TestBuildExecutor do
|
|
|
1658
1696
|
include_as( 'sub/MockFoo.h' )
|
|
1659
1697
|
|
|
1660
1698
|
expect(@generator).to receive(:generate_mock)
|
|
1661
|
-
.with( hash_including( output_path: 'build/test/mocks/sub', folder: 'sub' ) )
|
|
1699
|
+
.with( hash_including( output_path: 'build/test/mocks/sub', mock_root: 'build/test/mocks', folder: 'sub' ) )
|
|
1662
1700
|
|
|
1663
1701
|
@executor.stage_generate_mocks( @state )
|
|
1664
1702
|
end
|
|
@@ -1685,6 +1723,30 @@ describe TestBuildExecutor do
|
|
|
1685
1723
|
@executor.stage_generate_mocks( @state )
|
|
1686
1724
|
end
|
|
1687
1725
|
|
|
1726
|
+
# The path handling audit around GH #1370: a folder that climbs must not carry the
|
|
1727
|
+
# mock out of its test's mocks directory
|
|
1728
|
+
it "G14: keeps the mock below its test's mocks directory for a folder that climbs" do
|
|
1729
|
+
include_as( '../x/MockFoo.h' )
|
|
1730
|
+
|
|
1731
|
+
expect(@generator).to receive(:generate_mock) do |args|
|
|
1732
|
+
expect(args[:output_path].split( '/' )).to_not include( '..' )
|
|
1733
|
+
end
|
|
1734
|
+
|
|
1735
|
+
@executor.stage_generate_mocks( @state )
|
|
1736
|
+
end
|
|
1737
|
+
|
|
1738
|
+
# The compiler finds the mock as written only through CMock's root, so it must exist
|
|
1739
|
+
it "roots CMock as deep as a climbing folder climbs, and makes that root" do
|
|
1740
|
+
include_as( '../x/MockFoo.h' )
|
|
1741
|
+
|
|
1742
|
+
expect(@file_wrapper).to receive(:mkdir).with( 'build/test/mocks/_up_/x' )
|
|
1743
|
+
expect(@file_wrapper).to receive(:mkdir).with( 'build/test/mocks/_up_/_up_' )
|
|
1744
|
+
expect(@generator).to receive(:generate_mock)
|
|
1745
|
+
.with( hash_including( output_path: 'build/test/mocks/_up_/x', mock_root: 'build/test/mocks/_up_/_up_', folder: '../x' ) )
|
|
1746
|
+
|
|
1747
|
+
@executor.stage_generate_mocks( @state )
|
|
1748
|
+
end
|
|
1749
|
+
|
|
1688
1750
|
it "passes no folder when :mock_name_include_folder is disabled" do
|
|
1689
1751
|
allow(@configurator).to receive(:cmock_mock_name_include_folder).and_return( false )
|
|
1690
1752
|
include_as( 'sub/MockFoo.h' )
|
|
@@ -25,6 +25,8 @@ EXTENSION_HEADER = FilenameExtension.new('.h') unless defined?(EXTENSION_
|
|
|
25
25
|
describe TestBuildPlanner do
|
|
26
26
|
before(:each) do
|
|
27
27
|
@configurator = double( "Configurator" )
|
|
28
|
+
# Ceedling always defaults it, and the mock locator reads it
|
|
29
|
+
allow(@configurator).to receive(:cmock_mock_name_include_folder).and_return( true )
|
|
28
30
|
@loginator = double( "Loginator" )
|
|
29
31
|
@reportinator = double( "Reportinator" )
|
|
30
32
|
@batchinator = double( "Batchinator" )
|
|
@@ -167,6 +169,7 @@ describe TestBuildPlanner do
|
|
|
167
169
|
|
|
168
170
|
context "with a non-Partial mocked header" do
|
|
169
171
|
before(:each) do
|
|
172
|
+
allow(@file_path_utils).to receive(:form_mock_output_path) { |root, subdir| subdir.to_s.empty? ? root : File.join( root, subdir ) }
|
|
170
173
|
mock = MockInclude.new( 'MockFoo.h' )
|
|
171
174
|
allow(@test_context_extractor).to receive(:lookup_mock_header_includes_list)
|
|
172
175
|
.with( 'test/TestFoo.c' ).and_return( [mock] )
|
|
@@ -204,6 +207,45 @@ describe TestBuildPlanner do
|
|
|
204
207
|
end
|
|
205
208
|
end
|
|
206
209
|
|
|
210
|
+
# Two headers directly in two include roots mirror alike, and only their #include
|
|
211
|
+
# folders tell their mocks apart
|
|
212
|
+
it "keeps two same-named mocks whose #include folders alone differ" do
|
|
213
|
+
allow(@test_context_extractor).to receive(:lookup_mock_header_includes_list)
|
|
214
|
+
.with( 'test/TestFoo.c' ).and_return( [MockInclude.new( 'a/MockFoo.h' ), MockInclude.new( 'b/MockFoo.h' )] )
|
|
215
|
+
allow(@configurator).to receive(:cmock_mock_prefix).and_return( 'Mock' )
|
|
216
|
+
allow(@configurator).to receive(:project_use_test_preprocessor_mocks).and_return( false )
|
|
217
|
+
allow(@file_finder).to receive(:resolve_mock).with( 'a/MockFoo.h', collection: [], complain: :error ).and_return( ['inc/a/foo.h', ''] )
|
|
218
|
+
allow(@file_finder).to receive(:resolve_mock).with( 'b/MockFoo.h', collection: [], complain: :error ).and_return( ['inc/b/foo.h', ''] )
|
|
219
|
+
allow(@file_path_utils).to receive(:form_preprocessed_file_filepath).and_return( 'unused' )
|
|
220
|
+
|
|
221
|
+
@planner.stage_determine_files( @state )
|
|
222
|
+
|
|
223
|
+
expect(@testable.mocks.keys).to contain_exactly( :'a/MockFoo', :'b/MockFoo' )
|
|
224
|
+
expect(@testable.mocks.values.map( &:source )).to contain_exactly( 'inc/a/foo.h', 'inc/b/foo.h' )
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Nothing in the loop over a test's mocks changes its search paths, so one collection
|
|
228
|
+
# serves every mock. Validation lists the whole search paths, mock directories included.
|
|
229
|
+
it "builds one mock header collection for all of a test's real mocks" do
|
|
230
|
+
mocks = %w[MockFoo.h MockBar.h MockBaz.h].map { |name| MockInclude.new( name ) }
|
|
231
|
+
allow(@test_context_extractor).to receive(:lookup_mock_header_includes_list).with( 'test/TestFoo.c' ).and_return( mocks )
|
|
232
|
+
allow(@configurator).to receive(:cmock_mock_prefix).and_return( 'Mock' )
|
|
233
|
+
allow(@configurator).to receive(:project_use_test_preprocessor_mocks).and_return( false )
|
|
234
|
+
allow(@file_finder).to receive(:resolve_mock) { |mock, **| ["src/#{mock.delete_prefix( 'Mock' )}", ''] }
|
|
235
|
+
allow(@file_path_utils).to receive(:form_preprocessed_file_filepath).and_return( 'unused' )
|
|
236
|
+
allow(@file_path_utils).to receive(:form_mock_output_path) { |root, subdir| subdir.to_s.empty? ? root : File.join( root, subdir ) }
|
|
237
|
+
@testable.search_paths = ['build/test/mocks/a_test', 'src']
|
|
238
|
+
@testable.mock_search_paths = ['build/test/mocks/a_test']
|
|
239
|
+
|
|
240
|
+
collections = 0
|
|
241
|
+
allow(@include_pathinator).to receive(:ordered_header_files).with( ['src'] ) { collections += 1; ['src/Foo.h'] }
|
|
242
|
+
|
|
243
|
+
@planner.stage_determine_files( @state )
|
|
244
|
+
|
|
245
|
+
expect(@testable.mocks.length).to eq( 3 )
|
|
246
|
+
expect(collections).to eq( 1 )
|
|
247
|
+
end
|
|
248
|
+
|
|
207
249
|
context "with a Partial mocked header" do
|
|
208
250
|
before(:each) do
|
|
209
251
|
mock = MockInclude.new( 'Mockceedling_partial_foo_interface.h' )
|
|
@@ -217,6 +259,15 @@ describe TestBuildPlanner do
|
|
|
217
259
|
|
|
218
260
|
# A Partial mock has no real header to resolve against, so its directory comes
|
|
219
261
|
# from the generated #include rather than from a mirrored source location.
|
|
262
|
+
it "builds no mock header collection, having no real header to resolve" do
|
|
263
|
+
@testable.search_paths = ['build/test/mocks/a_test', 'src']
|
|
264
|
+
@testable.mock_search_paths = ['build/test/mocks/a_test']
|
|
265
|
+
|
|
266
|
+
expect(@include_pathinator).to_not receive(:ordered_header_files).with( ['src'] )
|
|
267
|
+
|
|
268
|
+
@planner.stage_determine_files( @state )
|
|
269
|
+
end
|
|
270
|
+
|
|
220
271
|
it "stays flat when its generated #include names no directory" do
|
|
221
272
|
expect(@file_finder).to_not receive(:resolve_mock)
|
|
222
273
|
|
|
@@ -431,6 +482,23 @@ describe TestBuildPlanner do
|
|
|
431
482
|
expect( captured ).to include('build/test/mocks/a_test/drivers/spi/Mockconfig.c')
|
|
432
483
|
end
|
|
433
484
|
|
|
485
|
+
it "compiles a mock whose #include folder climbs from where it is written, below the mock root" do
|
|
486
|
+
allow(@configurator).to receive(:cmock_mock_name_include_folder).and_return( true )
|
|
487
|
+
@testable.mocks = {
|
|
488
|
+
:'x/Mockconfig' => TestInvokerTypes::MockDetails.new( name: 'Mockconfig', path: 'x', partial: false, include_path: '../x/Mockconfig.h' )
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
captured = nil
|
|
492
|
+
allow(@file_path_utils).to receive(:form_test_build_objects_filelist) do |_path, files, **_kw|
|
|
493
|
+
captured ||= files
|
|
494
|
+
[]
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
@planner.stage_determine_artifacts( @state )
|
|
498
|
+
|
|
499
|
+
expect( captured ).to include('build/test/mocks/a_test/_up_/x/Mockconfig.c')
|
|
500
|
+
end
|
|
501
|
+
|
|
434
502
|
# A mock and a generated Partial both sit below their own generated root rather than a
|
|
435
503
|
# configured source root, so nothing in the standard roots mirrors them. Without those
|
|
436
504
|
# roots, two same-named mocks or modules collapse onto one object filename.
|
|
@@ -484,7 +552,9 @@ describe TestBuildPlanner do
|
|
|
484
552
|
allow(@test_source_file_directive_resolver).to receive(:resolve)
|
|
485
553
|
.with( 'test/TestFoo.c', :test ).and_return( [['src/Foo.c'], {}] )
|
|
486
554
|
allow(@test_context_extractor).to receive(:lookup_source_includes_list)
|
|
487
|
-
.with( 'test/TestFoo.c' ).and_return( ['src/Foo.c'] )
|
|
555
|
+
.with( 'test/TestFoo.c' ).and_return( [UserInclude.new( 'src/Foo.c' )] )
|
|
556
|
+
allow(@file_finder).to receive(:find_build_input_file)
|
|
557
|
+
.with( filepath: 'src/Foo.c', complain: :ignore, context: :test, test: 'a_test' ).and_return( 'src/Foo.c' )
|
|
488
558
|
end
|
|
489
559
|
|
|
490
560
|
it "resolves it as a source to compile but excludes its object from what gets linked" do
|
|
@@ -494,6 +564,25 @@ describe TestBuildPlanner do
|
|
|
494
564
|
expect(@testable.objects).to_not include( 'src/Foo.o' )
|
|
495
565
|
end
|
|
496
566
|
end
|
|
567
|
+
|
|
568
|
+
# A test #includes a source by the name its own #include spells, and that source's object
|
|
569
|
+
# sits at the source's path, not the #include's
|
|
570
|
+
context "when a test #includes a source by its name alone" do
|
|
571
|
+
before(:each) do
|
|
572
|
+
allow(@test_source_file_directive_resolver).to receive(:resolve)
|
|
573
|
+
.with( 'test/TestFoo.c', :test ).and_return( [['src/Foo.c'], {}] )
|
|
574
|
+
allow(@test_context_extractor).to receive(:lookup_source_includes_list)
|
|
575
|
+
.with( 'test/TestFoo.c' ).and_return( [UserInclude.new( 'Foo.c' )] )
|
|
576
|
+
allow(@file_finder).to receive(:find_build_input_file)
|
|
577
|
+
.with( filepath: 'Foo.c', complain: :ignore, context: :test, test: 'a_test' ).and_return( 'src/Foo.c' )
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
it "excludes the object of the source it names from what gets linked" do
|
|
581
|
+
@planner.stage_determine_artifacts( @state )
|
|
582
|
+
|
|
583
|
+
expect(@testable.objects).to_not include( 'src/Foo.o' )
|
|
584
|
+
end
|
|
585
|
+
end
|
|
497
586
|
end
|
|
498
587
|
|
|
499
588
|
describe "#stage_flatten_objects_list" do
|
|
@@ -696,7 +785,20 @@ describe TestBuildPlanner do
|
|
|
696
785
|
|
|
697
786
|
result = @planner.collect_test_framework_sources( true )
|
|
698
787
|
|
|
699
|
-
expect(result).to include( 'test/support/unity_helper' )
|
|
788
|
+
expect(result).to include( 'test/support/unity_helper.c' )
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
# The path handling audit around GH #1370: :unity_helper_path names the helper's header,
|
|
792
|
+
# and its source is what compiles
|
|
793
|
+
it "G25: compiles the source beside a Unity helper named by its header" do
|
|
794
|
+
allow(@configurator).to receive(:project_use_mocks).and_return( true )
|
|
795
|
+
allow(@configurator).to receive(:cmock_unity_helper_path).and_return( ['test/support/unity_helper.h'] )
|
|
796
|
+
allow(@file_wrapper).to receive(:exist?).with( 'test/support/unity_helper.c' ).and_return( true )
|
|
797
|
+
|
|
798
|
+
result = @planner.collect_test_framework_sources( true )
|
|
799
|
+
|
|
800
|
+
expect(result).to include( 'test/support/unity_helper.c' )
|
|
801
|
+
expect(result).to_not include( 'test/support/unity_helper.h' )
|
|
700
802
|
end
|
|
701
803
|
|
|
702
804
|
it "omits a Unity helper source file that doesn't exist on disk" do
|