ceedling 1.2.0 → 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 +57 -58
- data/Rakefile +5 -3
- 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 +35 -1
- data/bin/ceedling +13 -3
- data/bin/cli.rb +25 -6
- data/bin/cli_handler.rb +119 -73
- data/bin/cli_helper.rb +56 -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 +84 -3
- data/docs/KnownIssues.md +90 -4
- data/docs/ReleaseNotes.md +13 -0
- data/docs/overrides/main.html +11 -8
- 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 +19 -18
- 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 +39 -41
- 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} +65 -28
- 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/rake_app/test_task_name.rb +29 -0
- data/lib/ceedling/rakefile.rb +16 -1
- data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
- data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
- data/lib/ceedling/rakefiles/tests/rules_tests.rake +3 -20
- data/lib/ceedling/rakefiles/tests/rules_tests_generate.rake +4 -30
- 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 +95 -87
- 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 +42 -41
- 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/bullseye.rake +6 -9
- 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/gcov.rake +6 -9
- 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/sanitize/sanitize.rake +6 -6
- data/plugins/valgrind/lib/valgrind.rb +14 -7
- data/plugins/valgrind/valgrind.rake +6 -6
- data/site-local/404.html +6 -20
- data/site-local/assets/javascripts/{bundle.d7400e89.min.js → bundle.c21346df.min.js} +3 -3
- data/site-local/assets/javascripts/{bundle.d7400e89.min.js.map → bundle.c21346df.min.js.map} +2 -2
- data/site-local/assets/javascripts/workers/{search.2c215733.min.js → search.a7633da7.min.js} +2 -2
- data/site-local/assets/javascripts/workers/{search.2c215733.min.js.map → search.a7633da7.min.js.map} +1 -1
- data/site-local/assets/stylesheets/main.57a0d79d.min.css +6 -0
- data/site-local/assets/stylesheets/main.57a0d79d.min.css.map +1 -0
- data/site-local/assets/stylesheets/palette.fb2fffe2.min.css +4 -0
- data/site-local/assets/stylesheets/palette.fb2fffe2.min.css.map +1 -0
- data/site-local/configuration/environment-vars.html +6 -20
- data/site-local/configuration/global-collections.html +6 -20
- data/site-local/configuration/index.html +6 -20
- data/site-local/configuration/loading.html +6 -20
- data/site-local/configuration/mixins.html +10 -24
- data/site-local/configuration/parallel-builds.html +6 -20
- data/site-local/configuration/project-file.html +8 -22
- data/site-local/configuration/reference/cexception.html +6 -20
- data/site-local/configuration/reference/cmock.html +8 -21
- data/site-local/configuration/reference/defines.html +16 -30
- data/site-local/configuration/reference/environment.html +10 -24
- data/site-local/configuration/reference/extension.html +6 -20
- data/site-local/configuration/reference/files.html +22 -30
- data/site-local/configuration/reference/flags.html +13 -27
- data/site-local/configuration/reference/index.html +6 -20
- data/site-local/configuration/reference/libraries.html +27 -23
- data/site-local/configuration/reference/mixins.html +6 -20
- data/site-local/configuration/reference/partials.html +6 -20
- data/site-local/configuration/reference/paths.html +38 -29
- data/site-local/configuration/reference/plugins.html +6 -20
- data/site-local/configuration/reference/project.html +32 -36
- data/site-local/configuration/reference/release-build.html +8 -20
- data/site-local/configuration/reference/test-build.html +6 -20
- data/site-local/configuration/reference/test-runner.html +6 -20
- data/site-local/configuration/reference/tools.html +27 -32
- data/site-local/configuration/reference/unity.html +6 -20
- data/site-local/configuration/which-ceedling.html +383 -37
- data/site-local/development/index.html +6 -20
- data/site-local/development/plugins/configuration.html +6 -20
- data/site-local/development/plugins/index.html +6 -20
- data/site-local/development/plugins/plugin-subclass.html +54 -68
- data/site-local/development/plugins/rake-tasks.html +8 -22
- data/site-local/development/releases.html +84 -29
- data/site-local/development/workflow.html +62 -71
- data/site-local/getting-started/builds.html +8 -20
- data/site-local/getting-started/command-line.html +62 -24
- data/site-local/getting-started/example-projects/cipher-quest.html +6 -20
- data/site-local/getting-started/example-projects/index.html +6 -20
- data/site-local/getting-started/example-projects/temp-sensor.html +6 -20
- data/site-local/getting-started/example-projects/wondrous-forest.html +6 -20
- data/site-local/getting-started/index.html +6 -20
- data/site-local/getting-started/installation.html +6 -20
- data/site-local/getting-started/quick-start.html +6 -20
- data/site-local/help.html +6 -20
- data/site-local/index.html +11 -24
- data/site-local/overview/build-system.html +6 -20
- data/site-local/overview/index.html +6 -20
- data/site-local/overview/test-environments.html +6 -20
- data/site-local/overview/tools-and-frameworks.html +6 -20
- data/site-local/plugins/beep.html +6 -20
- data/site-local/plugins/bullseye/index.html +13 -24
- data/site-local/plugins/bullseye/licensing.html +14 -28
- data/site-local/plugins/command-hooks.html +8 -22
- data/site-local/plugins/compile-commands-json-db.html +6 -20
- data/site-local/plugins/cppcheck.html +8 -22
- data/site-local/plugins/dependencies.html +16 -27
- data/site-local/plugins/fff.html +49 -32
- data/site-local/plugins/gcov/examples.html +7 -21
- data/site-local/plugins/gcov/gcovr.html +22 -33
- data/site-local/plugins/gcov/index.html +6 -20
- data/site-local/plugins/gcov/overview.html +9 -20
- data/site-local/plugins/gcov/reportgenerator.html +9 -23
- data/site-local/plugins/gcov/reporting.html +6 -20
- data/site-local/plugins/gcov/setup.html +8 -21
- data/site-local/plugins/gcov/tool-versions.html +6 -20
- data/site-local/plugins/gcov/troubleshooting.html +10 -24
- data/site-local/plugins/index.html +6 -20
- data/site-local/plugins/module-generator.html +21 -35
- data/site-local/plugins/report-build-warnings-log.html +53 -67
- data/site-local/plugins/report-tests-gtestlike-stdout.html +6 -20
- data/site-local/plugins/report-tests-ide-stdout.html +43 -57
- data/site-local/plugins/report-tests-log-factory.html +50 -64
- data/site-local/plugins/report-tests-pretty-stdout.html +7 -21
- data/site-local/plugins/report-tests-raw-output-log.html +9 -21
- data/site-local/plugins/report-tests-teamcity-stdout.html +20 -31
- data/site-local/plugins/sanitize.html +56 -65
- data/site-local/plugins/valgrind.html +49 -58
- data/site-local/project/index.html +6 -20
- data/site-local/project/release-history.html +6 -20
- data/site-local/project/sbom.html +6 -20
- data/site-local/project/upgrade.html +9 -20
- data/site-local/reference/build-directives.html +6 -20
- data/site-local/reference/command-line.html +15 -22
- data/site-local/reference/environment-vars.html +6 -20
- data/site-local/reference/gcov-plugin.html +6 -20
- data/site-local/reference/global-collections.html +6 -20
- data/site-local/reference/index.html +6 -20
- data/site-local/reference/partials-macros.html +6 -20
- data/site-local/reference/project-configuration.html +6 -20
- data/site-local/sitemap.xml.gz +0 -0
- data/site-local/snapshot/examples/cipher_quest/index.html +16 -30
- data/site-local/snapshot/examples/temp_sensor/index.html +8 -22
- data/site-local/snapshot/examples/wondrous_forest/index.html +6 -20
- 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/build-directives.html +14 -28
- data/site-local/testing-guide/conventions.html +66 -27
- data/site-local/testing-guide/frameworks.html +11 -25
- data/site-local/testing-guide/index.html +6 -20
- data/site-local/testing-guide/partials/configuration.html +8 -22
- data/site-local/testing-guide/partials/conventions.html +8 -22
- data/site-local/testing-guide/partials/directives.html +16 -30
- data/site-local/testing-guide/partials/example.html +14 -28
- data/site-local/testing-guide/partials/index.html +6 -20
- data/site-local/testing-guide/partials/overview.html +6 -20
- data/site-local/testing-guide/partials/variables.html +11 -25
- data/site-local/testing-guide/test-cases.html +13 -27
- data/site-local/testing-guide/test-sample.html +12 -26
- data/site-local/testing-guide/test-suite-anatomy.html +6 -20
- 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_pipeline_spec.rb +10 -0
- 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 +62 -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/rake_task_registry_plugins_spec.rb +95 -0
- 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 +192 -75
- data/spec/support/file_tree_helper.rb +88 -0
- data/spec/support/integration/configurator_integration_helper.rb +10 -7
- 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 +47 -0
- data/spec/units/bin/cli_handler_spec.rb +284 -7
- data/spec/units/bin/cli_helper_spec.rb +126 -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 +65 -103
- data/spec/units/config/configurator_spec.rb +37 -6
- 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} +154 -32
- 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/rake_app/test_task_name_spec.rb +47 -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 +107 -5
- 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 +122 -33
- data/lib/ceedling/file_path_collection_utils.rb +0 -164
- data/site-local/assets/stylesheets/main.ec1eaa64.min.css +0 -1
- data/site-local/assets/stylesheets/main.ec1eaa64.min.css.map +0 -1
- data/site-local/assets/stylesheets/palette.ab4e12ef.min.css +0 -1
- data/site-local/assets/stylesheets/palette.ab4e12ef.min.css.map +0 -1
|
@@ -11,21 +11,17 @@ require 'ceedling/config/configurator_validator'
|
|
|
11
11
|
require 'ceedling/config/config_walkinator'
|
|
12
12
|
require 'ceedling/reportinator'
|
|
13
13
|
|
|
14
|
-
# Unit coverage for ConfiguratorValidator
|
|
15
|
-
# validations make of a real project tree is proven in
|
|
16
|
-
# spec/integration/configurator_validation_spec.rb.
|
|
14
|
+
# Unit coverage for ConfiguratorValidator's checks of required entries, tools, and matchers
|
|
17
15
|
describe ConfiguratorValidator do
|
|
18
16
|
include ConfigYamlHelper
|
|
19
17
|
|
|
20
18
|
before(:each) do
|
|
21
|
-
@file_wrapper = double('file_wrapper')
|
|
22
19
|
@loginator = double('loginator', log: nil)
|
|
23
20
|
@tool_validator = double('tool_validator')
|
|
24
21
|
|
|
25
22
|
@validator = described_class.new(
|
|
26
23
|
{
|
|
27
24
|
config_walkinator: ConfigWalkinator.new,
|
|
28
|
-
file_wrapper: @file_wrapper,
|
|
29
25
|
loginator: @loginator,
|
|
30
26
|
reportinator: Reportinator.new,
|
|
31
27
|
tool_validator: @tool_validator
|
|
@@ -33,14 +29,6 @@ describe ConfiguratorValidator do
|
|
|
33
29
|
)
|
|
34
30
|
end
|
|
35
31
|
|
|
36
|
-
def existing(*paths)
|
|
37
|
-
allow(@file_wrapper).to receive(:exist?) { |path| paths.include?( path ) }
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def directories(*paths)
|
|
41
|
-
allow(@file_wrapper).to receive(:directory?) { |path| paths.include?( path ) }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
32
|
describe '#exists?' do
|
|
45
33
|
let(:config) { config_from_yaml( ":project:\n :build_root: build\n :use_mocks: false\n" ) }
|
|
46
34
|
|
|
@@ -58,165 +46,6 @@ describe ConfiguratorValidator do
|
|
|
58
46
|
end
|
|
59
47
|
end
|
|
60
48
|
|
|
61
|
-
describe '#validate_path_list' do
|
|
62
|
-
let(:config) { config_from_yaml( ":paths:\n :test:\n - +:test/**\n - -:test/ignore\n - '**/generated'\n" ) }
|
|
63
|
-
|
|
64
|
-
it 'checks each path stripped of its aggregation decorator and glob' do
|
|
65
|
-
existing('test', 'test/ignore')
|
|
66
|
-
expect(@validator.validate_path_list( config, :paths, :test )).to be true
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it 'skips a path that begins with a glob' do
|
|
70
|
-
existing('test', 'test/ignore')
|
|
71
|
-
@validator.validate_path_list( config, :paths, :test )
|
|
72
|
-
expect(@file_wrapper).to_not have_received(:exist?).with('')
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'logs each path that does not exist' do
|
|
76
|
-
existing('test')
|
|
77
|
-
expect(@validator.validate_path_list( config, :paths, :test )).to be false
|
|
78
|
-
expect(@loginator).to have_received(:log).with("Config path :paths ↳ :test => 'test/ignore' does not exist in the filesystem.", Verbosity::ERRORS)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
it 'fails a missing entry' do
|
|
82
|
-
expect(@validator.validate_path_list( config, :paths, :source )).to be false
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# An entry naming no path, or wrapping its path in quotes, is rejected before any
|
|
87
|
-
# filesystem check. Both usually come from quoting only the path after a +: or -:
|
|
88
|
-
# decoration, so each rejection carries a hint about quoting.
|
|
89
|
-
shared_examples 'an entry that names no usable path' do |walk|
|
|
90
|
-
{
|
|
91
|
-
'a bare subtractive decoration' => " - '-:'\n",
|
|
92
|
-
'a bare additive decoration' => " - '+:'\n",
|
|
93
|
-
'an empty string' => " - ''\n",
|
|
94
|
-
'whitespace alone' => " - ' '\n",
|
|
95
|
-
'a YAML null' => " -\n",
|
|
96
|
-
}.each_pair do |label, yaml|
|
|
97
|
-
it "rejects #{label} as naming no path, with a quoting hint" do
|
|
98
|
-
expect(validate( yaml )).to be false
|
|
99
|
-
expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '.*' names no path/, Verbosity::ERRORS)
|
|
100
|
-
expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# YAML reads an unquoted decoration with nothing after it as a one-key mapping
|
|
105
|
-
it 'rejects an entry YAML read as something other than a path, with a quoting hint' do
|
|
106
|
-
expect(validate( " - -:\n" )).to be false
|
|
107
|
-
expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '.*' is not a path \(YAML read it as a Hash\)/, Verbosity::ERRORS)
|
|
108
|
-
expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it 'rejects a path wrapped in quotes after its decoration, with a quoting hint' do
|
|
112
|
-
expect(validate( " - '-:\"src/a.c\"'\n" )).to be false
|
|
113
|
-
expect(@loginator).to have_received(:log).with(/#{Regexp.escape(walk)} => '-:"src\/a.c"' wraps its path in quotes/, Verbosity::ERRORS)
|
|
114
|
-
expect(@loginator).to have_received(:log).with(/Quote the whole entry/, Verbosity::ERRORS)
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
describe '#validate_paths_entries' do
|
|
119
|
-
def validate(yaml_list)
|
|
120
|
-
@validator.validate_paths_entries( config_from_yaml( ":paths:\n :source:\n#{yaml_list}" ), :source )
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
it 'accepts a glob that yields directories' do
|
|
124
|
-
existing; directories('src', 'src/a')
|
|
125
|
-
allow(@file_wrapper).to receive(:directory_listing).with('src/**/**').and_return(['src', 'src/a', 'src/a/x.c'])
|
|
126
|
-
|
|
127
|
-
expect(validate( " - src/**\n" )).to be true
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it 'warns about and skips a path naming a file' do
|
|
131
|
-
existing('src/main.c'); directories
|
|
132
|
-
|
|
133
|
-
expect(validate( " - src/main.c\n" )).to be true
|
|
134
|
-
expect(@loginator).to have_received(:log).with(/'src\/main.c' is a filepath and will be ignored/, Verbosity::COMPLAIN)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it 'accepts a subdirectory glob of a directory that has no subdirectories' do
|
|
138
|
-
existing; directories
|
|
139
|
-
allow(@file_wrapper).to receive(:directory_listing).and_return([])
|
|
140
|
-
|
|
141
|
-
expect(validate( " - src/*\n" )).to be true
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it 'logs a path that yields no directories' do
|
|
145
|
-
existing; directories
|
|
146
|
-
allow(@file_wrapper).to receive(:directory_listing).and_return([])
|
|
147
|
-
|
|
148
|
-
expect(validate( " - -:src/missing\n" )).to be false
|
|
149
|
-
expect(@loginator).to have_received(:log).with(/'src\/missing' yielded no directories/, Verbosity::ERRORS)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
it 'escapes literal brackets before globbing' do
|
|
153
|
-
existing; directories('src/[legacy]')
|
|
154
|
-
allow(@file_wrapper).to receive(:directory_listing).with('src/\[legacy\]').and_return(['src/[legacy]'])
|
|
155
|
-
|
|
156
|
-
expect(validate( " - 'src/[legacy]'\n" )).to be true
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it 'fails a missing entry' do
|
|
160
|
-
expect(@validator.validate_paths_entries( { paths: {} }, :source )).to be false
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
it_behaves_like 'an entry that names no usable path', ':paths ↳ :source'
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
describe '#validate_files_entries' do
|
|
167
|
-
def validate(yaml_list)
|
|
168
|
-
@validator.validate_files_entries( config_from_yaml( ":files:\n :source:\n#{yaml_list}" ), :source )
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
it 'accepts a glob that yields files' do
|
|
172
|
-
existing; directories
|
|
173
|
-
allow(@file_wrapper).to receive(:instantiate_file_list).with('src/*.c').and_return(['src/a.c'])
|
|
174
|
-
|
|
175
|
-
expect(validate( " - +:src/*.c\n" )).to be true
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
it 'warns about and skips a path naming a directory' do
|
|
179
|
-
existing('src'); directories('src')
|
|
180
|
-
|
|
181
|
-
expect(validate( " - src\n" )).to be true
|
|
182
|
-
expect(@loginator).to have_received(:log).with(/'src' is a directory path and will be ignored/, Verbosity::COMPLAIN)
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
it 'logs a glob that yields no files' do
|
|
186
|
-
existing; directories
|
|
187
|
-
allow(@file_wrapper).to receive(:instantiate_file_list).and_return([])
|
|
188
|
-
|
|
189
|
-
expect(validate( " - src/*.x\n" )).to be false
|
|
190
|
-
expect(@loginator).to have_received(:log).with(/'src\/\*.x' yielded no files/, Verbosity::ERRORS)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
it 'escapes literal brackets before globbing' do
|
|
194
|
-
existing; directories
|
|
195
|
-
allow(@file_wrapper).to receive(:instantiate_file_list).with('src/\[legacy\]/*.c').and_return(['src/[legacy]/a.c'])
|
|
196
|
-
|
|
197
|
-
expect(validate( " - 'src/[legacy]/*.c'\n" )).to be true
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
it 'fails a missing entry' do
|
|
201
|
-
expect(@validator.validate_files_entries( { files: {} }, :source )).to be false
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
it_behaves_like 'an entry that names no usable path', ':files ↳ :source'
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
describe '#validate_filepath_simple' do
|
|
208
|
-
it 'accepts an existing path' do
|
|
209
|
-
existing('helper.h')
|
|
210
|
-
expect(@validator.validate_filepath_simple( 'helper.h', :cmock, :unity_helper_path )).to be true
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
it 'logs a missing path with the configuration walk it came from' do
|
|
214
|
-
existing
|
|
215
|
-
expect(@validator.validate_filepath_simple( 'helper.h', :cmock, :unity_helper_path )).to be false
|
|
216
|
-
expect(@loginator).to have_received(:log).with("Config path 'helper.h' associated with :cmock ↳ :unity_helper_path does not exist in the filesystem.", Verbosity::ERRORS)
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
49
|
describe '#validate_tool' do
|
|
221
50
|
let(:config) { { tools: { test_compiler: { executable: 'gcc' } }, extension: { executable: '.out' } } }
|
|
222
51
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# =========================================================================
|
|
2
|
+
# Ceedling - Test-Centered Build System for C
|
|
3
|
+
# ThrowTheSwitch.org
|
|
4
|
+
# Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
|
5
|
+
# SPDX-License-Identifier: MIT
|
|
6
|
+
# =========================================================================
|
|
7
|
+
|
|
8
|
+
require 'spec_helper'
|
|
9
|
+
require 'shellwords'
|
|
10
|
+
require 'yaml'
|
|
11
|
+
require 'ceedling/defaults'
|
|
12
|
+
require 'ceedling/tool_executor'
|
|
13
|
+
require 'ceedling/ruby_expandinator'
|
|
14
|
+
|
|
15
|
+
load File.expand_path( '../../plugins/gcov/config/defaults_gcov.rb', __dir__ )
|
|
16
|
+
load File.expand_path( '../../plugins/bullseye/config/defaults_bullseye.rb', __dir__ )
|
|
17
|
+
load File.expand_path( '../../plugins/cppcheck/config/defaults_cppcheck.rb', __dir__ )
|
|
18
|
+
|
|
19
|
+
# GH #1373: the default tools that run a test executable named it unquoted, so a path holding
|
|
20
|
+
# an apostrophe or a space broke the shell command. Each command here is split as a POSIX
|
|
21
|
+
# shell splits it, and every path must come back as one word, exactly as given.
|
|
22
|
+
describe 'Default tools' do
|
|
23
|
+
SPECIAL_PATH = "build/test/out/test/o'neil dir/test_q/test_q.out"
|
|
24
|
+
OTHER_PATH = "src/my dir/o'neil.c"
|
|
25
|
+
|
|
26
|
+
DEPENDENCIES_TOOLS = YAML.load_file(
|
|
27
|
+
File.expand_path( '../../plugins/dependencies/config/defaults.yml', __dir__ ), symbolize_names: true
|
|
28
|
+
)[:tools]
|
|
29
|
+
|
|
30
|
+
before(:each) do
|
|
31
|
+
helper = double('tool_executor_helper').as_null_object
|
|
32
|
+
allow(helper).to receive(:osify_path_separators) { |path| path }
|
|
33
|
+
system_wrapper = double('system_wrapper').as_null_object
|
|
34
|
+
allow(system_wrapper).to receive(:constants_include?).and_return( false )
|
|
35
|
+
|
|
36
|
+
@tool_executor = ToolExecutor.new(
|
|
37
|
+
{
|
|
38
|
+
:tool_executor_helper => helper,
|
|
39
|
+
:loginator => double('loginator').as_null_object,
|
|
40
|
+
:verbosinator => double('verbosinator').as_null_object,
|
|
41
|
+
:system_wrapper => system_wrapper,
|
|
42
|
+
:ruby_expandinator => RubyExpandinator.new
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Configuration hands Ceedling an unfrozen copy of each default tool
|
|
48
|
+
def words(tool, *args)
|
|
49
|
+
Shellwords.split( @tool_executor.build_command_line( Marshal.load( Marshal.dump( tool ) ), [], *args )[:line] )
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
{
|
|
53
|
+
'test fixture' => DEFAULT_TEST_FIXTURE_TOOL,
|
|
54
|
+
'gcov fixture' => DEFAULT_GCOV_FIXTURE_TOOL,
|
|
55
|
+
'Bullseye fixture' => DEFAULT_BULLSEYE_FIXTURE_TOOL,
|
|
56
|
+
}.each do |name, tool|
|
|
57
|
+
it "names the test executable as one word in the #{name}" do
|
|
58
|
+
expect( words( tool, SPECIAL_PATH ) ).to eq( [SPECIAL_PATH] )
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'names the test executable as one word in a simple backtrace rerun' do
|
|
63
|
+
expect( words( DEFAULT_TEST_FIXTURE_SIMPLE_BACKTRACE_TOOL, SPECIAL_PATH, '-n "test_a"' ) ).to eq( [SPECIAL_PATH, '-n', 'test_a'] )
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'names the test executable as one word in a gdb backtrace' do
|
|
67
|
+
expect( words( DEFAULT_TEST_BACKTRACE_GDB_TOOL, 'build/gdb.txt', SPECIAL_PATH, '-n "test_a"' ).last( 3 ) ).to eq( [SPECIAL_PATH, '-n', 'test_a'] )
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'names each source file as one word for cppcheck' do
|
|
71
|
+
expect( words( DEFAULT_CPPCHECK_TOOL, ['src'], [OTHER_PATH, 'src/b.c'] ).last( 2 ) ).to eq( [OTHER_PATH, 'src/b.c'] )
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'names the library and each object as one word for the Dependencies archiver' do
|
|
75
|
+
expect( words( DEPENDENCIES_TOOLS[:deps_linker], [OTHER_PATH, 'b.o'], 'build/my dir/libx.a' ) ).to eq(
|
|
76
|
+
['ar', 'rcs', 'build/my dir/libx.a', OTHER_PATH, 'b.o']
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'names the archive as one word for the Dependencies zip unarchiver' do
|
|
81
|
+
expect( words( DEPENDENCIES_TOOLS[:deps_zip], 'vendor/my dir/x.zip' ) ).to eq( ['unzip', '-o', 'vendor/my dir/x.zip'] )
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
require 'spec_helper'
|
|
9
9
|
require 'json'
|
|
10
|
-
require 'ceedling/file_wrapper'
|
|
10
|
+
require 'ceedling/filesystem/file_wrapper'
|
|
11
11
|
require 'ceedling/loginator'
|
|
12
12
|
require 'ceedling/dependencies/dependency_cache_store'
|
|
13
13
|
|
|
@@ -124,6 +124,37 @@ describe DependencyCacheStore do
|
|
|
124
124
|
expect( @store.load('cache.json')['entries'] ).to eq( {} )
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
+
# GH #1364: version 2 places per-test build output by the test's path from the project root
|
|
128
|
+
it 'marks the 1.2.2 build layout as schema version 2' do
|
|
129
|
+
expect( DependencyCacheStore::CACHE_SCHEMA_VERSION ).to eq( 2 )
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it 'rebuilds once from an older build layout, advising clobber for what that layout left' do
|
|
133
|
+
payload = JSON.generate(
|
|
134
|
+
'schema_version' => 1, 'hash_algorithm' => DependencyHasher::HASH_ALGORITHM, 'entries' => { 'foo.o' => valid_entry }
|
|
135
|
+
)
|
|
136
|
+
stub_file( 'build/cache/.test.dep_cache.json', payload )
|
|
137
|
+
|
|
138
|
+
expect(@loginator).to receive(:log).with(
|
|
139
|
+
'Dependency cache build/cache/.test.dep_cache.json comes from an earlier Ceedling build layout -- rebuilding ' \
|
|
140
|
+
'everything once. Run `ceedling clobber` to remove any orphaned build output left in the old layout.',
|
|
141
|
+
Verbosity::COMPLAIN
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
expect( @store.load('build/cache/.test.dep_cache.json')['entries'] ).to eq( {} )
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it 'keeps its usual warning for a schema_version it never wrote' do
|
|
148
|
+
payload = JSON.generate(
|
|
149
|
+
'schema_version' => DependencyCacheStore::CACHE_SCHEMA_VERSION + 1, 'hash_algorithm' => DependencyHasher::HASH_ALGORITHM, 'entries' => {}
|
|
150
|
+
)
|
|
151
|
+
stub_file( 'cache.json', payload )
|
|
152
|
+
|
|
153
|
+
expect(@loginator).to receive(:log).with( /cache\.json has an incompatible or missing schema_version/, Verbosity::COMPLAIN )
|
|
154
|
+
|
|
155
|
+
@store.load('cache.json')
|
|
156
|
+
end
|
|
157
|
+
|
|
127
158
|
it 'treats a mismatched hash_algorithm as an absent cache' do
|
|
128
159
|
payload = JSON.generate(
|
|
129
160
|
'schema_version' => DependencyCacheStore::CACHE_SCHEMA_VERSION,
|
|
@@ -153,7 +184,7 @@ describe DependencyCacheStore do
|
|
|
153
184
|
result = @store.load('cache.json')
|
|
154
185
|
|
|
155
186
|
expect( result['entries'].keys ).to eq( ['good.o'] )
|
|
156
|
-
expect( @loginator ).to have_received(:log)
|
|
187
|
+
expect( @loginator ).to have_received(:log).with( /'bad\.o' in cache\.json is malformed/, Verbosity::COMPLAIN )
|
|
157
188
|
end
|
|
158
189
|
|
|
159
190
|
it 'drops an entry with a self_hash of the wrong length' do
|
|
@@ -7,16 +7,57 @@
|
|
|
7
7
|
|
|
8
8
|
require 'spec_helper'
|
|
9
9
|
require 'digest'
|
|
10
|
-
require 'ceedling/file_wrapper'
|
|
10
|
+
require 'ceedling/filesystem/file_wrapper'
|
|
11
11
|
require 'ceedling/dependencies/dependency_hasher'
|
|
12
12
|
|
|
13
13
|
describe DependencyHasher do
|
|
14
14
|
|
|
15
15
|
before(:each) do
|
|
16
16
|
@file_wrapper = instance_double('FileWrapper')
|
|
17
|
+
# No file status by default, so every read below hashes afresh
|
|
18
|
+
allow( @file_wrapper ).to receive(:stat).and_return( nil )
|
|
17
19
|
@hasher = described_class.new( { :file_wrapper => @file_wrapper } )
|
|
18
20
|
end
|
|
19
21
|
|
|
22
|
+
# GH #1368: every test link hashes the libraries it links, so a large library was read
|
|
23
|
+
# once per test executable on every build
|
|
24
|
+
describe '#hash_of_file memo' do
|
|
25
|
+
def status(size, mtime)
|
|
26
|
+
return double( %q(File::Stat), size: size, mtime: mtime )
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
before(:each) do
|
|
30
|
+
allow( @file_wrapper ).to receive(:read_binary).with('libx.a').and_return('library')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'hashes a file left unchanged since before the build began only once' do
|
|
34
|
+
allow( @file_wrapper ).to receive(:stat).with('libx.a').and_return( status( 7, Time.now - 60 ) )
|
|
35
|
+
|
|
36
|
+
2.times { expect( @hasher.hash_of_file('libx.a') ).to eq( Digest::SHA256.hexdigest('library') ) }
|
|
37
|
+
|
|
38
|
+
expect( @file_wrapper ).to have_received(:read_binary).once
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'hashes again a file whose size or modification time changed' do
|
|
42
|
+
allow( @file_wrapper ).to receive(:stat).with('libx.a').and_return(
|
|
43
|
+
status( 7, Time.now - 60 ), status( 8, Time.now - 60 ), status( 8, Time.now - 50 )
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
3.times { @hasher.hash_of_file('libx.a') }
|
|
47
|
+
|
|
48
|
+
expect( @file_wrapper ).to have_received(:read_binary).exactly(3).times
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# A file the build writes can change within one timestamp tick, unseen by its status
|
|
52
|
+
it 'hashes afresh, every time, a file modified as the build began or since' do
|
|
53
|
+
allow( @file_wrapper ).to receive(:stat).with('libx.a').and_return( status( 7, Time.now ) )
|
|
54
|
+
|
|
55
|
+
2.times { @hasher.hash_of_file('libx.a') }
|
|
56
|
+
|
|
57
|
+
expect( @file_wrapper ).to have_received(:read_binary).twice
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
20
61
|
describe '#hash_of_file' do
|
|
21
62
|
it 'returns the SHA-256 hex digest of the file content read via FileWrapper' do
|
|
22
63
|
allow( @file_wrapper ).to receive(:read_binary).with('foo.c').and_return('int main(void) {}')
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'spec_helper'
|
|
9
|
-
require 'ceedling/file_wrapper'
|
|
9
|
+
require 'ceedling/filesystem/file_wrapper'
|
|
10
10
|
require 'ceedling/dependencies/dependency_path_normalizer'
|
|
11
11
|
|
|
12
12
|
describe DependencyPathNormalizer do
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
require 'spec_helper'
|
|
9
9
|
require 'ceedling/exceptions'
|
|
10
|
-
require 'ceedling/file_wrapper'
|
|
10
|
+
require 'ceedling/filesystem/file_wrapper'
|
|
11
11
|
require 'ceedling/system_wrapper'
|
|
12
12
|
require 'ceedling/loginator'
|
|
13
13
|
require 'ceedling/yaml_wrapper'
|
|
@@ -52,6 +52,8 @@ describe DependencyTracker do
|
|
|
52
52
|
allow( @file_wrapper ).to receive(:mkdir)
|
|
53
53
|
allow( @file_wrapper ).to receive(:write)
|
|
54
54
|
allow( @file_wrapper ).to receive(:mv)
|
|
55
|
+
# No file status, so every hash reads its file afresh
|
|
56
|
+
allow( @file_wrapper ).to receive(:stat).and_return(nil)
|
|
55
57
|
allow( @system_wrapper ).to receive(:env_get).with('CEEDLING_DEP_DEBUG').and_return(nil)
|
|
56
58
|
|
|
57
59
|
hasher = DependencyHasher.new( { :file_wrapper => @file_wrapper } )
|
|
@@ -51,6 +51,17 @@ describe FilenameExtension do
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
describe '#pattern' do
|
|
55
|
+
it 'matches any one of its extensions, escaped, as a group' do
|
|
56
|
+
pattern = FilenameExtension.new( ['.c', '.c++'] ).pattern
|
|
57
|
+
|
|
58
|
+
expect('a.c++').to match( /#{pattern}\z/ )
|
|
59
|
+
expect('a.c').to match( /#{pattern}\z/ )
|
|
60
|
+
expect('a.cxx').to_not match( /#{pattern}\z/ )
|
|
61
|
+
expect('a_c').to_not match( /#{pattern}\z/ )
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
54
65
|
describe '#candidates' do
|
|
55
66
|
it 'produces one candidate filename per configured extension' do
|
|
56
67
|
extension = FilenameExtension.new(['.s', '.S'])
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# =========================================================================
|
|
2
|
+
# Ceedling - Test-Centered Build System for C
|
|
3
|
+
# ThrowTheSwitch.org
|
|
4
|
+
# Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
|
5
|
+
# SPDX-License-Identifier: MIT
|
|
6
|
+
# =========================================================================
|
|
7
|
+
|
|
8
|
+
require 'spec_helper'
|
|
9
|
+
require 'tmpdir'
|
|
10
|
+
require 'fileutils'
|
|
11
|
+
require 'ceedling/filesystem/build_subpath'
|
|
12
|
+
|
|
13
|
+
# GH #1370 and the path handling audit around it: a build file placed by text could land
|
|
14
|
+
# outside the build directory
|
|
15
|
+
describe BuildSubpath do
|
|
16
|
+
WINDOWS_ONLY_BUILD = { if: Gem.win_platform? }.freeze
|
|
17
|
+
|
|
18
|
+
around(:each) do |example|
|
|
19
|
+
Dir.mktmpdir do |dir|
|
|
20
|
+
@ws = File.realpath( dir )
|
|
21
|
+
FileUtils.mkdir_p( File.join( @ws, 'app' ) )
|
|
22
|
+
Dir.chdir( File.join( @ws, 'app' ) ) { example.run }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Every other example reads INSTALLATION_ROOT itself, so only this one shows it names the
|
|
27
|
+
# running installation
|
|
28
|
+
it 'names the running installation, which holds what Ceedling ships' do
|
|
29
|
+
expect(File.file?( File.join( BuildSubpath::INSTALLATION_ROOT, 'lib', 'ceedling', 'filesystem', 'build_subpath.rb' ) )).to be( true )
|
|
30
|
+
BuildSubpath::INSTALLED_DIRS.each { |dir| expect(File.directory?( dir )).to be( true ), dir }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '.encode and .decode' do
|
|
34
|
+
{
|
|
35
|
+
'a file in the project' => ['src/drv/uart', 'src/drv/uart'],
|
|
36
|
+
'a sibling of the project' => ['../shared/src', '_up_/shared/src'],
|
|
37
|
+
'the working directory' => ['.', '']
|
|
38
|
+
}.each do |label, (path, encoded)|
|
|
39
|
+
it "places #{label} by its path from the project root, and reads it back" do
|
|
40
|
+
expect(BuildSubpath.encode( path )).to eq( encoded )
|
|
41
|
+
expect(BuildSubpath.decode( encoded )).to eq( path == '.' ? '' : path )
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# A project's own directory may carry a marker's name, which must read back as itself
|
|
46
|
+
it 'places a directory named like a marker apart from the marker, and reads it back' do
|
|
47
|
+
['_up_/x', 'src/a/_up_', '_ceedling_/src', '_abs_/C/x', '_unc_/srv', 'src/__up_/x'].each do |path|
|
|
48
|
+
encoded = BuildSubpath.encode( path )
|
|
49
|
+
|
|
50
|
+
expect(BuildSubpath.decode( encoded )).to eq( path ), "#{path} => #{encoded}"
|
|
51
|
+
end
|
|
52
|
+
expect(BuildSubpath.encode( '_up_/x' )).to_not eq( BuildSubpath.encode( '../x' ) )
|
|
53
|
+
# macOS and Windows file systems fold case
|
|
54
|
+
expect(BuildSubpath.encode( '_UP_/x' ).downcase).to_not eq( BuildSubpath.encode( '../x' ).downcase )
|
|
55
|
+
expect(BuildSubpath.decode( BuildSubpath.encode( '_UP_/x' ) )).to eq( '_UP_/x' )
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Windows has no relative path from one drive to another
|
|
59
|
+
it 'places a file of the running Ceedling on another drive below `_ceedling_` too' do
|
|
60
|
+
file = File.join( BuildSubpath::INSTALLATION_ROOT, 'plugins/fff/src' )
|
|
61
|
+
allow(ProjectPaths).to receive(:relative).and_call_original
|
|
62
|
+
allow(ProjectPaths).to receive(:relative).with( file ).and_return( file )
|
|
63
|
+
|
|
64
|
+
expect(BuildSubpath.encode( file )).to eq( '_ceedling_/plugins/fff/src' )
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'places an absolute path below the project as a relative one' do
|
|
68
|
+
expect(BuildSubpath.encode( File.join( @ws, 'app/src/x' ) )).to eq( 'src/x' )
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'places a file of the running Ceedling outside the project below `_ceedling_`, and reads it back' do
|
|
72
|
+
file = File.join( BuildSubpath::INSTALLATION_ROOT, 'plugins/fff/src' )
|
|
73
|
+
|
|
74
|
+
expect(BuildSubpath.encode( file )).to eq( '_ceedling_/plugins/fff/src' )
|
|
75
|
+
expect(File.expand_path( BuildSubpath.decode( '_ceedling_/plugins/fff/src' ) )).to eq( file )
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# A project may itself sit inside a Ceedling checkout, as the system specs' projects do.
|
|
79
|
+
# Only what Ceedling ships places below `_ceedling_`.
|
|
80
|
+
it 'places a directory beside a project inside the installation by its path from the project root' do
|
|
81
|
+
root = BuildSubpath::INSTALLATION_ROOT
|
|
82
|
+
allow(ProjectPaths).to receive(:working_dir).and_return( File.join( root, 'specout/proj/app' ) )
|
|
83
|
+
|
|
84
|
+
expect(BuildSubpath.encode( File.join( root, 'specout/proj/shared/src' ) )).to eq( '_up_/shared/src' )
|
|
85
|
+
expect(BuildSubpath.encode( File.join( root, 'plugins/fff/src' ) )).to eq( '_ceedling_/plugins/fff/src' )
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'places a file of the running Ceedling inside the project by its path from the project root' do
|
|
89
|
+
Dir.chdir( BuildSubpath::INSTALLATION_ROOT ) do
|
|
90
|
+
expect(BuildSubpath.encode( 'plugins/fff/src' )).to eq( 'plugins/fff/src' )
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'places a path on another drive below `_abs_`, and reads it back', **WINDOWS_ONLY_BUILD do
|
|
95
|
+
other = Dir.pwd.start_with?( 'C' ) ? 'D' : 'C'
|
|
96
|
+
|
|
97
|
+
expect(BuildSubpath.encode( "#{other}:/x/inc" )).to eq( "_abs_/#{other}/x/inc" )
|
|
98
|
+
expect(BuildSubpath.decode( "_abs_/#{other}/x/inc" )).to eq( "#{other}:/x/inc" )
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'places a UNC path below `_unc_`, and reads it back', **WINDOWS_ONLY_BUILD do
|
|
102
|
+
expect(BuildSubpath.encode( '//server/share/inc' )).to eq( '_unc_/server/share/inc' )
|
|
103
|
+
expect(BuildSubpath.decode( '_unc_/server/share/inc' )).to eq( '//server/share/inc' )
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'never places a file outside the build subpath it names' do
|
|
107
|
+
['../../far/x', '/opt/x', '../shared', File.join( @ws, 'app/../../x' )].each do |path|
|
|
108
|
+
encoded = BuildSubpath.encode( path )
|
|
109
|
+
|
|
110
|
+
expect(encoded.split( '/' )).to_not include( '..' ), "#{path}: #{encoded}"
|
|
111
|
+
expect(encoded).to_not start_with( '/' ), "#{path}: #{encoded}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe '.of_directory' do
|
|
117
|
+
it 'is the encoding of a directory, with the working directory as empty' do
|
|
118
|
+
expect(BuildSubpath.of_directory( 'src/drv' )).to eq( 'src/drv' )
|
|
119
|
+
expect(BuildSubpath.of_directory( '.' )).to eq( '' )
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# =========================================================================
|
|
2
|
+
# Ceedling - Test-Centered Build System for C
|
|
3
|
+
# ThrowTheSwitch.org
|
|
4
|
+
# Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
|
5
|
+
# SPDX-License-Identifier: MIT
|
|
6
|
+
# =========================================================================
|
|
7
|
+
|
|
8
|
+
require 'spec_helper'
|
|
9
|
+
require 'ceedling/filesystem/destination_collision'
|
|
10
|
+
|
|
11
|
+
describe DestinationCollision do
|
|
12
|
+
describe '.find' do
|
|
13
|
+
it 'gives each output more than one input maps to, with those inputs' do
|
|
14
|
+
shared = DestinationCollision.find( ['a/x.c', 'b/x.c', 'c/y.c', 'a/x.c'] ) { |input| File.basename( input ) }
|
|
15
|
+
|
|
16
|
+
expect(shared).to eq( 'x.c' => ['a/x.c', 'b/x.c'] )
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'gives nothing when every input has an output of its own' do
|
|
20
|
+
expect(DestinationCollision.find( ['a.c', 'b.c'] ) { |input| input }).to be_empty
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe '.raise_for' do
|
|
25
|
+
it 'names every input and the output they share, with a fix' do
|
|
26
|
+
expect { DestinationCollision.raise_for( 'out/x.o', ['a/x.c', 'b/x.c'], 'would build to the same file' ) }
|
|
27
|
+
.to raise_error( CeedlingException, '`a/x.c` and `b/x.c` would build to the same file `out/x.o`. Rename one, or move it to its own directory.' )
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|