From ad67309b1dc9d2c2ebdf225fee799f55699c1757 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 31 Dec 2025 14:59:57 +0000 Subject: [PATCH 1/4] Initial plan From 682dd016c62f19391895b73d48c091875b1e1b1d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 31 Dec 2025 15:03:21 +0000 Subject: [PATCH 2/4] Initial analysis of Ruby 3.2 compatibility issues Co-authored-by: georgi <19498+georgi@users.noreply.github.com> --- .bundle/config | 2 + Gemfile | 2 + Gemfile.lock | 38 + vendor/bundle/ruby/3.2.0/bin/htmldiff | 29 + vendor/bundle/ruby/3.2.0/bin/ldiff | 29 + vendor/bundle/ruby/3.2.0/bin/rake | 29 + vendor/bundle/ruby/3.2.0/bin/rspec | 29 + .../ruby/3.2.0/cache/diff-lcs-1.6.2.gem | Bin 0 -> 59392 bytes .../bundle/ruby/3.2.0/cache/rake-13.3.1.gem | Bin 0 -> 86528 bytes .../bundle/ruby/3.2.0/cache/rspec-3.13.2.gem | Bin 0 -> 10752 bytes .../ruby/3.2.0/cache/rspec-core-3.13.6.gem | Bin 0 -> 167936 bytes .../3.2.0/cache/rspec-expectations-3.13.5.gem | Bin 0 -> 89600 bytes .../ruby/3.2.0/cache/rspec-mocks-3.13.7.gem | Bin 0 -> 82944 bytes .../ruby/3.2.0/cache/rspec-support-3.13.6.gem | Bin 0 -> 40960 bytes .../ruby/3.2.0/gems/diff-lcs-1.6.2/.rspec | 1 + .../3.2.0/gems/diff-lcs-1.6.2/CHANGELOG.md | 518 ++++ .../gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md | 128 + .../3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md | 71 + .../3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md | 49 + .../ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md | 40 + .../3.2.0/gems/diff-lcs-1.6.2/Manifest.txt | 115 + .../ruby/3.2.0/gems/diff-lcs-1.6.2/README.md | 92 + .../ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile | 115 + .../3.2.0/gems/diff-lcs-1.6.2/SECURITY.md | 41 + .../3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff | 35 + .../ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff | 9 + .../gems/diff-lcs-1.6.2/docs/COPYING.txt | 339 +++ .../gems/diff-lcs-1.6.2/docs/artistic.txt | 127 + .../3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb | 3 + .../3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb | 742 +++++ .../gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb | 7 + .../diff-lcs-1.6.2/lib/diff/lcs/backports.rb | 13 + .../gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb | 37 + .../diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb | 327 +++ .../diff-lcs-1.6.2/lib/diff/lcs/change.rb | 174 ++ .../diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb | 160 ++ .../gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb | 379 +++ .../diff-lcs-1.6.2/lib/diff/lcs/internals.rb | 308 +++ .../gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb | 189 ++ .../diff-lcs-1.6.2/lib/diff/lcs/string.rb | 5 + .../diff-lcs-1.6.2/lib/diff/lcs/version.rb | 7 + .../ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml | 5 + .../gems/diff-lcs-1.6.2/spec/change_spec.rb | 89 + .../gems/diff-lcs-1.6.2/spec/diff_spec.rb | 51 + .../gems/diff-lcs-1.6.2/spec/fixtures/123_x | 2 + .../gems/diff-lcs-1.6.2/spec/fixtures/456_x | 2 + .../gems/diff-lcs-1.6.2/spec/fixtures/aX | 1 + .../gems/diff-lcs-1.6.2/spec/fixtures/bXaX | 1 + .../gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv | 50 + .../gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv | 51 + .../gems/diff-lcs-1.6.2/spec/fixtures/empty | 0 .../diff-lcs-1.6.2/spec/fixtures/file1.bin | Bin 0 -> 1 bytes .../diff-lcs-1.6.2/spec/fixtures/file2.bin | Bin 0 -> 6 bytes .../diff-lcs-1.6.2/spec/fixtures/four_lines | 4 + .../fixtures/four_lines_with_missing_new_line | 4 + .../fixtures/ldiff/diff.missing_new_line1-e | 1 + .../fixtures/ldiff/diff.missing_new_line1-f | 1 + .../fixtures/ldiff/diff.missing_new_line2-e | 1 + .../fixtures/ldiff/diff.missing_new_line2-f | 1 + .../spec/fixtures/ldiff/error.diff.chef-e | 2 + .../spec/fixtures/ldiff/error.diff.chef-f | 2 + .../ldiff/error.diff.missing_new_line1-e | 1 + .../ldiff/error.diff.missing_new_line1-f | 1 + .../ldiff/error.diff.missing_new_line2-e | 1 + .../ldiff/error.diff.missing_new_line2-f | 1 + .../spec/fixtures/ldiff/output.diff | 4 + .../spec/fixtures/ldiff/output.diff-c | 7 + .../spec/fixtures/ldiff/output.diff-e | 3 + .../spec/fixtures/ldiff/output.diff-f | 3 + .../spec/fixtures/ldiff/output.diff-u | 5 + .../spec/fixtures/ldiff/output.diff.bin1 | 0 .../spec/fixtures/ldiff/output.diff.bin1-c | 0 .../spec/fixtures/ldiff/output.diff.bin1-e | 0 .../spec/fixtures/ldiff/output.diff.bin1-f | 0 .../spec/fixtures/ldiff/output.diff.bin1-u | 0 .../spec/fixtures/ldiff/output.diff.bin2 | 1 + .../spec/fixtures/ldiff/output.diff.bin2-c | 1 + .../spec/fixtures/ldiff/output.diff.bin2-e | 1 + .../spec/fixtures/ldiff/output.diff.bin2-f | 1 + .../spec/fixtures/ldiff/output.diff.bin2-u | 1 + .../spec/fixtures/ldiff/output.diff.chef | 4 + .../spec/fixtures/ldiff/output.diff.chef-c | 15 + .../spec/fixtures/ldiff/output.diff.chef-e | 3 + .../spec/fixtures/ldiff/output.diff.chef-f | 3 + .../spec/fixtures/ldiff/output.diff.chef-u | 9 + .../spec/fixtures/ldiff/output.diff.chef2 | 7 + .../spec/fixtures/ldiff/output.diff.chef2-c | 20 + .../spec/fixtures/ldiff/output.diff.chef2-d | 7 + .../spec/fixtures/ldiff/output.diff.chef2-e | 7 + .../spec/fixtures/ldiff/output.diff.chef2-f | 7 + .../spec/fixtures/ldiff/output.diff.chef2-u | 16 + .../ldiff/output.diff.empty.vs.four_lines | 5 + .../ldiff/output.diff.empty.vs.four_lines-c | 9 + .../ldiff/output.diff.empty.vs.four_lines-e | 6 + .../ldiff/output.diff.empty.vs.four_lines-f | 6 + .../ldiff/output.diff.empty.vs.four_lines-u | 7 + .../ldiff/output.diff.four_lines.vs.empty | 5 + .../ldiff/output.diff.four_lines.vs.empty-c | 9 + .../ldiff/output.diff.four_lines.vs.empty-e | 1 + .../ldiff/output.diff.four_lines.vs.empty-f | 1 + .../ldiff/output.diff.four_lines.vs.empty-u | 7 + .../output.diff.issue95_trailing_context | 4 + .../output.diff.issue95_trailing_context-c | 9 + .../output.diff.issue95_trailing_context-e | 3 + .../output.diff.issue95_trailing_context-f | 3 + .../output.diff.issue95_trailing_context-u | 6 + .../ldiff/output.diff.missing_new_line1 | 5 + .../ldiff/output.diff.missing_new_line1-c | 14 + .../ldiff/output.diff.missing_new_line1-e | 0 .../ldiff/output.diff.missing_new_line1-f | 0 .../ldiff/output.diff.missing_new_line1-u | 9 + .../ldiff/output.diff.missing_new_line2 | 5 + .../ldiff/output.diff.missing_new_line2-c | 14 + .../ldiff/output.diff.missing_new_line2-e | 0 .../ldiff/output.diff.missing_new_line2-f | 0 .../ldiff/output.diff.missing_new_line2-u | 9 + .../diff-lcs-1.6.2/spec/fixtures/new-chef | 4 + .../diff-lcs-1.6.2/spec/fixtures/new-chef2 | 17 + .../diff-lcs-1.6.2/spec/fixtures/old-chef | 4 + .../diff-lcs-1.6.2/spec/fixtures/old-chef2 | 14 + .../gems/diff-lcs-1.6.2/spec/hunk_spec.rb | 83 + .../gems/diff-lcs-1.6.2/spec/issues_spec.rb | 160 ++ .../gems/diff-lcs-1.6.2/spec/lcs_spec.rb | 56 + .../gems/diff-lcs-1.6.2/spec/ldiff_spec.rb | 100 + .../gems/diff-lcs-1.6.2/spec/patch_spec.rb | 416 +++ .../gems/diff-lcs-1.6.2/spec/sdiff_spec.rb | 216 ++ .../gems/diff-lcs-1.6.2/spec/spec_helper.rb | 376 +++ .../spec/traverse_balanced_spec.rb | 312 +++ .../spec/traverse_sequences_spec.rb | 137 + .../ruby/3.2.0/gems/rake-13.3.1/History.rdoc | 2454 +++++++++++++++++ .../ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE | 21 + .../ruby/3.2.0/gems/rake-13.3.1/README.rdoc | 155 ++ .../rake-13.3.1/doc/command_line_usage.rdoc | 171 ++ .../gems/rake-13.3.1/doc/example/Rakefile1 | 38 + .../gems/rake-13.3.1/doc/example/Rakefile2 | 35 + .../3.2.0/gems/rake-13.3.1/doc/example/a.c | 6 + .../3.2.0/gems/rake-13.3.1/doc/example/b.c | 6 + .../3.2.0/gems/rake-13.3.1/doc/example/main.c | 11 + .../3.2.0/gems/rake-13.3.1/doc/glossary.rdoc | 42 + .../ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb | 592 ++++ .../gems/rake-13.3.1/doc/proto_rake.rdoc | 127 + .../ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 | 156 ++ .../3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc | 622 +++++ .../3.2.0/gems/rake-13.3.1/doc/rational.rdoc | 151 + .../ruby/3.2.0/gems/rake-13.3.1/exe/rake | 27 + .../ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb | 68 + .../gems/rake-13.3.1/lib/rake/application.rb | 854 ++++++ .../gems/rake-13.3.1/lib/rake/backtrace.rb | 25 + .../3.2.0/gems/rake-13.3.1/lib/rake/clean.rb | 78 + .../gems/rake-13.3.1/lib/rake/cloneable.rb | 17 + .../gems/rake-13.3.1/lib/rake/cpu_counter.rb | 122 + .../rake-13.3.1/lib/rake/default_loader.rb | 15 + .../rake-13.3.1/lib/rake/dsl_definition.rb | 196 ++ .../gems/rake-13.3.1/lib/rake/early_time.rb | 22 + .../gems/rake-13.3.1/lib/rake/ext/core.rb | 26 + .../gems/rake-13.3.1/lib/rake/ext/string.rb | 176 ++ .../lib/rake/file_creation_task.rb | 25 + .../gems/rake-13.3.1/lib/rake/file_list.rb | 435 +++ .../gems/rake-13.3.1/lib/rake/file_task.rb | 58 + .../gems/rake-13.3.1/lib/rake/file_utils.rb | 132 + .../rake-13.3.1/lib/rake/file_utils_ext.rb | 134 + .../rake-13.3.1/lib/rake/invocation_chain.rb | 57 + .../lib/rake/invocation_exception_mixin.rb | 17 + .../gems/rake-13.3.1/lib/rake/late_time.rb | 18 + .../gems/rake-13.3.1/lib/rake/linked_list.rb | 112 + .../rake-13.3.1/lib/rake/loaders/makefile.rb | 54 + .../gems/rake-13.3.1/lib/rake/multi_task.rb | 14 + .../gems/rake-13.3.1/lib/rake/name_space.rb | 38 + .../gems/rake-13.3.1/lib/rake/packagetask.rb | 222 ++ .../3.2.0/gems/rake-13.3.1/lib/rake/phony.rb | 16 + .../rake-13.3.1/lib/rake/private_reader.rb | 21 + .../gems/rake-13.3.1/lib/rake/promise.rb | 100 + .../rake-13.3.1/lib/rake/pseudo_status.rb | 30 + .../gems/rake-13.3.1/lib/rake/rake_module.rb | 67 + .../rake-13.3.1/lib/rake/rake_test_loader.rb | 27 + .../lib/rake/rule_recursion_overflow_error.rb | 20 + .../3.2.0/gems/rake-13.3.1/lib/rake/scope.rb | 43 + .../3.2.0/gems/rake-13.3.1/lib/rake/task.rb | 434 +++ .../lib/rake/task_argument_error.rb | 8 + .../rake-13.3.1/lib/rake/task_arguments.rb | 113 + .../gems/rake-13.3.1/lib/rake/task_manager.rb | 331 +++ .../gems/rake-13.3.1/lib/rake/tasklib.rb | 12 + .../gems/rake-13.3.1/lib/rake/testtask.rb | 189 ++ .../lib/rake/thread_history_display.rb | 49 + .../gems/rake-13.3.1/lib/rake/thread_pool.rb | 157 ++ .../gems/rake-13.3.1/lib/rake/trace_output.rb | 23 + .../gems/rake-13.3.1/lib/rake/version.rb | 10 + .../3.2.0/gems/rake-13.3.1/lib/rake/win32.rb | 51 + .../ruby/3.2.0/gems/rake-13.3.1/rake.gemspec | 101 + .../ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md | 27 + .../ruby/3.2.0/gems/rspec-3.13.2/README.md | 47 + .../ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb | 3 + .../gems/rspec-3.13.2/lib/rspec/version.rb | 5 + .../3.2.0/gems/rspec-core-3.13.6/.document | 5 + .../3.2.0/gems/rspec-core-3.13.6/.yardopts | 8 + .../3.2.0/gems/rspec-core-3.13.6/Changelog.md | 2447 ++++++++++++++++ .../3.2.0/gems/rspec-core-3.13.6/LICENSE.md | 26 + .../3.2.0/gems/rspec-core-3.13.6/README.md | 389 +++ .../3.2.0/gems/rspec-core-3.13.6/exe/rspec | 4 + .../rspec-core-3.13.6/lib/rspec/autorun.rb | 3 + .../gems/rspec-core-3.13.6/lib/rspec/core.rb | 212 ++ .../lib/rspec/core/backtrace_formatter.rb | 65 + .../lib/rspec/core/bisect/coordinator.rb | 62 + .../rspec/core/bisect/example_minimizer.rb | 173 ++ .../lib/rspec/core/bisect/fork_runner.rb | 140 + .../lib/rspec/core/bisect/server.rb | 61 + .../lib/rspec/core/bisect/shell_command.rb | 126 + .../lib/rspec/core/bisect/shell_runner.rb | 73 + .../lib/rspec/core/bisect/utilities.rb | 69 + .../lib/rspec/core/configuration.rb | 2419 ++++++++++++++++ .../lib/rspec/core/configuration_options.rb | 240 ++ .../lib/rspec/core/did_you_mean.rb | 52 + .../rspec-core-3.13.6/lib/rspec/core/drb.rb | 120 + .../rspec-core-3.13.6/lib/rspec/core/dsl.rb | 98 + .../lib/rspec/core/example.rb | 666 +++++ .../lib/rspec/core/example_group.rb | 912 ++++++ .../rspec/core/example_status_persister.rb | 235 ++ .../lib/rspec/core/filter_manager.rb | 231 ++ .../lib/rspec/core/flat_map.rb | 20 + .../lib/rspec/core/formatters.rb | 279 ++ .../core/formatters/base_bisect_formatter.rb | 45 + .../rspec/core/formatters/base_formatter.rb | 70 + .../core/formatters/base_text_formatter.rb | 75 + .../core/formatters/bisect_drb_formatter.rb | 29 + .../formatters/bisect_progress_formatter.rb | 157 ++ .../rspec/core/formatters/console_codes.rb | 76 + .../core/formatters/deprecation_formatter.rb | 223 ++ .../formatters/documentation_formatter.rb | 102 + .../core/formatters/exception_presenter.rb | 553 ++++ .../core/formatters/failure_list_formatter.rb | 23 + .../formatters/fallback_message_formatter.rb | 28 + .../lib/rspec/core/formatters/helpers.rb | 118 + .../rspec/core/formatters/html_formatter.rb | 153 + .../lib/rspec/core/formatters/html_printer.rb | 412 +++ .../core/formatters/html_snippet_extractor.rb | 122 + .../rspec/core/formatters/json_formatter.rb | 103 + .../core/formatters/profile_formatter.rb | 68 + .../core/formatters/progress_formatter.rb | 29 + .../lib/rspec/core/formatters/protocol.rb | 182 ++ .../core/formatters/snippet_extractor.rb | 134 + .../core/formatters/syntax_highlighter.rb | 91 + .../rspec-core-3.13.6/lib/rspec/core/hooks.rb | 646 +++++ .../lib/rspec/core/invocations.rb | 87 + .../lib/rspec/core/memoized_helpers.rb | 580 ++++ .../lib/rspec/core/metadata.rb | 498 ++++ .../lib/rspec/core/metadata_filter.rb | 255 ++ .../rspec/core/minitest_assertions_adapter.rb | 31 + .../rspec/core/mocking_adapters/flexmock.rb | 31 + .../lib/rspec/core/mocking_adapters/mocha.rb | 57 + .../lib/rspec/core/mocking_adapters/null.rb | 14 + .../lib/rspec/core/mocking_adapters/rr.rb | 31 + .../lib/rspec/core/mocking_adapters/rspec.rb | 32 + .../lib/rspec/core/notifications.rb | 523 ++++ .../lib/rspec/core/option_parser.rb | 325 +++ .../lib/rspec/core/ordering.rb | 208 ++ .../lib/rspec/core/output_wrapper.rb | 29 + .../lib/rspec/core/pending.rb | 157 ++ .../lib/rspec/core/profiler.rb | 34 + .../lib/rspec/core/project_initializer.rb | 48 + .../lib/rspec/core/project_initializer/.rspec | 1 + .../project_initializer/spec/spec_helper.rb | 98 + .../lib/rspec/core/rake_task.rb | 190 ++ .../lib/rspec/core/reporter.rb | 266 ++ .../lib/rspec/core/ruby_project.rb | 53 + .../lib/rspec/core/runner.rb | 216 ++ .../lib/rspec/core/sandbox.rb | 37 + .../rspec-core-3.13.6/lib/rspec/core/set.rb | 54 + .../lib/rspec/core/shared_context.rb | 55 + .../lib/rspec/core/shared_example_group.rb | 271 ++ .../lib/rspec/core/shell_escape.rb | 49 + .../core/test_unit_assertions_adapter.rb | 30 + .../lib/rspec/core/version.rb | 9 + .../lib/rspec/core/warnings.rb | 40 + .../rspec-core-3.13.6/lib/rspec/core/world.rb | 287 ++ .../gems/rspec-expectations-3.13.5/.document | 5 + .../gems/rspec-expectations-3.13.5/.yardopts | 6 + .../rspec-expectations-3.13.5/Changelog.md | 1366 +++++++++ .../gems/rspec-expectations-3.13.5/LICENSE.md | 25 + .../gems/rspec-expectations-3.13.5/README.md | 326 +++ .../lib/rspec/expectations.rb | 82 + .../expectations/block_snippet_extractor.rb | 255 ++ .../lib/rspec/expectations/configuration.rb | 244 ++ .../rspec/expectations/expectation_target.rb | 163 ++ .../lib/rspec/expectations/fail_with.rb | 39 + .../rspec/expectations/failure_aggregator.rb | 236 ++ .../lib/rspec/expectations/handler.rb | 181 ++ .../expectations/minitest_integration.rb | 58 + .../lib/rspec/expectations/syntax.rb | 132 + .../lib/rspec/expectations/version.rb | 8 + .../lib/rspec/matchers.rb | 1046 +++++++ .../lib/rspec/matchers/aliased_matcher.rb | 116 + .../lib/rspec/matchers/built_in.rb | 53 + .../lib/rspec/matchers/built_in/all.rb | 86 + .../rspec/matchers/built_in/base_matcher.rb | 225 ++ .../lib/rspec/matchers/built_in/be.rb | 191 ++ .../lib/rspec/matchers/built_in/be_between.rb | 77 + .../rspec/matchers/built_in/be_instance_of.rb | 26 + .../lib/rspec/matchers/built_in/be_kind_of.rb | 20 + .../lib/rspec/matchers/built_in/be_within.rb | 72 + .../lib/rspec/matchers/built_in/change.rb | 452 +++ .../lib/rspec/matchers/built_in/compound.rb | 293 ++ .../matchers/built_in/contain_exactly.rb | 312 +++ .../matchers/built_in/count_expectation.rb | 171 ++ .../lib/rspec/matchers/built_in/cover.rb | 24 + .../lib/rspec/matchers/built_in/eq.rb | 44 + .../lib/rspec/matchers/built_in/eql.rb | 38 + .../lib/rspec/matchers/built_in/equal.rb | 81 + .../lib/rspec/matchers/built_in/exist.rb | 90 + .../lib/rspec/matchers/built_in/has.rb | 194 ++ .../matchers/built_in/have_attributes.rb | 114 + .../lib/rspec/matchers/built_in/include.rb | 218 ++ .../lib/rspec/matchers/built_in/match.rb | 120 + .../lib/rspec/matchers/built_in/operators.rb | 128 + .../lib/rspec/matchers/built_in/output.rb | 207 ++ .../rspec/matchers/built_in/raise_error.rb | 275 ++ .../lib/rspec/matchers/built_in/respond_to.rb | 200 ++ .../lib/rspec/matchers/built_in/satisfy.rb | 62 + .../matchers/built_in/start_or_end_with.rb | 94 + .../rspec/matchers/built_in/throw_symbol.rb | 138 + .../lib/rspec/matchers/built_in/yield.rb | 375 +++ .../lib/rspec/matchers/composable.rb | 171 ++ .../lib/rspec/matchers/dsl.rb | 546 ++++ .../lib/rspec/matchers/english_phrasing.rb | 60 + .../lib/rspec/matchers/fail_matchers.rb | 42 + .../rspec/matchers/generated_descriptions.rb | 41 + .../lib/rspec/matchers/matcher_delegator.rb | 61 + .../lib/rspec/matchers/matcher_protocol.rb | 105 + .../lib/rspec/matchers/multi_matcher_diff.rb | 82 + .../3.2.0/gems/rspec-mocks-3.13.7/.document | 5 + .../3.2.0/gems/rspec-mocks-3.13.7/.yardopts | 6 + .../gems/rspec-mocks-3.13.7/Changelog.md | 1343 +++++++++ .../3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md | 25 + .../3.2.0/gems/rspec-mocks-3.13.7/README.md | 465 ++++ .../rspec-mocks-3.13.7/lib/rspec/mocks.rb | 133 + .../lib/rspec/mocks/any_instance.rb | 11 + .../lib/rspec/mocks/any_instance/chain.rb | 111 + .../mocks/any_instance/error_generator.rb | 31 + .../mocks/any_instance/expect_chain_chain.rb | 31 + .../mocks/any_instance/expectation_chain.rb | 50 + .../mocks/any_instance/message_chains.rb | 83 + .../lib/rspec/mocks/any_instance/proxy.rb | 125 + .../lib/rspec/mocks/any_instance/recorder.rb | 299 ++ .../rspec/mocks/any_instance/stub_chain.rb | 51 + .../mocks/any_instance/stub_chain_chain.rb | 23 + .../lib/rspec/mocks/argument_list_matcher.rb | 117 + .../lib/rspec/mocks/argument_matchers.rb | 366 +++ .../lib/rspec/mocks/configuration.rb | 212 ++ .../lib/rspec/mocks/error_generator.rb | 390 +++ .../lib/rspec/mocks/example_methods.rb | 434 +++ .../rspec/mocks/instance_method_stasher.rb | 146 + .../lib/rspec/mocks/marshal_extension.rb | 41 + .../matchers/expectation_customization.rb | 20 + .../lib/rspec/mocks/matchers/have_received.rb | 134 + .../lib/rspec/mocks/matchers/receive.rb | 134 + .../mocks/matchers/receive_message_chain.rb | 82 + .../rspec/mocks/matchers/receive_messages.rb | 77 + .../lib/rspec/mocks/message_chain.rb | 87 + .../lib/rspec/mocks/message_expectation.rb | 856 ++++++ .../lib/rspec/mocks/method_double.rb | 316 +++ .../lib/rspec/mocks/method_reference.rb | 214 ++ .../lib/rspec/mocks/minitest_integration.rb | 68 + .../lib/rspec/mocks/mutate_const.rb | 339 +++ .../lib/rspec/mocks/object_reference.rb | 149 + .../lib/rspec/mocks/order_group.rb | 81 + .../lib/rspec/mocks/proxy.rb | 517 ++++ .../lib/rspec/mocks/space.rb | 238 ++ .../lib/rspec/mocks/standalone.rb | 3 + .../lib/rspec/mocks/syntax.rb | 325 +++ .../lib/rspec/mocks/targets.rb | 124 + .../lib/rspec/mocks/test_double.rb | 174 ++ .../lib/rspec/mocks/verifying_double.rb | 125 + .../mocks/verifying_message_expectation.rb | 55 + .../lib/rspec/mocks/verifying_proxy.rb | 221 ++ .../lib/rspec/mocks/version.rb | 9 + .../gems/rspec-support-3.13.6/Changelog.md | 437 +++ .../gems/rspec-support-3.13.6/LICENSE.md | 23 + .../3.2.0/gems/rspec-support-3.13.6/README.md | 40 + .../rspec-support-3.13.6/lib/rspec/support.rb | 163 ++ .../lib/rspec/support/caller_filter.rb | 85 + .../lib/rspec/support/comparable_version.rb | 48 + .../lib/rspec/support/differ.rb | 216 ++ .../lib/rspec/support/directory_maker.rb | 65 + .../lib/rspec/support/encoded_string.rb | 163 ++ .../lib/rspec/support/fuzzy_matcher.rb | 50 + .../lib/rspec/support/hunk_generator.rb | 49 + .../lib/rspec/support/matcher_definition.rb | 44 + .../support/method_signature_verifier.rb | 467 ++++ .../lib/rspec/support/mutex.rb | 75 + .../lib/rspec/support/object_formatter.rb | 279 ++ .../rspec/support/recursive_const_methods.rb | 78 + .../lib/rspec/support/reentrant_mutex.rb | 80 + .../lib/rspec/support/ruby_features.rb | 221 ++ .../lib/rspec/support/source.rb | 87 + .../lib/rspec/support/source/location.rb | 23 + .../lib/rspec/support/source/node.rb | 112 + .../lib/rspec/support/source/token.rb | 96 + .../lib/rspec/support/spec.rb | 84 + .../rspec/support/spec/deprecation_helpers.rb | 50 + .../lib/rspec/support/spec/diff_helpers.rb | 45 + .../rspec/support/spec/formatting_support.rb | 11 + .../lib/rspec/support/spec/in_sub_process.rb | 73 + .../rspec/support/spec/library_wide_checks.rb | 152 + .../lib/rspec/support/spec/shell_out.rb | 115 + .../lib/rspec/support/spec/stderr_splitter.rb | 77 + .../lib/rspec/support/spec/string_matcher.rb | 47 + .../support/spec/with_isolated_directory.rb | 15 + .../support/spec/with_isolated_stderr.rb | 15 + .../lib/rspec/support/version.rb | 9 + .../lib/rspec/support/warnings.rb | 41 + .../support/with_keywords_when_needed.rb | 35 + .../specifications/diff-lcs-1.6.2.gemspec | 35 + .../3.2.0/specifications/rake-13.3.1.gemspec | 26 + .../3.2.0/specifications/rspec-3.13.2.gemspec | 31 + .../specifications/rspec-core-3.13.6.gemspec | 31 + .../rspec-expectations-3.13.5.gemspec | 29 + .../specifications/rspec-mocks-3.13.7.gemspec | 29 + .../rspec-support-3.13.6.gemspec | 29 + 417 files changed, 55703 insertions(+) create mode 100644 .bundle/config create mode 100644 Gemfile.lock create mode 100755 vendor/bundle/ruby/3.2.0/bin/htmldiff create mode 100755 vendor/bundle/ruby/3.2.0/bin/ldiff create mode 100755 vendor/bundle/ruby/3.2.0/bin/rake create mode 100755 vendor/bundle/ruby/3.2.0/bin/rspec create mode 100644 vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem create mode 100644 vendor/bundle/ruby/3.2.0/cache/rake-13.3.1.gem create mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-3.13.2.gem create mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem create mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-expectations-3.13.5.gem create mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.7.gem create mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/.rspec create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CHANGELOG.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md create mode 100755 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff create mode 100755 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc create mode 100755 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md create mode 100755 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/comparable_version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb create mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb create mode 100644 vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec create mode 100644 vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec create mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec create mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec create mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec create mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec create mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec diff --git a/.bundle/config b/.bundle/config new file mode 100644 index 0000000..2369228 --- /dev/null +++ b/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_PATH: "vendor/bundle" diff --git a/Gemfile b/Gemfile index 886bd8b..ab3ae0a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,4 @@ +source 'https://rubygems.org' + gem 'rake' gem 'rspec' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..8d18c4a --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,38 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.6.2) + rake (13.3.1) + rspec (3.13.2) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.7) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.6) + +PLATFORMS + ruby + x86_64-linux-gnu + +DEPENDENCIES + rake + rspec + +CHECKSUMS + diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 + rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c + rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587 + rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d + rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 + rspec-mocks (3.13.7) sha256=0979034e64b1d7a838aaaddf12bf065ea4dc40ef3d4c39f01f93ae2c66c62b1c + rspec-support (3.13.6) sha256=2e8de3702427eab064c9352fe74488cc12a1bfae887ad8b91cba480ec9f8afb2 + +BUNDLED WITH + 4.0.3 diff --git a/vendor/bundle/ruby/3.2.0/bin/htmldiff b/vendor/bundle/ruby/3.2.0/bin/htmldiff new file mode 100755 index 0000000..58aadf2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/htmldiff @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'diff-lcs' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('diff-lcs', 'htmldiff', version) +else +gem "diff-lcs", version +load Gem.bin_path("diff-lcs", "htmldiff", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/ldiff b/vendor/bundle/ruby/3.2.0/bin/ldiff new file mode 100755 index 0000000..7a54829 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/ldiff @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'diff-lcs' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('diff-lcs', 'ldiff', version) +else +gem "diff-lcs", version +load Gem.bin_path("diff-lcs", "ldiff", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/rake b/vendor/bundle/ruby/3.2.0/bin/rake new file mode 100755 index 0000000..6b572b3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/rake @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'rake' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rake', 'rake', version) +else +gem "rake", version +load Gem.bin_path("rake", "rake", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/rspec b/vendor/bundle/ruby/3.2.0/bin/rspec new file mode 100755 index 0000000..b8bf169 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/rspec @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'rspec-core' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rspec-core', 'rspec', version) +else +gem "rspec-core", version +load Gem.bin_path("rspec-core", "rspec", version) +end diff --git a/vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem b/vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem new file mode 100644 index 0000000000000000000000000000000000000000..21c4c77c3d4368d3a91cd2442074342f08e61a73 GIT binary patch literal 59392 zcmeFYRcs|N(!bxN}B%v_C3ja-cwEWAPfcL~#f1ONbl{5Sm{`LCLlm6-*EnT?5=iG_`w zPK5F)1kT?YNH>$%^))Q^I8938j+d;~+Qu3D)^{ zUT}gzMwc#zk~RRbT7Zz04B8#wRux#EI!CsVa8N+qPM=bPD$Wh+aHVUN3_SR4;283OydG|r~&vq1Qy;SGB`{5>XQ%@6XYu;Mj%vY&DhP8X;RDZQ3Y2(@{cJffwbS1+vbY{}bg`l;4v8<$(P!`{g zUfu_IrWMU+EXBC&t+A_Iuv(u-+&7HZ_rK=CX^KJO^kzzoUN_6u^%f`{nC{NCPtb>~ z5!;#-(d@CYG8tstOe~8&{*aHm&M=Fv>^qFD!?z2TdI}3)z$}@8Dm%9ML3aYAB_o8Lu z%>uhJ!@j~mL_cWHIY*e>_+7L`W!L!!*M1m}etWEeEVd1Kj>Ox0zg~K*7YsQie#(MUH#ccnOEfAE^0&zLY9ze072mCrpfe)o85>%E2`??n$M zt83~&kI0C)OPKRqr4X?=i#3|w>rU!A99w!y7(hOmTSvN&^G7r4mxRt+2UXi7TGylRm--P8K7H1##z&t0XuC5f_WV`J2;t6{#&#bv1JS#e=hMd0>08 zqpGrg*?xR;H56;ski+68!g*)+7bwk-SxCwki{R8W8S065AOX@sq4lM4h_sA7s?vv9 zBpQ;7YUQHx%4?B#PU_Ac9D~^H8GYu8aPoE|r*XO}TbWc@`Q&gYesraTpcc z2Fv#bCM=!bV{lu287^NUb>Ai>rdH`W$mWosE-oHR@Ow3-tU0>6simJ}N8Eyz?x4CZ zvUR}tY)nj_^R-l$g}qSGjK8YEv`V!cQ>WIegJFgnqp|{FL2>x#o%}+Sl}zfV#DxlX z?xnmB|)K+ddz0q_+!DAwA{Fa=~8!7iFF!TjEKlTa^lRg?y8 z2697}jix_dxf^&!BwOP7L&&im&W|QDjT9~zjn_*e(A4psrl|zDa#?Ix1Nj&)a8*mP z_#_gfA8l2gv=Rsa9N4U$ByfF;DvWfshF*V`;17k`Ti#qW>eN?(Ej4*8=$^nkk5(t40Kw z@bUSK|4i;KaH%qteVJ_gNlMb#0HR3Z*0IfFF_oDXBz#QI!oqSrKXz}m^fM^%=up|- z{A6iyillSj`np?PZT^5Xt><0Y{Bg#d$DzYhT`iDNE$|5y(AWjTnl&*^6+M#gdE?T{ z$Z#z%ZqU7>FbbrD`@a3y4H)kITD>aP$Q?Y?h#TL_clq`pIGoa${c(5kIemHf(fQ01$TJiQ-nB~nlJiuM+0MZe$2y9s^&qPGBrUO~6Dk!vHsq z*cdKw7vG$}lJB;V@hJ8&C;f8f6P)T;8b9vDTjS zO)0FP0x7+6umA$<5?$gC)Uw=<*+&3j=3j7&CG*L*EY<}-_6ud1#wG^C!xvh!p?*-t z1Wy)Px>Ii@&xV4GU1d>oOyI1!Pa{tJMUcLp2C@Q%958=Ow6!>Cl?|alSj1a**lpYG zESIx4&z{9N>6x4w719k7QNybPuqdQ>H<(BV5{0sm1rI052u8k;D;MRI_w*hQOjVH6 z(nbWHi;6(lQ6;14uBRbHWLdHwEt6phI?&cw0y9hBSp699!?|$9yhI~+31^|^^#%D> zrmX-782`%Yb30)<$a2Jb2kCOL;SG9Ylg3DPY4D0>Vsm27OcJR>WzdNPhXH&W%G^c} zUIZ!f>9KtgoeiporNYH13$}JTe+v~fVTF?3sSc2Ripn#yA(!mNa5~AoO%ef$8PmT7 z=S`*Ccw(c@;EPC-v<@S{kQ+^I+Uh;{Z?|rt{MXzBE;ppw|DCb#HPiEu`&Kz2d2Z1V zwqC0CA~ka69*2Vpp?!=!#yq>J%UVEk*mMYG6JkcV_zBQ__&@en$#@j7e9`4CObozB z3PNWhdliq!5v0ozY*K9PTBhk{%2L%gU6g5w_q~UQ_x}BT6w9ae22L@v=>M~qsKe{G zQSP$hD26i7|x^H6%sc#JiQQ`*SqP0}yi^ zB*){QD0s7&V15hZ#=NxQU?7vW34xovX*K_+y~wISDY2j|AVX zzFk>?3WV@C{F3G=ATRZ+qOEUqhzDH)@-7{ES7OaJZ(+Ib>dEXHuaF&TFj6Dn!B}>a zvcwI$dWL*3U9LTJAInF_-LMaT@(9B;_Ct5T2m2%x4Xp2EHskDankb+D&O;;TQKsR0 zl5F)+gLVrf`T5?k(-r6O)A>GWl8xL3lvHM$`)eaZPx~+)#my4;^MSpL{LS~4|Mv60`GH$@hUKJxhEMS2pBZ$Tl;M4YLT{qf z@hHKKUBnTNy)rU?!MX(IyC$T5OhRk?UP;o4i`hCD5qoI^J%Qse%b5#DAq*d7v~s%# zUu-HRt(!(7Pk1;n!&;Z5^bkq3^9dtMpYzYx>vR-DV*}6>~>vC45@Lj{w^~b)m{R*eeQ) zKe+Zuo-_2Ic$58y@h6M{YCZ)q`7l5}%7j4T1K51qlt70lfQrW-L)xWo3N&1?XdpqC zsg;06KS}pJ(aCH`wiH%?BI2XI)9?1e_ccy2gHT09Mq5N0{rXLuCkYK$B6^p^I?k92 z|3jbk7}+!LAS?KaJQ8-iV_9dF5_gK=Gj24@Rp_C2#*Z8YLaa+}sgkRZdsWTRX$o}< z%Iwut&dWX9Z?LdlGH~8>E%+kkwuQ=fvlb z_-A>mjp;2CR}RuYBR`&ai%+ieGIAEygTfE+F9GujRN0JD35|p|H~v(%*oirWcmRPL ze1i%r>*Sec+`@$0p2g!WTRo%#xQL!Sh^rjkHs{y*DB)~xfLY$;Es2+1$jA`3T}s!^g9MgQ?speynhxq6gMaR z4|l6C7Jb$n7Ot?RWHy>MhCwsY#>zyomv3d6O+Sskus|{}?Iclm`J#@l;xs?DdU(uRIcv)a>2bnasn;7h&wsEMb zaox<4xJ7unAXq~Pm1KGWRyS~PCLV3mowo#L1rLQXBHQ}2UFi$OAbDzF$_;bGw_Ic& z1_(yZoM*b^4{$Sa=&Wz;_Nk86jD3+#k8BTGGI<|zMBY~H*_zn);u_@KzcAXA;@+eI zj-7jolVk=p9d=O*Ts{R}3^xZf*+7aVsC03HWetBp8zope=J+_TfvM`pE`BeA$9m?C z_KIRnIkF7g(%nwwC|IhU_5tg5^Xqd$I=7z7wHZlV{dyW)xdj3%j)vGD-{d=9?NR-C z8KJe?`Pk0sAf3@tf%X0rsf|AKgS@ykUf^(xK|6w#CzU)jp|2DKX!ZHzfJ5W7x^PfI zj4vb<^mC4-i&kWo{taFwvL_N*{CB$j?la|A$V!qzKzmaX*nW8Vc}>z|_)vyScXCD* z1H)Yqivt(hmZjpNht|x&9gyWrBv75jP2My(5Gg8~nk>OoBXYRj5*!)XI$;6Vo~#2j zvCO$R8i#}tRG=aot_U0AG6v@7fTU}Tq`dMysh;Is&Lh9Kr zGn(jM`|IwMl6BHqc&M#5Hf;I0U`8af-6y%;d{ifsY?K7`9eNiATT|vO!CV2tgZv0; zTnOU87EBFzCO%y12C;z`1e=n|(U4&$PjuTURXd$H*0XgAgO)n#NUS7`lln0?u@;J3 zhgt4V$YhROy^ZEyV#KMc!ei|aP6Gm$WAA1Thvj^I#%Z81)fheP3ZmII-K0=0s)9LM z6SAfz7&dBSy5fs$sVK2IW#9!9R*R^jwB{+?6c8_MM|`F84{aV2j)7S*e1xKW<{5+F z-u;o0kZ1Z4%2%%!>=drr5*3_sUhbxpr&!}Jmz9gTW1Lf(qhw^35O3~@-?3KzP954R z?Kbu763(m3@=*1EyOkVo5q8(+4n0QBB&EJdecNQHa}$JGc}Ho&uoGvffH6D>9Nzf~Xjr3;rswhQ`85@WLuvfE9ms2p;H!Dtqfvu<+}< zr@HXA+NQkG|MdL!J3VUh@iom0km-C=UGZ0@nIzzX3gl0fT)0mREt&F5LW_#e4x!6w zpb*SV@fF_OkGX2{0`hB)i8;BiHsp4aP`89Vl(MEYu)y+ub0emJA3=dcjK*IzL^uYZ zqwI+7i-sv0EdENnNlc|DU=wH)V@t<;TDZ~C)Ez}QDzQu!O(#C0=ehxWZ#9T?OH$Nb z0LC6+(bk&NYPKou!DI#>_ErB8Q9ia&C#)h?l0LX(X{7vR9?sb{i~5-_3LfXIme zcl=lNs~^90>*dczF&@VXy&kR~-8QQX$Qu!s)iLO-hO2ZSW4~BQCH)J#^ckeZEe$A| z0>0XaZ0RG%_ulrglVY86hSP^`2l$E6iH$+$TE_$5n$l$6K^~#+WAxW)kbKP}6juJs z4AG&fFS7hgQww!c@>-|d%GbQ6m?v^q4rc5df@HQ6Nn7tCE}@O7c+9TjgliYcsKRjGcO+$T4JK7>nqgZ~AuWTb5nK$ISENe4ovT}~>_aJFn1Q*zhgtyoAhJkL?A~1Ix?7m64?HGl22jVX zkgzX;`s#p%8kN>PoOzfIBE~ZXo0IhQ9y(=J-@_cv`y8+BWZplMg7!PXsem(hSo7;x@T8xwQVxb?#;-W?#ux z@Wg4H)Ez6)*OpH~ug1*hXeEWvgT#!YVqAxznDhN9I8MoWlyV48w^~V1C(t-?|2l23 zc(yPfb>tt`oN1l?_3&%zh4`_muK^Z6!{!WmXG28J@Dt8R(|G4E5F^GBLS~tC-Q+rU zr@G93MbsmvPNLxqy@QUeiW@piTZ+vRq{Y5_>a3#8)XyL+wtQ^2p`$o08C4<538Z)2 z2O-#7s2G*2y_^c*FhFO7Vgb6c8J{snY0<7jWVorm+I@9dolAzL<6qtt*q!uIpM^YX z6&aS=A?aYKH{Bva_uk}eSlLpBL?C%}grCQJjB;?X2JE6tM-zsJrVQraipu@E2VwfN#6DoJ)&Yj=`N6z zBy#ajPZio#=sI)E=mSEfvPu9{&KRUf+Ofad6XG^i;HuvL4ht=%q_m%U--kTbjcKYc*lBOt8!HK0h ze}^7IwWdX7!QN0Y?k^EtNKZ{jHp!PDeif#SZNI%_N#Nf zZETK1H>+Ot+bBd<(%5l{Jn4QEqOg>J;cB(&`UYhKC!4LrQLq7-#gbNty!MGV9NZP(~XILuUe^YqcudYlRf$sMut;rw=Qg>uMFDjS|(xXU^ zGph;upLw&B9lE&?Jn)MfiWkkJf0-@SzzO@cagnO)AwXu-9ih_*ZhB6inEK;xgUCR;{Yaf;saxH|5`G<4SNY_=m|I$elHgX7BBZ|!eyo~aN>WGes8N=WV@1odI zI`p5>=6}USmJ0*uf+!*^rlF;jQOi)1(JoAj2u!P4iblA#FgyZ{BWNR|QPd}NIIW6M zqxr*`Mwe8t3ZjKDOctzpKut23wfDd7+nTnV)@vLbs(BeErJs6O&(<$Cfp}J4CGU#M zBbX16@JfYQ+K!-Shuc=&ejU44D{s>zQ0`BW%+%dPRlc<_5c$RHoKxtCDo+BaAr;HZ z++-_@e^piIk5*jfyN-3|T=oTX@FYy>RD`F}1$Hk=nhoDhthf!B+oIhF^}z%BKf!-~ zb(;Ecs2=k=sikfo`GnW}?y-<2ROdpq=Da9VTCqrNbEWd^KQTI$xfsg_`>jsSDKd|U zQeTo1c05`N0uoGC{k(nAf3q11nJ;p3)FhXJM$|xGRb;Sw@!Q_# z)^aUi;k-7>=dHL?V0qoTc;B97`M&={%2lG<5s|ZV&P?W6>;(8XDP{Se72ZnnRitnK> zBfODoDkuirEezs0W-_0CiWyAV?MToGhZZ1^Lq)$PobU40+4No#J>(C!RCU|j?I@Ii z+BK7tGZs=???Y6o9W2>(6dK$Tw%#bh5ICA$Mx0o4uWM7Nn?5xgy`*^F@Cr?y+U9deI4%jSW^;43-pcPhHBfoUCE= z$O*VQ6Za&+nLG2nu8*dkSeQKQt4! zBOmx>k}TB}m1wg7Q#>>li@VE&yyRKkru;mWu`REuIzLVM8s`@0ADB$fk`)%~X5Ywx zI|NbK7#LzuPwv|4+tOxz(&a;gilHOo7@~h+JRT~_NX(DJ2|3&iLNzbCCz zzk)NH@hep)x}bAIy7E!QCeOiz`F3XRyHe%%=mXF$Nc8g?uFQIir0PxxEO5umjDX`E z3J)H?csNdf)7~-QU}1RlcX!7q6k3;pzhN2iM|%S@H${~zk2kzKA`{_i+%GhU{Vsfp z>&{oLi`I4_HJC;Z`@nM&RcHG>S9-G;bD^+^>$*AJEf(N1=fRNdDfSgE4>;lXuZtE= zLaU>SC3B-i9J7Ztw ze%VQNKWVb>a@Cfe5J&YP`SnhX4A8C^dw?Ah-KoE}lPY0LTY3WxXLPPd1?rzPZppeR zbd8ZkG!z=m$zLd<*s^QHL>MMz5;IkqObrwe7Y##4GBkcEE6KB|SEz6wW_Ze+)=SYL z=_t`v-snEUPI^->@hc*vyLg!XTiWN44$0%wnJKZHq=xBs%0!}P%a^IneRrx<#b8r2 z4t6(^Q4>pBLM0}8m7}?qau7yM{&2F^Z@Bm(dM~Lsr2nwn@Ndnt21&1IGEYD0PcD;d z^v7ABoPVdCc(Oe-g|bR{2($9~<&J7-$8Nh|G;;ZN@B7AG_Zz z6{dkm=@$5%S}o{vQKDOylhAL&kj20H^11leTbFy(Xwj9;&z^UI9bJkC<+(u+S{4^Q zj#CF_jROgG-Msi)U^9rg$NDVVbcUX&|0HibR{ND1tD@q|kg+iED>pLsW{D6hJ1RD4 zDxvZ&FW{WDJJSe@W>zeu{7kIlG&7k*|NFYiwW%#P^y$$1~3~v2`~KHkLN@6$mu%B8||E?14#kL`vi>}5&^At z(=ZIk6h|?Sn>0AmhH!R@%u=!VM5YXR48L~cw{m71x}*S~ti*vTPH^Od9lh<$=a{(2 z1ZvX-*X{;Ufkcf)LOc2eAr^$rK40Cw#g4MYoMJr1h_B3}i%D4EyHZw_s=$svNKjC{ z3{qc$hd2vYWBBK%jzR23T48Xk+~sSL+hi?elUqoj@~4$prOkMB?VN+Tvx#68|BiX<8q+XBUFT%<*I;*(sNi2)@`blBhnU>4Jje; z_OyH3yJ9D_yw8Z3y$(eUX&xOPKX2JOoiS8DzqP)vBL>T%?Hm4ls7&VY2ui8aCi76* z#XysPo{czO3xnLg8rg3g${0IG&zm|RJqC5`ahCG2(nMSJw6=Rm2`sS56|DLGPFP%Q zqJsIA{ixg*q*3fB>lZ$JnI?XGlfAqeV!gF8G15Bh3t58x-Y!)A?WWS#vkou)`?1GP zN671RxAn?h(HZx}t`jZg8vQ>CH)RI-#qNWODlEZga2>SL?MKeKU2o$XOp-^@VV6*M z6H$Lt;d=K~O3^!d*C%D0!cgCGj#^CxJLfup6+Eu-%lu^P|e=R(1~jD*IZJ!&N$eDTUI}3BsE8 z|2e7dgVXE{ct}dJO|abXjA2v(!_3NDECFBtCN{-MwQ!xR!+{UOCWnbc=uIbIVIh8L(>R@ZMKo(Mky*}Y@A_W%g zpP8u(cX7sJ1o)BP+zXe^DlP@flX#ZdKZ900F9}H8r=yIsF9`{VJ6HK%A`OE6+&?Cb zVj%isKW&S)*WY zI5i2>Bc0F(kZnqFqN~$%yKqQw3SYOB*7JI7si@V z*K*1$VbdjHAb}(6R4kMN=BSv+U5;V5=McF`*Bzu1i+2&0Jw<{f%OCXY+mO~m!v5e* z;FS}9x{uC1NdWj?gcb_|K8SN&``mJze-%6Vj&Bceqx*#d>sT7mSse>O1VjneMBI8K z(LAlB&q1FL=OCy%obDN}Mgc`e_C@uk?^Tc?8FsjAchci}1^ZOLMu#JdolGBa5T)c( zUyp_6-mnLjQf06Oc#KSANKa9(dF9v~WJPh)N}?v!RmBonWQ@1*I4z8@xkz6B#X}Hj zII&0u;)>D08mviq;*uXV3mXV(9&6eMH1Ppu0RH`YEBB^j(eJPT)yq*hPQ&Lwrx z@x2n}sx~UiGT}SzVJ5Z! zS!nYNz73sAiC3`)hfOSDaPlHvcCKX&dn3JyDTbvqP88+iTVpa5f3r%1%dxNpBkh}S zfC@Ek=Oot-u!xI-m2E#>{>mk9cvRF4b8Gzix_35#!E}k7T13K%z{tVs8o4-$3{;6VHEPrWA`*6s5+#r) z!^S~w0`6;~EU5j}E?lLuE@yqA;p~r*wtbvP+!YJK9k+~r?tzwh57vQ!<0$XmmTo$Y4S3U5c0nrcqcOwzp~hC4t%(fR0s!x-X~ zzdGGW;v)YxvXEnoG10U-Ih6XIHWvwr{Mv7MG=E}~NFUtHLNbjkRDwU08*yz8$zv6r zfpQ}U22d;DTkjih5dRjCUt3*c%71eIx*XnNCQxikZ{ZObf7`U}0tN7T5t8y}P}ffs zQLoCupHdtWERoyVC2vVukgO!QEMTwO_WuYpB+HrH0icAi?2)BkWY-pbG^vsd9VjB5 z(N5>-Q#?@*3?XKar0rh5$UpUY7ZWA0EDvrvCCYM>Sw%<&wS0c)JQulq{CsZtPI^bx7CTn36DP~Dkd3Bn&4A%>w=SFRDH|b)=0f9(-+Fbl zb1fcy3^S}zRjlBw8D{vw>}5W0qgZ=Lnw z^eKDKi4=yj5F|Mv+2>Hn0U&pdDvE?GlU>vzNL2XJ=~*z}v0T zUHes6p}OhN!k(RNSUbD8-!3hW;OQk$%k(_C%E2R*42?|4af}_IZ znv^k15Qh?wt;auA^?-_y0d()}d%%g~3m+f2WNN+`Xd#ewi#zF<+eqKI zp^S@Nbf$tBLcrLZPf@;u0<<}#ykf}G(ipZ>X6a-E4^O5cFyyc}!Xhc-??$j&&!`W( zBYoBeHe-)97n#DL;o7Oe)~AftWSaaQ3~5xs{3kz-xn}enF2bUj+ObdN)QP%TNk|oC zbHs?YelWSFz<(~m7pMtKFt1{reVaX;kt{IyN@!o;KEoS{g%YJ}WO|E+{$M~{6?1IK zbKHA~KgpY=^Kt;B+iBMa*ig>LJoz|cmJ;Ck;}US+FOxMH;uy<4K`D7a0-I!x zbI807Dh4g_hkto{{#&n914mN%pIFV=WgYJk-qEK)>13XqM~VV-pDU^Ej-j8p7dZF| zzzsy|cm8YrXBuBTWeOCozwhLT=qf;kfDcOuDm0d?Xw(W+&06g$2~wBSy#JqO{O3G& z7NBu-91lPLs=Z6)&e5I$KwoAWK``1ahox=?PSCI;CgLpf5KVS~P(^T&3&^b=Mvn@K zEV<7Tjnw>}Igh-YH?^bx8nkW{cT>kCK)|)VN1!x?$V=6NMWGgkc{1TLpiJnTZTx=5>#>h7YT|7f8RGNp1F?RB`OU9 z8{QyZ@Ti)R?8~)g*yX3B5+W>~q_Y=odlv-H_3cq(w7=EbhwLc@$6HzYmI~t@zj2?U zsYK4yoa8ZM?g7SWU5Z=hy*+tWRQD+J<`{8dzsjLb6k#ar2nvY@ovfB8BMcu7x2gHd zwnwhUXFi+xZBb2E(u?{VZ%le(eeoUCXh@A@_n)9V28Zuqzje4Rsdfh_CT})*Y3OmD zp90EB1fUZKRSZ6OwMhkuoGMzy$>xe^2MJ;bBe+>NC_dR0equpG+c!bZf$=W*rLKSd z=#Nd-Ceq!*J0$Zlne+j*Uj++r7KY__P1I>NdDS7}tFLE#BIK-&p6 z2wa$v)?Tzd=8io|3Rder*mTF>Jx$oM9}rdF4Rkfb z??dh&N#ju&fypCc=j~9js>ucWy%C7u-spU12gQHmZt+w7!*ZWr=kWvomLS?|_I5L0 zynEccyY)kRitO=k<+*oco_wHYwU?H9CR`@?vrtcV%wSc>aZ26)C= z4wIt$3kf0$?(Uxa2|sa|t|$8Lt_(oJC+ribD5&uH?`YcKR~JqyN2`+0@?Tb?ZXdS=nseNa)}BXX%C zvTj}dq6IzAC|=T&l{CPf4QH_YMK;5w`GQyF0YzEcGIr>xgl-eI`V^+ zUfMH(kf!!!TYJazJ=p3a14u-F`MjUUmq8MAG)vI9j`~vpzl@!j_lsW zpWX0pLTN~Ow%vmALAmlb{oLljMw@^?g4yU0(~(tFhGw1?regMqd`HpF`i zUaam6_s%g^$wJg4>XeqhEjy2%*k}o$js5=Ww}+KOuCNcWHp%`okHKRs9eg-p3NDrv zgrh5HFZRJ27f{VP?9t2YsS)C1S}Cp%9TsDOQeKQSMT17q%r-C0ni)1j_#OAX`=9L* zm3kch(6`y(Nh|2ra^MBu0b`oxK4}IGI*-(Ulgauliq2O#nkO%On;@1z0z&K-*fs&# zCCBhz0@|g;4uBG`8ynFvQgPwqWe^9LNvSuGIs5sT}P zm4~#7DfQdt>CNy%3@dYSNkKLuTGr%R$221lm?HPH(Hmg|evOa&&y~%^QJm>-1YFHZ zav%L#`FBXC{R$fh=n8sM&t zO3}=X2#WGxJ(L?o|GdO=JE)a5_h+KKa6*f|0Hr-TkED=O@SjJc`rHQiRoyVt2jaNo zShklre|~Ke86;F}mDny$rvyl!%AKB7 z2^BA}F23dUWGt>;4T=y{e8rmw3_NTK_1 zBW-STu({0nFZzeA=Vq9kABP$&u7BNjgh+tKt(N}m3W(rSXhXq;J~oS2@^ZPz1)Sx% zTbKGR@Iead=i#ZmfKWCUXmm&bs*8)`AHfu}C*tR5U%#)LRA!C~7Wx17$k!YHm=!{+ zEnH9yTB(|Y4~O#Bo~l9sn&NN6ss&+-qDtLy3~_5GMS6R zWehI+_l(AKI=;3VEuVvQTGx5iEU;ZIm;qYbQKh!}zPj3HU>$bF;)(Jjprhjxbaoh$ zUKAy|UzCHdq^k2{q|JWcPW$UK*Tp3k`vzD9kKY}SmVY>KzdpTzRyM;bGyUDS@R5tQ z$iY>fJK9eXW$Ye-!xifDSj{;8N|m#N!GkpU*Lj=pU#D3kZ!x$#pfs)QaXnqY+sSNy0!f*d zr!So?P&yAYGX8DzS4g{Sq@a~A9bZrgZ3B>?6)Zu+%)kZ4Ck&1pzpgglB?5!H4!^3} z4~)~}CiMM;5*Hc~V>`n^?W)DU@Qg3%fyM~1&X1HRI$s_JscpPq#e+tm#3pQ z{xL8lzx?iwcqjLHk)@TnY7p9Jz1m}CznBI_dB#Z*(n7=Mg_);_4LYn|a~6cR*YF|5 zdSNOs$mKoVY`u!-3O-DKU7IuF>59jFzB^Cb@+0Nhh0ki0`1R=rs6_R;@Qf?HCTU3| zUstv_VPSBT_XaLVj+6oL_rzPK!UxT%KM{=(6PoCDZ2c@+%qVg3ljL0(satHlm0QekB@>i*i zHY7s5Sp53&d%nkdUg+p?g1Y0%+sw%gnK5=Id`puk0+bAYmlL=ogzRldT&kc~hg;-V zg}5J!1OR@}a;eqbHNhH;!hgWenFe>Dd`!31Kf?7?@aia)EcHHs;!l-}GCfG^F|n*x zS|SMIi2^97yI&{E<# z0_cGRLdGoh?W0SJgiDhJ$!XU+F~Tq~FbG<4GSHL~5^9%R4H6YRECF`2evZxg0DOxa ziN7=Rr`BX;jZ1M~+sOqEM?t@M|K``ehD{;&*g}BjocGY5t{41N7wd%n`QF;t`xA1G z>#6J&_Es@L`*zPWKby*t)=qWvltpXcB9FWc6N#d;z2d9lsVMmF zu>Q;IV!`Tdr_B4%ZMTraFQJ7UCO$RPGLgKW>_S0VIR_PG&PPOF$D`NbO#D9K(W$$` z=X1?Iy4CEH_a$J@?_jjD^(<}rU(4;w@e2Mv#jmt5yFOa-DNMtgRvi$}=3Jy>EEiH} z7|JiB<&g(u25=-SSu!M>(m2AqO=d02u0r_{Nijp*M@a^6Bq& z&~n8M6YL6YD6V#Y*Vk&p;t(ev1K_El^?C$(ligNw160^WJzR z5%=o{K0J8#Wl^X~xT`ToJh$NwcP(CFHV(aW&Z?oOOYvBE)AA#oA|qCuMUySyWbvxEp3HbyHych!wGbry)b#^ zA+*MeJcKy<%&hb@BN*RZWiqY@!q-JNMr(1S<$nWX^{1E?8>= zGeWaP;}0!fQNO(H54Ilo9iZk;6up-Hc82zvwuU~}DcEW=zn;Idv)U=l8=BRMWqRvn zwho)>yF1l(ceZO#>P}1F9`8(|F6Z}-V0EX#H%N?GOK_MY!p1$gau#9OFs z683HRr66oK!?}|iYP|2{vw$V~L!=+xui0zoPlf+{dad4l66hVyPZe9Sb==lg@-zr$18jNj3}$e_A(BPS9gq{Ny6)4-I)K%m#0iXCsaqAhONZ%eEb=yb z!Xz+}U))|V2cs@=QyjBX+KqRv2*i21l$zKj&;Unn$q%0-b)q6TNAkh zQjG0Jrrg{F6?%Zx2h+*dL07wo`qttMc-5!VbjAFNWD`K0B}QXpx7$iuacXps@7BBBG$K|Z+2482d|^QVq+d0tg}jrc%gUSlt{QBf_3 zULzy17i@6w6Mk8d2jdzt{Cg^*@(a98-G5#=f7vhh^X=_dwnjW*`YAMWLmO84?Pd0< zq81{$ef!ValjXvz1oX)Bv>1Ko3ds_7s{nq7pLUFZ#wYTLjeOGY8CNcCa|vaBb4*V+ zS^!v)A+m-70_-CzH9s6bbo8C1?dINP!6mAXo=zzBv1rr}y9HYxftl;=Uv5P@@9r*> zJv*O6AEB-9-^C;D#ncD{iyyHWu8!Rhn!6wI zxO)(5X*a7WnmL1Ps3sdXR?Y+zQryM*w;57PT$IhntuRxk-A>+7jMv>rEvMq>Npswi z)3vYfw8cVPCgiFYuMPY8{EqFRWvt_G*&lyHuF>SPgN?_unpz{s^OZiJl*XR;x;lst zjhJ>S9)xm^t1i4}DZTJs_yPXXho*jZ4sk|A{FSG`CS=8>PNeT{+jkB)Z`sAm_2Mzr zzHRxK>!d!DBtmBexyG_4b?(8gmuIGj7n@i`LLBypQ@W^t@8UO)2b`ot2%5z1!dRmKl?5(iSctQMm~smT1LPd)?1;=V};Ms{{=`ux4+?Q7l#&r zMivRq^{G=Eq)PV{i*nIs+ng8;a}0e1%pp>w7svQ(8^%M@bZ#Dsa+g{>gve-%Mh_Zm z+_S*L<>JusjPMEj$29l$t4@`u;cvyBM<1g;$^5IXAcBO)uIP#4YB9|xdvv*n{VQ+q zPhz4mD^TVzoTsy56A3}+%y*H1L=*+wfRXpvv-+FP=_xISlajENp@7>o8%28by~ic8 z8HjW*A>!dG%9biF0Q{WAie%X&oaUpnFn0b3>1Ja>Zx%y^p1a&AqCP4{d%_3w%P8?O zVUE5zy}EREuKI(2Up{nylRoTf7C@rd_-Tj`BekaMLuQsb&8}Y0CZ>LEFk;r2-VFY> zx0$7BQD)NUMdNWVP6nIOvM$?KhZjxWf;who>f<$U+yAr6f1Wq~KTG~2VQ;bi&vvu< zd;Y)Q$o}te|I}8ZVw0LA#)}5#do>IqSV}XiJL_OpS_7TtiqjNjQ6I#lV$X8{v{Ph+ zPiMKy@+v8bIYttu$#{Z_Cxxbmh_#-2wJ#gyVA}j*7*u|)RmQ1i8^hGNAPchVX#PK* zK^}jk$tT5#&7OhFBk#Y1oc?8yt=D2*)=;EH$kk+un`nF;>95ET_9E(surN4qHya;q z*U(zuAfa6*rs$!m7>;XYPJ4xXP*KynE#Q(3oJw9zPy?66Sk%be?Y5M*AH|m=WJ?O3 zoA-b8YL9Pb5?A-I8465 zL;Y$_bW;ytqWIO~p6Mim9AE9?tIxS*-TV9WSMNEu`uzpX3P8TUgP<8 zMUP8>C_zEj;&d8ec>KfLER zK9n)}?5|r|ATC^*I*C(mm<}2c5`zBNk|SRs(E|F^A;zrp3oB+-p|uO8G`!iP22RPTXLHhpfqwk#@qB+;YUdMxuCM?^Ni zHQi%Y^Q~iw@3%f|H1a8dc>TX^ZUmA&Vd0f#<&{7Zs{jQ5PJ(`1KvVc!Ku@#NPXA^< zHb4Ar4T=c6A-)Ta2VbaUFuj`Or>JTAmVCoO_k9bhB3?WS1+MF}npwM96FtsQltwP} zRl9hV#!kLw)#+<9Q@(aW4fw_(+Flv6wZZp4I?f!m$F6jCnZ2$WN{oiV} zmgxW1U3u`&AZcfU^+Gpsm(c6XzEc;2d0v#t$IxF_GsvdX3z>;$vw5P zy7XY;?9D#)?BdTJmr{O{t5h|D+knG=Z;6$g^u`h1f{U9o;Y$5YIPbgsWEm7Ud0Etx zYoQ|JH)nN5`m;gG9*FtK<}q-8FgF7d13sHK*C9D%?Of730XhJ11mZ%Rb{6uFV zXIZmZ!9Ot+ehciJ>vdb;o0D#{JnrWe!*;WRjI9Km^d3%+QX;N8HJj_n)dyuQQto0M zDyS2bsPk|k!<%M>)56bLdYOe2WIaRAvtpEHxh+b;S=eMxX-ey-2!WDjx1nieacowS zB2gCDhf$s*UFqtD!3aWpePhEIn>rqAog0~p6jYE2=SV!4GHP+Lg&X!V46gtT25Rmy zz1>7wk9QblnP$n?{ezEVfl_Y$h!%(n-K%GoFQJ~lrIJ-VaK&#ui)Lt+*aX#YIkTR6h)QU+}D`RC0FeJW@i@-KS$@;kPn&KTr)Cw}H zn>Wo-YpJ4>gylA#uZ8cZ>;Q2N@H7)!(%?esS7UQ zU(PEQo%%4Mj(8j-yhJ`tjWO!S)0iD`L00^Z`o{IjR5r&I-2X%? zdxr@1e3;v%*ea~FAVGLOjTYe*;Q|J@OAyZaWZ9gXyR8svnxs&*;1ZgvMM>`uch}HH zbcah<3{O60GHg&%!KERW2)11O=rO-QsYUK%5KULNEG(pg0&gP|JH6*6enT9#VfL0K zapuu1rJH?{`|))>y?Qk80UZ!&9%Jh@2dM2U(Cg?Sj5{+iU<mYtY<5C79x8l*<6#fwnRQK^ayF3+2S!vSLJ@I4}sMG}QNLjr*= zNRD4GD)aR+YAR|yRBi)Qo*o14?mYipXQ~{Iwx;VIS(ju?RAko^OTc#szg>Z2i;Rmymx%WFTOcG=)UakxA6c& zZfPx>6>O8@CPUs8dge+oLMAl+glh*$Le}XxROFSyYL*6#Bos9d=gRwP)v1z*pklPW zj0B*TkzUPfG-MCf-pc&eY7!k=3z&g%)8{+FTLWgVHRR12FU5t(aMXnM7D(Jx6!Vh3 zUyPQ5qp6~>El581B9ku{JPvR6)`u>n>_7;S(mjV}UK!4dxWSE<_bz^R5}MG^a4~nnZU+(qTfU-Yu%2LTfquX>`%WdgdZ4!8lJDbrtW><<;@P)uMH7@vi zG)ssU*pb(XCTcY(mQYaDmnO#!QcT6XIz!&@8;#%x;dYEevTSB6OR*K%UP5k>T5Zdq z>^pNb;ruQVt!3P_n}@m2)L?skP8&S5mUcvO?b)PO7UFUe06;U1`?GYGk7abP${hj^ z)s3AN!3={=(tj&hnI)PH#$h~>5J}4hd}FRqQX^(7v}N@IX_njTYbdeiMTHWI6v#1G zy_}=?Qi+UrT?aNpyC*ApTtO9dWkT`FI6;W8K`&{%ysd@7c$Y-%VNTY$$xKJ{oU2F) zUdv&&vRkMr!Ex8jwHK}Gq(&KK03EO7F=M!aKUyi>a?p%9trByT+0)`y)49~>T!Ao_ zVk%_|gtE~aGrlAzGTmEAaZN8)!Bd~>WYS(Ggi7GeimT*Q7uO6p&G-tuB-9}8dlE&0 zB(jP;s^%%@vVf2z|tCVycOldxv;Rs$F0E0@E*8i(q+9Z zE)1FaDH)Vi=q=5IaZ?JlX}2D{Y>9US>I%^iKgS!oocUMg#xfUL%i!erNxJI%>f635Wtp;3)sd4zSd>rNZp#g~}~jPt|tF9HUM6&H5(x zX~{q>SV~0R3J`gzzCOl@Otj3UxY4uwY?=DMO7T|b#SggyeQ>)VgpwK%W@?rLbNHdB zK<42ZY?Rsy*0k}7_jvrsRsv*b^LB}!^umGBYZTGVdViri!;)`muH)!tfhKY zGZc`uIuw3YB7H?ar)*Ec@fA)aDdXji=Ch25Lv@IlO337k}ppe-Gm%L%PPr^UMLa-AvNY;O8D zTItnPQD}nISBHlF8A(yJL9l>xn!rH2rPel$jioRmnQ$C`xue12og!(CJbqK}Ea}4v zh}y~$p`Z!@(FK>P5s~?X2e7N=1gjzv1)`KuplbS%A(6K8*tbK z_?Z!%Xx!4GC_AHuHP4J7uC9ghk*Xf;+cMnD7kRos=2LU6vg4|WsBou&;xbuL3ebDs z7}})~%MImFEZqdr$0!p~*ecO%?anM6uLQOyKXH}rF*F-in#xyl0<`9C={?J3PKXFz zUII$CTNQa^9e~QJj)Fy2i|M0=>fg$UY~Xu{sQ(%C`@;Y!rc#av5t3f6PgviQ2=y{c z{=C@<)nuH8kh1cU+x|4CzPN*n>Tw{#-qVP{rJR4NQ{=Lj?Q4S}%c7_#M+h3-5t z$6Z5MWGvkg%;5Z6NMS7Qf@>Kvx8S4-=8u>l%xlVzD+86lvL(vs#8zx2zDSK-RzMhY zX(P*OE8u*5t??x+u;(5YA?{t#iR+%)-Lhn`D6Bm5%cUz9qh?*v4h&h9n1B%lr6j3sN!wwy2)Ohlz)R=nvs#}& zyu4n=pN04H_I33I3GvO>)G ziqJS33u}^tjBn@)1H`_I%$m=0lu2bB69{j0{agXQX2V4_SCbAEDAyk935_+0k_SDy zjD)p{;E&dD_5WPmHCu%IpSfWa)oPRTL= ziK><1{OWH$(^6q20zp(DZ}f2rH7<)!ded8K?r|zGY(l+MAdPy!EY1xxgXyiq-#$9X zCrnI&f^0SlXSfAyS~6TB5-Z~Kt}CV$xMOJHD;0&Wqms6Y#)^SqE$+O#xF9Tp=4k|- zDb6}E#98Tx<0i%@hj$6m4M?$_Ko)T+F#3NE9%HH(BVM1kZdbO>N_W1jDG^!=B3K?n zC28%{j5+Fg!L-&bA3QN*ILw(`1yPi?RjaNl^oWArvN6yG75Sp&L%eVx@P<|>%h+Bw zihCT5M<;U}-Z(?P%8ASCk$&iINnxh$&BaDG*F^rQH z@k3SVR`%FcE@XY9bvU|@jZbFmrXMT-aY4dSuZKqsv7&JBqVOl5;`BeW;);L6!U0m` z&pBdJ)@&)7ODLwlh|`E1;;JUmv-R6~m4zMy-=m=lGwV&E4~>&Gm9{DY(CVIC>@!XpLG>i5vx+cDB-qlweW^idPoNr#R+&+5K1n(MJ(z^V4i_$(lUjQ9R*P%+CQaqPTD(`_fSN(^?NWE!(;no;9E~wPtcj z47^bbJS=2hnBmBX0NhzuR~RfxX2p3LY2qX;+ks0;y-}uA%tEA)R7T$ov2aFeVr-MM zjOzlbPmJqs#@pM9_l3Gbp}DWoPn8+Z;lM-amB*9Wn2u>ArXn$4&>eEAY-LIH1K()l z`RzprU*z?c&GhD9+C*^P7BO!*d+GtO?4%Uh-F1#M94Lscw03Hi&Phs`*V((kJKP?d zU`HY1CtPpJ9yzHquc?7$K-WUQ;Nrtf*Yq1nk<3)kI%J8GGL&;)i1R0qfo5gF%UMI? zqO7obSeZQ1Sf{Y3XSlSSHi$R*6Vn$K&NKNe>7%$N?--1<$ii@{OXN^SWx42pyTD=W za|mod&ib>7Z*98z7)oY(W9*vgOThs)HlN zhH#AI$_%ZIPn~M8=*vudv>utId|laM;rVM$y&AY&qjJS-fUCv+DJ$dwFw|@2;>sx! zsypwTfRno-w%*l>wt^x{la*lhN(S{N6hb^o zW9A9Z7EXw1C27i_wfEr)xvO~4T7-rwS!E-V0;Sez#MFD>sBYxDb%u>T(C)Q>^iY3}(n&SF<4 z9C9blt;=AG;0er75+tL+ASxvGKd{mH7{d8dijjj5k)0u#x3+0K2r$sDCY+XnGZoEf z(IAWV4XMgddWu@nSW}ZR^IUy*NsbUo>3P%XMY{&t&B^p^4{Nnjh~pdErTZ-t2$bs6 zDnD&K#H@YLPAbi;%Rpr)yTPT89?&6JfeuS+FU=VOg!w8EESSjV&VePhY`$#*(RB4} zRt0B>-_lmY@{ZOU)jJ)`Dl9plup^w1U*8`!SL~p*KatOBb`JzWO=~Xfm1Q&&i7dZHgJcPDQxKE5y}tB zxxjh+G7ZOky7}y7*B0%BD?pM6aqOk`r4E1}*-)QK0FCsNPEsebBLqks8wNyR^crzZ zG}}9px_mMa>gd?~&^|e7AD#WkNYQMV7oGh!O2eZH{M(b`S10W^rh97rWDm^ClTL?A z)4y(?yz12O-bn{<_z?Hi2$fH&R^f2 zbWUmg0rlN|Lo@EskKLpF!*>Vl8vKHKI66KfIMK>zo@d7l8vCy8ohC#52X8tjNH%)b ze$hSb(va{ae%U=cq9NGhxGgi^e|OlXMZ7zCdwkk~P6r^QP6*&9-P6CA_GzGi{kL~* z*AYRN`gp^6dTA{S8;RwbACKSRDxq~B9^i$*z5qaV%t7a6XaB7GJ#8<&NyD7Jd(%;P zpPn&*4iC*yXCE2iPJT3}os;jo`+!4m(s|qN68PaYeR6_cj*o=kv>Mnv!jjJSz=3y1 zhgj`N=ilDZdRAZp`e?r*Yy&X8eGh)<(%{&k#m%pA6Z)at{2vL8j?J6)kK(HRqoM~* z)A@2&v4W7I#Lo7MW5D1A&8N%LqKNoA#^DX)SO_z(cEhdCi=@?d*5)fqo~{ zqrE;9sL(0;w|Ce@dZ3+{Hf<-C20YX)!x;pw9a$Wqu@}$fdO7w2{sAuzk57SYG{{-o z@QmrdFFJVpq;o{@;^Wlb-+y;PM+_3~-%o*dZo#Beq*+ug%= zCrda+BOen8(Iw-W+YpOnryDiK0n>d+L+!uT-7}R_`=fbHTk)bpueA@p?}GBkI02o7 z)2_ngSbI=7-bU?cwcL7zgMYQfYjLJ(v(ze@*fVAn=;4o`%tyo(>2;W+sa~O)&=@7C zgl#IlExnL9_2tuB^^!wI@*;4xL1wwTs6+%*$sD2uln$)B9zhfl?nu1h`Lc?Opn7S@ zW$9vk;J;K+f_lND&ZcbDj5dhQs&0!S>@Ox^axTBAZ&L-M!y;224zV=M*tMS6m)Q%D zO;PwoO);Ec*@l-&(295#5+`vT&DFF;Tz;sa6c;9<@QRkiCL2`NKEyg?{F zMS*&&n zT@{;L`fukI2GjZU-Of>!;T95&ZU;Fmjb_}-dexVDW0}!ztOkH@u~m6(1m~YZ;cU4x zI##ruHSsDT$;V#!AWZhs|Hj2>s6|lyXRHPNhj*1^^%~D7kei8zdnRES> zYKBmIv!5ir$Mh+e*o%rsED|WHg94ynXmOh{hO43jI|G1oxm3S5DDn zWw&qq;rb8#iD-48(R>PtknLfmZ@8Tw&%w1;47S0#l^B$Yz-i z9&_WT3D8&*T`c?XA%dA-iHN48b85D3gXNvqvbLT?*@ltu?<~k6>yO1Il8E0sjM50V zE46rKpw3zu&tf@{co-yzuFoaN^R@c3hj6!;j_KN9XDe>QiNG1Ve@y4;V4g&J(%B5y zo4bL;ji{UepAhgUN`!TA>gdA5^M^2`v1=in#$2L+bE6I|@R!Lq{HjX-irJXgAre0` z5qu^dCx{m(EIFIgNlTOGHPa++EsMvT&;)FY{7^%Vk36=KVBZr4sRsBK`sfrgYGEps zA;2Ghe_0I@c)_zSPk}SXWj-kiVa&}^*s?)vdKoow+MK|;k#ig;2*2D`Y^Ic%5N%~A zFn>f(1D`whl|VbU+9n|iH`bffMuHF0GQ;R{evDvsevD-$=HJU4?Z>Uhi}{}(?fhQ<={Nb~AZ%MZ#vZk`Aoz;@%A7@K%fSgYFOm(AE^PW=PYo+~ zylT>ew^~6!W5?MTKB$T1#Kt~(%*<;s6~W_5!r5@Q26;p?vQ}e@w=Prx5xrvg66tv2 zW*pf91~uZjAhVGex)gowxU0cuv zt0&1)kHJ@cEs5<6x6#L97LF^kZeW_HwsN;-1@q^tIbR&$xKc9g-5h6uYMEcz@GAD| zbJZqX(3Nw9W+ZTal&~mZmbN1HA{xP!PmMnVNj1Q8U3_m%?yr;?tym;$C+d~_2l3Qj zxo>&N1IeGxp{X*6U#=IfM9a4SNv%)ctJHMK1V?&)8e9zmpPAY@=Zmt=apQ zCu{}spHSfn&Vb@q_Ej&;W8Pgj=Z73&P&0#BX;PPf1ek4O5ggRsA1Bx8n1sGs@Rjo@ zhSU6yY{OA!%3f6Qb+m&!W8f;xgHX&yR)@p3d?y&}Spu&HXi_jO8XGJPou(^J%M-d3 zAfbRA;msR>5#&eevwcm{0wA^KS5r??j=zR6hgVxxEC7QYd?mikwbHd0jH}YBAwt0{ zFn|uk)(>1zB-%HEueyZ|L3U#<$CBgS<#0@riM}coB$kx>>DoczrWhh7c<7B$N_ zc4+NxNdaKhUZvZAuy|G-dABFj>L@(7zEwE^EHXu2?6p~8|F=3kE#71O`%8fWbk7S@ z7iS(+r03f4HTFr;B=%ZPo`Ww~*s9RaU^%){*vx~Jop|B7XMb75Pq;)|2n0UmQSt>C z=OeClRoLq9Wo#yTT!bsF$_oZ7eXN(m@E72(*%&wm*@8WA;aYSpk^n8DTqR1KlK^n? z1&vD=J*7siLjr|~&xLiC(d)=a7Te&)<@m5cT1Gt`A9XAmt%wm5zj|I+HI_t)>C$d^ zKoQrNNTP@q54Ca(xEQ#|wZt@p@nAV-& z@fN6kOZX(wYq8B=K(m<5XpF{e)<~d=60exhxBD;MMPm5o;1G@(yA?*OPiN%a3mUez zl*GWIk9ZHpxOFU&sfejg2H9np#J`kAdXB)#BGo9vnKG%{x=UUhhs|^*BD{4Ar$aEL zO)W~L->RmSfIp^~y)qQBf_NI%?jnpQVFHe08fs<>#_(HasGJPEsx()C;^~CT3h{B`gC>_e z4<&GF4z}fis=(I*?+$?bd*JY{7tU-`+GH!)Qs)%E>}MS3RuJ@J32b+WBaq~?*5^pl zbx8G_+uJkoSmtJiDBBiQ?i{CPK{XbkgUF*(?+q}XmjB@kyw|9V;PJn697TBIGw zoRXE-ikIRsCBD#+n(kHJ$WctB#1+W_>3(%+IVde_-l6DfYE=uHG+O{on0>krb4@~` z2n=<#Ypl^aXOrm~I-}1(69`u%8w_%FO(&?bTpLK#s*g(Xgu%dJ8;cadrgY(V1hIm| zdK)hx*eZJBb}3=!ZVCAcusfd7xf+%W1lFno@B|=B|CSGdIMzpj$A=@I7#~kQr{%twN0kkM zr-(me-5D>(vzu-yGTEFvu!`BVP@ET=9gjy)zForem?J(2K}t=I%efc?Pa39O%~G-? zAWH&?=u=S{s@d@#pYVq^DeuDtM$!D*-r{-;Y|1a%V>|LrJoCnTr6K-6- zCx?1yn&XpT+2^w2s%cxXs~o3pt+;9i6<1C3MXs8nvIlrO_bE$DH-oEw+sJzVjQX$i zV{6g=^LzcD->m-Yee1maZZrL#>Cc}3&41eYf3(xwdbCvkhaUZY{{Q*sUo!M?@vd)# zS&+Oi$`byWe?bASZ@*y2s{XGW5q|&$^(@~A9?;uegU~Kc@5vb$ z5hRRcLZvfK8L7kk=-0r}uhnOYmA$Tl19dk7&kesOVgxw-9zW3J1L62GrG7^UFD!)b zn~Qg?XN^r0;!k8|Y@zdN07%5Px#irc3xG{B}X&N79x_uzG<*faOX`AiF$ z7Zjx8AtdHMFf1FysfuCv0umy;n!tr2XctMIBCf{A7MMzf^yS_@|hDx-yyhXy$l(iTH9vtW#&sFjUUeR`F%lFk>6cnex2L(4OG{8_@eEE-2*Jb+`t1DUl5+GUEM2zI#D%|so%j-$L-jCO=&<5<7d8zdJSXEo@&zItPEkou%9J1nx6Wy>JB~2 z{v`G2(b?g{m`Bm1+yYJ0pgHE8$b>m?opm4IOKIx?(5`?Bb&qSni~Nb!4{g~lyeC2r zhwVn1=nDoDt)q_KJv7U0{CmQM*u@78Vh{VQRc&oz3p>W|Kh8|45MW3Ba5%f;e{5t%a(e~@!*IF%OI)!mO1SU#62c0)g zf9ygabWOF=8F_DcuJ&(X&W3(AJa2#2j4U{xxf3O;M2zOi%l+l+1}BLP`^8L@TXsXK zgRgmX>W(}9+D%IS?hHon;^L~4Qb=~WMzM|IUGWoCUp z%rY+SVA@$0&KJu@+)nG)=}PED#SOe+(9_q@TWtlW#lnU@Q5T;TnD& zj%S>%{eddjqVh-0>4@2Cf{ol=IC~x_kGUxF!|>ro1LLok-#5VWaM6Z;`IqIFF>$=G z@Q7X{&Iuc|o=Ps>f9Z|W{?!Jx-dFx*{;PM7{b0J9{UsU=gCbf6Lk$gJ7-N9GcfCG zAg}e_ypI2(`1I#iBWG##igJHR`4_Ayzwe^XvJj*vvRjecY9zPQh5Vk2Ds+f**MVK( z@-O#X?urgpuigCmt6%x|RA1l!tzo02PUHc}^$IrKVv~~*7>3+%1sv_`OJKA=d?^%N z`#S;gg}(i1Ahty{oNM+mqM8aBXW?~f=&$*AIyHnsZ4M_b`CU%Gj{edLWniwuHFI%q z>La>{iTq;2O-TrS%H}k?ySmj`>2@j(m1wBo<}d4Z&_!U%uL3~-orn=39LHgPE*Fd0 znpBV}d^A@y*`%>$AvTy|UGU|9WO z$7OJFfBNEQQ0E?KL#JZ_TEu{8-t6-t{j=HAAvJtmzpXC!C*)ZEkK&yJ zw%txa6|!}o2oN;@ zv2_cZ`g0R(s&m9s7FAQw<1_9*@8arOnW<6jenS(c7xeo34_aS|Q_ZLp6X)mQpAqdF zYe2Df-@v%%sD<(oE*ihazv}9f=wks`>U%WJ2HnGdwwV{M(Xov1XI)3lG(Q-(DDOR9 z`1@;S$N96{ivobV_Q1*yZ@F>^0Ce5Zx&_~vhgPq5<#SkhDwZOlHam!v*KID8MQrMxL|MW3y*+$%yoa-x6V`;Y zF&J;uz)NQt-3dv_Z0R}D->fH#pM{Xmxi`!{@+N*PDx+}%sgV2HXVeX|OBaRY=mVzo zwd0ng8MRu>6?Pn7LpzmA?Q|s^USsQmS-NnQO$HnGu;#YE2Z-1~g)T1{fVj|9 z1SbDz-Nr2XXHBq0_C*Uc42S2+KZfJ=J$&a5S9DwD9xL!%$vKKNR3ayv`yJAGdFQz- zJOZmLIyk-Nzp^}IpK#q#|QiTSBFom?3Yg5GuEm- z{NqFSz~k)}UaD7L;u~S{ov*9!NPLKU6sb^bKb6{!zdJ$7?@p0U??9546%JAZTWj@c z@;NgM`w|-Du-?|06&>w2-sKBA1$^3lng|_4EcW`k_!28uDqBjhevUX0E|%KgZ@)G67xPBctnRmC<^>S0W#6!hSS$)u zm}tZ(%t6hW6qlfJTl;`HuD!j5Y*_o^Manqp8!ON;CqrW8OzPq8?SHELv33_|o4;;r zmoL62;{nR;)$fIQ&L!roy^byU+DLL_rCY+xSnjPT76Inx`oo4 z+^l=&Vxxi&4%6W+?MMoNT&RfPy-2Xy7vHgZBcu2WIX>XYY|@ru>w(U5 zd@uH)s&MT_^P&qSJI%>hWH(R%3aCP%P!~w&9GeEvi|+ZVqFpHwp&0_o%wxn-f3ETl zlDWA!sX6BZGa|q^1wSL5p|Ogx0}{ov49FU3o&EbDmnP|7q+@8+OiL&yHO)Is84^>-Yb8)XR4T&%uQo~f%b%!EEi+it zh)|XH$bkp78xbzXM0V~nT`W@-IpOi5Hdf1SN*;`&`98|%Xk3GxBGf3dSBqNoGF&o# z1d?8;@p3+(*B|At6{*^>OJ*iyG1RJi4d`WQLa`!uncTpZ&!ofxhn>77SY0?NT0UDe zEhIF?@5k@t87;t=*f9l{nnv=viAGPVz_NGbRhhTrp_{N*<9{{B9bQ&sX4ZZPe(gJv z*bn~Lk*Q`0+NwONE^bc6MYsrxjiZnO6`hi`xtSh;H94hx)R)d`BhwR3dw62(;WqIJ zUajXAPVv>89?*K2p@z#vMW#%HyjVt~0&v3s!-9cI5QB7TZU9nZnQ&I~2}KokDbbrx zr(~oiYMQ9V+TV)W3cnSky2V|SF}?`eMFfF2aMdqdT=p3m=svVh$8@#Hd!$SnCDtvy zccg`@G8sB?xDt4uEEfgOu<_#9@RXWYo@?voN`NVKtO4kvnEISm!Y8Hbpf*!-bYMj1 zoLxF?deWoxoG(}^-;!{ZUM}DY6htuwbXnYC72FLcosDB95@im33)VxBvmR)aDUAsX zb@laN;Y3N2H0OG}CUcc>{NUIxw>(%wQc)e;e78%F6!md=!;zc07!pp3JkS8WT;Znl9cv>HeXM!>>~_XgBTiN4d&K zwE4pA9a;@8stmw&FDecgxDdoIdBfDf>?Y=b)S{>>nkr)*4N_h~S+{^IqC%A(j>i*l ztu%1MY2uy4H=npeF(0LM@wYDecJ35?-8A|b3~uL$`3{7xIl|S(ceG%9>x@p14M{0I zE_+mZOq>wabD?IHGBj?B90-@c$`l3`!yCW_5XPpaU|e|Vy%R_wwfo18IB>vij(|3y zw@eM)CDhPeLJey!WfwK9iS65wS8jtE0v9!y z8_{i21MLNw)xH+;?qJ)m-TJnli(MPDHfmf*y>Ha)+!<=Rt4T#Eo5ZZ)H=cjB`35Fp zab5%CJ;WTN%_At4i_Y*y#oJ}_h|{@HLlnFs?GP!faFp%4bZ5z^sbA`->F=XZ1s@c5 z^b}nMi~%SB4jsj{Q5kyM8QOIw&y}QOi#lhaihsNiDok2 z>Pj$34H#t9zTH!O&mr~KtM=!g{D7!g0&xVsa#w;e?x9N8AQ}g6Aa_{Ii`<3eIm7V> znQO(tj7h&tad9cK9eOw7F;kptF(~dF!g!4!(Jx+$_k&sR8QB%UUCqy=Oe<^+3R{E1 z*5F#U20%sM)3%Wm1_)~yAXpguP8o(OK7`mdH@x+&6LLh~W!4GCJ+fo4a*t9A)v-FH z3s-(kF{6esNWEHs-N2^yWjA7qD~WUz^J#qRmJcheg=}{%1ZtxQ;(H4WBOFE%csK^j zh({UA2*ujsHM(-vvKnT86PK6D zZ&}EMW?lgblx{E^rBR0%q9TO9ibs;`q`bnVWyZz0a$T>k>s}9zx_C!Ot@5umf3@q# zEy$G%A{~>4L*{J*jex!93u`>3>jqoHw#9yc07K|MMrGB48%gFh>h6@>+Bx1+OP6Ko zvG~hFb=@fyveH3q6j+y-hO&lWpf4LcKC%I9$y;jiR5`dI_6*osMNF)@tS896a2W;0 zWy`2rxkKfUp|9bG`4iQCRkyAoqRepuiq$HrS4{?0o={FUcU{0sO~R={~Ren0ZA>X7LC zuaGhx$@oDQpqc?_XDJ{K$M|ZDER5X)qbMnu@&W9xj2Jp9$b)o;OQyXYkt0)_6VZEH zg(NXdn+YLO7lemoIXE%^u9}%WtPnr-l$P0SKJcdM1u^`j%mlKLx&)%8k`RU zFjRzM>(zKV3WlKfQK9i*7316UAnB+DC12&~=>q=m#A;5_ z6_D_VxIwy`_M~>p=s+o@spG|MMI8<2HAXWQ>2qLbL0Vm(y1ZsrXa#~1rz>ANf;*z$f;2Z*^cyP5d1`) zLcfJ;1+g?hnP>+wk%{iMRFDwtj9d$<6DNW_1!m*oP^BnSNq~7Wo~?jWW3iP1B0{36 zlj1$;DIrmYIWbC%C%S})loDBh8H*=2kW3M3TkM26tsB8ta$0wSwp(|0&^is+QCp1e zfwTv=2qTC~-VZrz8XCDoAt+IzBbJ$}Ry_5NCzb{Z*7e~bE9-OAv}YWn@W<&2mXjIV zV$)DEN8!We)l47pC?0RHkEKjI;c%I@jSJL95fOo$LgQlqbh?K}Q!SC|PdN@^&>72# z*aXAnGq~@svJb*qBo0Yn`!JqPFGcc(ei)!RfnZ^9u{8`WKw@>)onu>grgjhak$3-V zskEqo1ha55^@_}}CkJ23p*%Mt1W`L^{((~1y>-|zjoC>Py-PD$Tf^$mEaF_i9&Okc zuQi$#beK~V3YBW$U!ZZoT+wJYpoJ+B^vm)V7D4~z(U|hWy_flN&0w<-y|b1dT{a~< z7)LK#qLVvW<+i$v7nE!Cc-{V5z0FCT0E`pEs1`ZFzKr}|k0~JDt!DvSmjBOh9;EVr z?KSO5X20s_)V3GDGm1(6Qtk04D6-U2a9qk1&?u=zm4c|RP5*FtxAFboZyosQ{ogP0|2_!%hkFfN72=`+a)D7E^eO1Q zc#SH?|AD{K2$k*%&!*$~L?wf)b4cF?38mhus)P&}`8!}k43T79iF`n31=OO72sykF zbX$~hj}xVF!3OH=_k_%LyHWgjNa>u2GnrTB&V^jzwO6+C`OhUfCJfFYj3 zbr_CUW}%e)P&S?}N0ak3dz&s}(Q6-I0irH^=S9o%3~y8u>L#+`k;Ukyt*W5V@6%Go z5W%vckSeWQQw6E&$+g0esui%F;oFbHQpo$iUa?E8#QzO*s?EuN&E4IDto+w%6#V}o zp8p;bo65_2`G%6(+Rk&zEhe#YA_%>gDosJq%n<&ldY>BU|Ad**45Yuh;c;QaT~rg~{u`dh;0sDg znnyChmK3y|QKayv%c|A_DsH{VN`#|AyVFE5XWH)}#f7-ph5KGCXEvQ5+icb571$-s zt8TiQ?_R5UbQqJc1N0&JAbpE4ZLqK;FZMItNU|xkVoEuL9$@Kp zp^|Z93alv3OL6E3*0Ay_%|<%p^)nB_C?UOQZ?FGZSFM%1@AP@fJk04nX3_wrq_)rw zA4a)n`%m@EXc8s7!{~`nK|OOAq#R7R% zN;)K}@Pon>7>Su#Wd}r4ii}C$@SQ1&+fY!5HH#7$A(LCyFWOQ@21VXdK|`TIlpup4 zWqlCV41A>>+;yy3&&S-Hrr^P3{Tx_(s zmu(TteZ$L5w$ttD9>M!*{(B!Vl`MGACunj4Y_o%A3$&cvaW+?v`8o>0h-Yz zlmK2Nlt=H&nR3fy4Gv2zx>RB{KIcLlptGnj+~nhxQG(y7tZQUEx0Pju=rXr?97TcfgcC>3r23 z7?~hyqVILbwuM|K;7@7U_Q63^G&B(<4jV89LlJlz;v7*4WR=}yJeJ~bcH9NCP$UglqP*e2{HRR*z)laho87mF1`;wu|a({=4Xg2KE{mp$impNZ0fx+7Y%#B8;sBzxIv4M zGxf9{3cHonIi)khld1*@T`QX8{w4KH!h%yq&@+89$o)Dzi=?p$IdCY@VVumT(r800 zXos}>#&%R=rWvF8%-xthWVJYW zL)4;J6wgQ%iCVhsnxffOM-CI_T9T=dydYT3jigf#n)b3XX<8!Xu*{;COe(CIDASbrb>E$1jf(T!&e{5j_6etU8qTgaspUYRu{6D2I0G9 zDf~ps;qnJZ7m1P!#d2P@CCcItEu}A!(@#uEoqmWGmk92>?4H@8mg93J`4g1obrmhx zFA?oeOyT|nCG=D$_i{V=joG3U?VZAVO;w=d0srCa38?0^pvuS}csN+Of_Yld=LPem z081$rp;s_oO-R{n;(o-*78scz&wuJ@Ucg04TNH*51lrKP%>p$dLZls#TF?Nc;A;!J zJq$FOjFmKJXM)`l2{uVlYVu+1NHQPJ5)6acUO<1z3Iuou#E1JR(VG`|ZsK#%9&U*a z+VlFJQ7=n+=z~c_hO2ZoEJ$I%&BYVgGe33K_(P9XscY|G;-e>bkY|(WduZIl&HfCc-L3p6f2_C0xW(;ibdQ&ZxkgWfjr+L1Aa1HkORH0Mnx-~ z4xeEAudb(~M4l^2q71}YDmU*e?$Vbs1vAioFioAI786gUJ`M4FDo+*CZ|4a8f3M_0 zY;6j(w?M;d(d^g}2fPLTop^6^qjR)*gru{yi8o4~JD#Rlkqkh#;C!7ISNBUkX6KE$ zIBhREZMzW14i}xr*E`l((GCPME_JPIo!(Z5nZ5bBF2DuHF>x)R4r93|FyjGa;+oI_2{kp{C`ZmAvSFquuq@!2s{R^Hi%kHym! z4nCmwMBiZd!RL+8J-~ zj%6ft*f;H%=cO$f-!Pi85vThRga9}6O|aATL+B*@t&&ldh=3ll-{a_l&1aYvorBuJ z?(G<-JcvkWr7c-GEh^{1 z=4Vsy4^f)FFY5Qc(QhqI=fQ>&Ljn5$zb`5cB}St36a2ntlq8{N1oWKJB$qE1%hN)6 zRwlm{+0`jl6cX&Ro1kRXtDx7{6;i=sHqm!wbn~V9hX(PfQ6$wx#}X-ZnL`u~$7HPy z%_%KJJO(`@2!|jZ@*Ud~W=N3iwJL*Zqn}{Nw~yXThCokdpy!p=F)2mh3fNg!oPF35 zDoLeTne_ETx&kupeC%r+M;NZm9f>J;s{4VPiO0cR0PWr;P>0ZcU5H^#)QT~o{I zYhY$dKx+~a(n(&g2^EbQat;`}4i4q;?@;k0UdFTU@Z}NnDNqnzS)+>@ScXCud#J1D z`^ax|E+;hWyDsOoR{=k9ojv9(0bb2s!P!W~wxUQQJyKBeF-GPk9H~LKceYuXkGfKY z8xK|{gCY2Jv`u07RHQX{_=pz~XIl7q$bUju83hs%Wt;6(sxrFS_OY{g$|6VD3!&-@ z&Y9)y!{hA=b{57X0?p0i^o2tkcPA9DjAsdX+A#J%&wqOPedqaiZ(jcL>NTF-PImZ7 z@Q6L)hrq*A8SBtAl|+nn2!Bt@^q1JO1*|SSjGyXIAj%5C+6tJaeMX(FvS-=~;F*Mf#IPjU zbqrwky_Yd9MuCOrgqZEEj{?xuwkNFsvbG2ItUNQP#fJW?#MGP1NvHs-E>g@dMTz!K z9L1R2q5O46kJ8&Z-1+ZMVFKB3afS<>B8S0r3MrhXQ}g7a1Jv;6%7+T|LVLn`W?^tuK5NsHM!jC&6H!mF zYRgg8QKu#97$Jl0$&p@jrra#mRdp|G&?CM0zr#}_us(^AqoXn&VyMBgo*+1};hVY$ zu@|VYFlBvkq!MBknMD+#sY3FJRZJ~&S;}qna(HxXb`$4|`oP~E~QVc|PzT4V8E*kpt$jWSj>GY*<=78xPI5D_r#<%bXg z&6;}z=(vM-VO-C>br78M&?#JOv47)%dV40qf}Qgb;$BL91}4wbn-EV7hHq~i zFdl_~ZV2Z^!(+tSG*U6^Y&d|672%}9<7N9JSNQVo=nzra-mC`2j3v0@ZfG0fJu~{j zf7wQJ&kXSQw`G=p8TKoA8>cxM%mo7>`R%6^MpJI7&K6#UA97nTQKDP0o@QHcZn)Cv zSWJcZd9q+ePIaODnITQaE$rCYIkHPA0aEFp4E`iHPmtxoxB+4ajz`kHMr&I^JQvbG zrDCIWP4Cf6AM|b@@dJwj!CW2_vW0fG>*i3h`Uc)z$bdw4pK|Cz_y~iOhT&ta1LN@* z&C?VAltRcFB@T@e4S2mmogJfu?<{egfx4)U@@mVKki>L_L23zJOB#8$f;eI=U0u?A zYL_=xu`X{u&BD(JGp5OK270D+zRj;g{CT!a{;@}_i&>8yf{;COUC(;#s%K)rZZ1!f zlC5QHnNM@%ufoZHZT;W*Y($|mZdU`iB>u}mb2sh(zjx4R7W%)3o^tP`SN12a)h~FbHRtk5LSH9`}F7U<1#&z!-JsvylAU zQGSGo@<}p=KrTVt2`?rAM5zk8NhkT`P0K3+-B^JgMP@)0xo$5c@WtN!sy zdZRxxdI~kD(1|&KQxGpbeBh}ji~*R{%;!{(p4b(;ITgE^id`=oLJYVY;6R-bdPzbR zRR%6~K=A$%cazCKJ=k1i6lcR%hOw{8hZ7Lxp!$)w^|908r`&$0Q`SJQyyLBpqVm<@ zV_y9DtvD9QxVg%~M)XbQu+-LEI)ntOW6^kuGFk>xol>;4AbNwGR!(*b18IMys*gtcH+^B=!raJh%v?KsTZU+q^q-xV% z<+|C6zJKw<^WT4Z)A{9BsYw4wDTgesa}1KS$VDWH)_m4WQiW#GjJHRRu9tc!8`dwl zR5mMQVdoSa@vEg1fytp*=8?eNX#=H2D6|FN-6l7RM}7SUew1Y^Jx@Lt86rm$H@fzq5oO> zuMg*Zv#jCIHdrk}`;?K7kCT6;B}>EOV}Xchalh6Z5666i}L;M9tpjtod zjmZ?KjjOgMGTkG5T4s4b`~86dv^$)K|5V5oxM&#|=6lyw>D*V-V&D=J-oU)M)=2*3 zXH_=*}1jvsKh4Epa6dWe?-_cD9fMVUwWkLiEpL!^AzP^h7!)aWeJ&G*Elrs zGdMqIcO*a)-ib+Xr?~a)E-JuZn~m9T>pFI23I@?G!T;}M*5|*|MS6*7-=HZNTe=)l zIF-a$O`do$RLs_53x=u!dO~tzeL7DIPV&wIFDAglE>p@0gc7 zJm;(97^@uO65}FGdeL#&hF(#z1ojV1<8$NzJA2HRut)FAy0EZm=wQ8lN!1S@%k~ao zyATl1eRr$;ITe^3{}i6_X=wA-`6NlHOo))jzrZ~`-|2rDf~7bwa7@yj=x@44SJ!wI zeh@Xd{3aUfNAG2EBs6*~5a&K=EM%9=O2Teg)s-{Tlu~cjvw@q+&xqkZ6CBqFL3Afe zg=UZ=h31c@?eMW&K-b1hp~Sfd{SSl$xb^VA%i=#CH1?Wl{SQ1U^gj zM{rrf!0Wy(#jB+PdU0#8v_#kG39B^L&i0ibNV9E%rre6- zo&r>%v)*@HBm|cwLNK9z8Y*uiuqby0JM81($-Z$%c#|lkl$TJVo;@MJ;|_;Z#R44; zt4ejMY%mPYI%?Vn(J<@`!}x4=-qFU^GNIt}8JWgaWzTVGVC+S7iGnC{-%>1V5qXAh zZe3chN9-gWCmJ_k>_+8Oi@j9-q;Xoe;vR#zYrL~!AX^4H-vu$cmd+!<9Q6~;^tL`? zTguw$pVCmDA7oXKJZZs@q|{ryXOvvAPIsjpj$yEX=X1<4H14aki+scroJzjmb`ab0 zJx76@hx#A{EmEVxB~dve<}=R&m(9AYnG%8}6a%2~0v5`Vf+_?IQ1oE(N23n{uaK5r zJ;TV}a2CZB?A9Y1m2+q9&47m}fUn}nvG!q_Ro-twnBa>tq_!Qx-wx}TCJE<=t zW0`&oToi+*d1I{&?eJv=0DMbjaYF#vf;B%?(xl=gJfsV4cXK+{O?8X_I6BsCIt%7^ z>=`Z+LDYQwKt;T@nxKt}S%?U{ONDsZ9lH=H$pxGy!D(_hxb}?_0tl7h1$ShLlFa>4 zH+KdgO5>+tKVm94Xu#>GYG_sYo%oV%rc1r9(l`~42Fog*e&X2-@VgDk_wnrllSnblZ3(!kP- z(0W%A9?ObbT6>D_7I48MK_+}KWwl;+m_pItvj<`S~s#Y04x}(e8yBK`dd7C5X3ND4M5q;6kX!C^~gx;Hj44KUQvQ>8+llMknOSg?|5WBhrzCZv;) z<;#HkI@!+1EFLM0V;XVU>2kSjk{R_`tk4QO%?G_h;=G1=Z%04 zXCg7E+WrIOhp&^Bl<85G+*gh$6Nq7pPp`FIT3fCZqEG|@RSk=KKI7(}v}=ws$I$=x7^p5L)CmLst&jBO%4Oki#>#;; zJM2q?Mv&_8loZ65ie0CYAPW)?$if#F|F%fA3@fcGk5#Zz<<^9Y%*47qVIKlc{oacU zIPJj1XMvgB1fY*RLqsC!{aEI$rAnq)qhu;*+E@gmD1j3#tV)zFkJuyQ1j0`OvH;YR zrJk16jv)_HaLjPQ(#MY_uz)Pm7unwh!`>XC$Way_A^A?pSpFA@jH!%WsY87P*1oc3 zl&f-)y%$bM+@5OJv@tOW?6>k)7e<4E@d#M_#fU^_I4I+>FD!doA0+`G&~h6EB(LgK zuC_jA6%r?;l^IV?uQE09#E&)K#-2RRzZ|F>Q?N3DtDTA9CKJvnW_X0afKSrPFcg*% z#yXTI6jVp4gi{MDQ7=ox3Uu^b=P^Moi4)B$>vg%2pHiMDI*U;bY=OB$=2f^rAue&? zn|J}EPhTooHQ&DFRLtaRE1GQRB!jbbO{YA1kah*`q z(mv69fxrp>mXDL;JH?5MRskmtT!|L4*Qb(|X*ZnIPGPgR#k8EErf1JsZR?|isVS;* z#db2!fpc83XU~vYL~FmyXP8C}v7Shcs0=%R8@rMG1ds!=pQ10Fb8L%siP{T8%}p+2laQrj$H3pg@@6si^Qqz1zn6WVA(wnWi?E8c)`ML2xb zJPkY3yeua57@`{#xXD-o38WtCji*8ti&HcPF~arMN4feLZW@C4uN1*&?+X|7fyNE{tds?WC{Xi1M_E9M zIVxEo{+8JS?M=y*PY?_@c^@bVAnxkmI|7EOHC=+@oQYEExKQKEhjU=Hc651~;uETO zdcv0r`gMqD98Yu-BXhO!ldGT2XC!6=Fe4`H$ecd@c-@`MT!ngr*j}_jY_HQ}d)HeJ z={w7jZXBL=%--anpOdPMdtOWLz83IPA}njDIJ4=2S_57imFASX=1A||lI#94j^eVp z(^qo0Uvs-v?ycz)n7sv?`|H>CN6DF%D8XN_1!66;YQj}Oo*cV6zqt{ES@(4DtCE{> zOYzwRvXp2&yE;{Y5GS znSIN4Wl5o;vMqqFzj57g>&n@?uCsfk_AfC$y@4@3WaqB1+PfYz+@!WsC8dD_aeD;mTgT`CfZv@7!o*FOo-YZ)LBvuu}^; zyN#M#rrbvJ)sDBOqswlGTMRNK^rq2drtX%L`D8NYI}#d@L@|W0gm6iup%L|{ONYQs z0A0uJg{OaL^m-z_Xb0wY<#yH+_q7~s+{J2ri(Ccbo@B@KQbk3SCp1{luELH2zAmuC zV4YkGHdS5PM4mL6nD=Tzrr@v)g}AZqrG_zM!gOMx%AramX^okx#MJ%UO8U#C4V%#A z5M`W&#dr8CX~=-Lg_^O^j^xyhxjBR^QMY!t9G+lE)m!XeVGMC-L8DA+=JCK*UVyFw zR`pB*aoGhk5PH_3y6~+B1rfi&9)P^jo7I2zHO((dzzoo z7=l~NGbUd5z$52n52RX#%VpyZYlr!js&%33oA))^;~-U+j$^v6{B5u9GQ_42;oh3B ztAsD0@dUQcE047)p6CKrjKfq59!rZih3OBQiz(h632wc&95fkNYI zvzn|1oMO|F!f9dvHcAg@+7J__K2*=vDl;WGkk_a-hzBWNeG5~W0j?PIP3BrC54j-0 z1&agz_RpKySM8^+(m|AX^+NOChwZr2H9iT{V+*gHu1 zf9(5>R^k8g0Q^5x#13U0Z&>4Wg!fr6EEDs_NbfozzRvmb4>AGHc)O|Z9WKw54OcZS zI3QqSckfdu5!z8Q&Tr24P2nJM)$ayF&|LHvRhRO!4ge;TOqoH!4EG9|HC1iMQn0e2 z=;-qx^TQGPlc{<@V;Tyjib3)X#R9$(n-6>^g~TUn=R`j_ReGD$Nr)LmPZww%j7q6~ zr?wMg@37Ygg@YVnY!%bh=A~pfhJy`##5#DLJBC9j7|xDH;~2C3$S}O7 z37w834FFykVInd2J3r9xba(1zZVs~VBLnyk=i@~9E@2qTgtyZ>7xqwO7*&#~`9$?2 zXZP!z)s}-Q>sC_b@#u$AREN^Z;wg|Hk3Ok_d>2pPNZH{-;ba$_M5i3kNqAb3r_WG& zx^EeC2o!6!%E2fL+^+i85O2i7K4L*#*tC)Yr>oy|?Kkhk-fTQI5>UhZVD-KckQw zwG@p6VByzKfrk&Z}YygzCPSn3~!D^fP+^Rh60wNAl;K z6Yda625FB%uWF-&v5JEuyePKVb3UUN6V5p)YYm)8F?kglwvMOok~TY^%_d3v@neu9 z`FqZx>%7&+v+*SAJ^rTYefvoD>!@1+}DOhNvtjs$N&qWGIy-2M$2PF91DdoY+u<+=g$GUv@`09ismyfqL=I zaMFNcb*1Q%&HSMm{TAdGJck$`Wb2DVgQG16+IvTK*E4Vc;)j~?^ipJsj!+)}sID52 zq8X+D5*D2pFJlz_MRPQnPdR==v)ve62;fW%u+$Bnp1L#6j^(hD0&*5Jkos zh>Vl@aQOJ3X+Zq<`6XKO!2KK-C`Asnl>zcY?>tN%A3QO4K~%Gs2`wjlLpx@FRIEq9 ziB8!ee{Ae-y8IFQBX0|&i#EQDdm%q$U(EP%n;*WW0&Qu8Bl5*l z`Gz{x#yC8Tubn?mC6j(9nY2??Dhg2#Y~>+9hFB@sfG8k2@u@Olo<&0}Vz#3A2)sD) zPfrDyljf;4BKf#+n%6yoV_FuYExWLwN0WBW6NZ<6g|;KY1ZV_IA5e*f4^>{l+JqvS zZSjRZ9f4aYE!Z-}N==N2{5qyNJjq0QRp|t0V`-}_(?!WT5HYJFGRn@vo-~m+O#5|T zbqax!HX=(zRwc@~DdK$7kUO$wS$?TPx(U=5HOz>;ziMoZ8QpYTppuG8E5l~a20OA< zVcj6LKdLQj+zV!@AsQzPvx`U<&!=Z|kTPCOr{if=`AZ9~kSMQo$gfU$T|OduC}%|7 z%VSz6M(?XuA5TqA_TmB(zJxXpkS1quz*L^s14^!)T!>E{09uLBQl|J(GE5IGc%Ny}^d2K*qO3teTjHC-TA{9qf%^*tf(I zD{AVD1DJz_F=JxWB@MwW6|`J*WomZC%r;=cHy6vYz8FhsX=jei&e($xXnM2+O{vzz zh#oB*5w-ouyX`r-3vA}j?5c>?-G z$h9tpkk1UR#|Z58WEh`_YWGLvtMz3gRBrU<(F&Nkm6dNAtMg6y9hxQKj!ORcaAc<4 z?3gy%)YW!8?ikTH2}9($4^>r1^*-M#6}5{0M6_B}fQ*b5CwSti;&p`F z`r5c*8)e{SmCi=0%skemECqHFnrjhK3K*R>If!qW0IIR;OaqzTI2MrA4+op7S*;kD z$~2P!lxirinXHWMy>TAP!3q!cOk7+IDfcu8u9p;Z!l?1Kq*E+`TqrU(3h{V6<>CQn zszNP@p#+?AxgmD{5Xq^u0KXBx4LX(ANP3Tv{_&7*%SB>`28;h9S>y zv0pTXp32KHsAvXhq6ien_#6yOw4K|01Seg5Z=3lb2h(AKZc|UsnT> zU6fW44i<2#UC5}{aLUa>#UNv9Tn$70Z@xJ^G9XFIN3bl|fIbC);?Dy>oOdNMbLXc6Uf?xx+@mgcdaNdk~e> zwG<|$rSMWBcQg^#K8gn>_kf5#9#WJY07`bZETefJ~882p6#HhC|dl5xU_B)xwd~K&z)( zku2AMsFzXtPULW1(3BwhOe7;mdJHGC}*girAkll+s@yC&?-> z5G6+p0`9{>3UBkP?A<3OZZ1yb{k;V1n8tUe;7=?=$oi6hC>0(;5|nJ%jy17!W!ky*zM#3+2&+T^8RF1~EQ zMhfYOUt#CXEvy3+w^a~ZDNeOCNhej87#9H~=*XkZP@YM*EA4>sjL<~K7z37WxO3xyppm>x)Bo&;whqRIb>GsC^3e4CuPfkpq7{1tvhV3ekG1HvQhrqEZfSO*4S$R&v4hJQQ^PC3k+_xd^hytKjzjyM1}L3_ zRve(|OLRvAv;*y}JV37&Li-ey94{fa!~V8(9pyqjsaCO%Vs*^Ma)H!6>Qg7LQ(-@^ z)xq^!g~Nm}_Yx|TW!=blLFUggMT@V&OnAmzzJZ?N_5eM=%;&gbL6ZdsRgo@k1hp}# zRQIw5e=(STtm1-_9tjFBi_qYYFXD6LU30F2#D?EcbQg)9Ek z)q?UPay0NK;ifx{LY%(eLi8s_|3his!&wB3P_+!@=#rxjh|n}@7cAsmhota!`3Q`I4ZrMcQT7B^1( zhp>hff8=>tEK;d$N3Ns-FoN$=Dc{5wl1Sl3y&$;}lGWm@MhmwAG;D`4^=?}KzuPGE{}0Fi zTZNPp!k*y`UR(-(LHB<`ZE)KRU@85#8fp69+uJYb{{hgy;j+)kU;Lsd5R8diH#koF z_5FI&E0XqpcApWKj`_)MG`zz$meGG>-%rth%ik^X|8C@SG8>PF$!Tdi?}EO@Yt?tX zQt2d&-=CI#e*W^+n-{O1zxwV4yaJBk6@>j|eZai!G2LZ#;QJk<|6WG_y9cfPO#biP zBL35Zvj2g#(SfV1aLV~ZKZJ|WZs>3u#VaQD-UFY}e&3TfPszM1f?&%c{SKZnDERb_ zhdD?*VV|i&PDfCK{AoLwJ~{04c^QmJoGAfsMIPGR+RB?czsS-8bZF-T2v#W5#WLzj zMWKh`IKovCR9lXq#mJEz`)m*d86rhXt0L*>HdfIxL_Mrkv?higZ306pETs)%NJCi_ zNyiTaNlTZ~9U!T@Dv}OA7bLB+npQ$mLO~D|f_QyThkBrRH8X=0negtdGVO+|-E~(Z zPpJXNK>THbSK-Gt7XE4YcZ=7u8CjrVzZO7Mb=gSDuo4IE+~=+E5$Wyz`q(MkF%S&L zbcn}n$22e;&MPXeJj+L>Pi9)O4u8_*PYfuYy4_d}$7Ww;AwOFrjcc2bvUoFF zBn{9Uf@1<#l>adz$6ZPPOXdIO?tWVTzq{8g&i|j4{Lje=ud@VUXD$lb?bjT_j|iaM z{u#sNP0^MfI0R-x?19%CSr$MXR*JLpXH&5XTBUv`X=W`Cbl_HDAWkGB4z^fCv;mQ3 zKLk@sc~B9ARMxN!qw1WVHAT<-RL`0mfU{>!ii^9nXAoF5uWJB&N!Nn2Ac_;r?o3HY zWV}9qX)>F?|8Q~nmnVJK=&$gEU4X?5@&s#l5B}t|$}9wA2k#DTM%m59 z<*tYqB*gF&Ow0!+W>=Pz-Flr~IM>@37u#szvV9R;bhp(Ei|7sB#RY8#GA@G$#XPeY z8V?u%piB`MQrMw~2&AIAM?dZUO{IsYTzlG%yv(@Y3#-)wa*Hn0D0r1gKh`v-op|8L^MXS{S# zDE0r|`hP|LyLX1h5Wyf51;XZ{tNmS^dJ1^Uhe-Jtu+1b7WBWFPw=0D_zU`% z^xyr@U2uTq^uL#t{|o!SjeKCn3l31wKhb|b@$0?h{f6m(ua&X?Z#8!d`rpX;zuGD_ zs|Tf4)o+z{t4+VOS8e&F{pxP3bWq(pC_Skjv`XJpzwt|cqw4$okI##?N`ABI^VdGF z_=Nw0s{GwvwYkgx>{pw-mVZ!fHF%LH)fR{5e^YHe@k`A{b(go&^sBr3yy<3jj~8jS zs(X9<*KT#c!Qbsw_xJdp{pvx3KRl=&@P?XCs!w_H`9I_THJME~RYw1d$=HcJ1^^!?9%vr(M?Hu4$AVQKbZT!LJ( zVF~8H&;}RuA10KB9x@SuRWO*D!{fW6|E5j<%_bBt=>J~mzo3b~Fa2X^eRKz@r%B(h zh1YFkDgC$7^zZNQ7yjQH`MkoQ)iA-3UM!6J5N{KXfrS`Q(7#RpgN@REvHutJUwj@8 z{Wmwf{}=RM(0}oHNc6wi{lC!v7xZ6z?uGs_YYO_s)_dpS;QAZ?iuCXMDf`c6qtz(x z|2OhEgpeda@5gPH&kGJ=7g$=Vpr$XA{s;F!|9%nwy`cZ%bKmrTE4Khk<^SE3{ZF&S zSwKPm8=?P#vJ3iOhyDi}qW{AFr=b7h^U&zOxv~Afp#KLX{}*&p(Es&s0j@>=Mf{h7 z{)^AO(7(uF3Eyv}jpg>g>G%%^t%KtHzmbpM^Gk;;_)n=;tCfyf5e}xHf0O=ey$#TR zGrj-&2m5{z|7jziufP79rDFj8SF_P<)EfJ>W{dfL+uv)qnnt4VT4T4-0Di%;!NXRn z`nCOm-^^$D^^ssj{C5pF(xZYS-7o!z8=(J&-^|c|asR)m{lA11RxfC*pnnJb5AKQn zi~Il0e7N{u(0@Vyx%5BZg#7QI|04d|W(nK6Int*{|{vTZ>j{k#{BQLiur#y^B>;B{1^Uz4`==d_b~s3 z|JTEr|M}+Uf3Kkbhcf@oyO#fa-y#1M^uLkMw^1BSFVV^)VL8EoG0|vFpioS_85Tj~ zzTop;^RDH82mKfOe?kAn=b_Mlcn|bn-2WEzUwj@0{SP)z|GUNgZ$baX=V8$QeDn0b zSM2`<{TH8mr+)|lbJzO6#z9v9cTk-FH}YxqTBSqAnAZ=J-ZYxbqH*lCnRgy}!X+g8 zZaDS|djA{I|6S|<_8RHfyCj5)vG%_ zL8`mt3&Pk({(sJX;$Rd4-?{LrrAIluim|KG+XWu1=u^TWqgTnwkb%=JgZww3|GT#T zXtlERU-*A*X#X#{mwjOnUhMz36aeyC^k1C+H}c`)e?k8R{V%5fJJ$cT_VzRMzgz78 z8~J1f__gH!tQW{y@;`claH)I;{(1JSL~^+$me<_!{!Wgt{w2%m_eK9VH2_?y|IfsK zYP5>{Z=3lv`w;(S8up?|c+zdR`{5v%4`-((e>d=VtNuahSiT*%+nlUU^@BRuVM*jzmO#Ju#MnV7gtp97O9lX_Gjc?k!t#)f~4FzDP{_e`LV5)mk z11R`NU@)edi(9FZJ=ep&>tSfZG_`}yE;XyZP)lN2pL0g3OBC>iu0}?#hq3W+C(T`V z(%f|?&0TkHle?})|NXn&{~LQ5`Tw9e|8L~eZ-e zJOAfj0IYWYryGDheFNY+@w*QEuJgX@xbHaaW1G!ti#O_556o7Fj+!IKGwTGOKES8X z@9E?FgVK#IqyKO;nO)Z3C-uR2KE)Ie$*t3WW7kjTe`po=|C{+V0#10PV>XUM{_pI= z82&wm-~jgbc6S8;m!`d8XxXJkeh1mp4zi~m z!Jc*s_H2&(EeWn+5*ZVxpWib5H+Oe4^uJ%&|K5}SZ*}=UtNUA1{s%=|quNl)za13wQOXxWej(%EGyUrs z1tx%NqtO3-LG;fluiq#g;sN^*57>v|fPGjTunYQk(SM=;`=a%KYwqDU5g-=2|JRTw z)sQFE1W&3FPl7fZq#7(Jc=Pms>-xWp{SQC?7xq6J+y4t9D(HV5`X6k9{tNq`jePn( z+b!t7p#OE~ztI1E$@;%F<^QY_aCP}#x&MO_5RyTn#E$~MkoOA}#68o0lqB=;o4w9# z8bo|ioOOERcotsFZgu}}rs;pTRpkHMko?~R|9`*P645?)_x1~VE9ieI{jZ}0T)O}7 zr{jO{RansfJ?Z~AFX&uY+xJ1c(P;Yz^~OPC-`_j%_j6T$eBM%Z_uG3<+RgoX>q%q3 zx%;Gfuu%2aB-P&|WJru%2s6MY>G~cacY?hqp)n4d2hu|6XDLv!VUJ1VmLB z{1o)R9{msQnEng>|3*Gs{4eOgp#Syhe|~%P-)!z>=)Z{nb6@(u)#d-J>Th-VpHzQM zF#T(y>JKFT9hC12@%{nP|A;dHAp1D{fJ$Ni8f`4y|M%1W|E)$5|8Fy&-QKRW^dkiz zel23?7WAJ(|JR5Gx{UsJGy4A)hy(@w-;4e)|Nifwz1ymP)7)?Pt(L!v6L9B4G&}F4 zm(WUJmt+Qli$aE`flQbNKGLRvMxLMCas`LGF8znMPXCRp{cp3#|MgJkf3TVPFYG@a z=={%beg0cn|DWb=LI3x3{$F$dU*rUMgZ)2~83cE7+{jJSpq*kf-z@!KCl|=I&i}gw z{crgEza)KT5fH4Pe@_3KI{z2)-@TvzZ?JveSgg42`G1WZz_~CA`d>u<8#@0N^#4HT ze?#a0;{Nx6&i{ta{{{Wu`}zL{`~Nzjfo^jCU$os9!GqSOe;K>|cH3CW|Myb--{0G7 z752Xy`9Q*5E8ng=ukKYrDSs#WZ*G+SclTRq`Y-Z-Z0O@ix8caF;Yh6E$g3e94YH5U zvX9QQkD~0OKeCVBWgiW*k4D)?arV)*@*RD_^e=P2-2eVx-2XqA{r@~F_W!@h{;zUB zZFc|no0HmBlzw5xa`m}ooZ7iYx-MwbY|KH!`44|O@O?{04;e{)Jn?zwROaPb~1!~Qi?0A*Q7R_pa1gjDaz0S*) zvo))XnmK8lR#~gc8Wj!;fkiXsO{U}ioWI49M1v^oGwcDM)e)PWhoCYQ06d9X#=;9e zoikqch#el*Ui|0R7vH^k@qPU)nRm;N|L@ym=W&&JUd1u~dhdKZng}qAp_-QM_^6^4 zpW5yI8UYPzFpQ#>;In`bwof8?*4wvK(RsYlLzCS~z3nVUU1Yc{aVQ ze9j1D?Cm05`I=a+B70a9*TQpjqw6zmMqoT=KC>P@Vr!rsO$nqSfvf(F*0R9Vdiafj z>)afSz#y>MUo5 zk|I60=wleSkF$d*XLz_}CE?5%eRfAal^fAQwrYU5MZzY|Ny$S@-nkA(OrvuBZG~{D z|H8lU|IbYRM<@T}&Q1V}<$u4ix1Txx`_01t_uOCdfvX{8H1Q&?n-f-Tx zr2f|&@{b6(-Tpb4_0Bo-vQ7vdE>E`QD^8M}2h*_M2`_@tWXKtgcOJxj_>x5M0ND<< z$UY^0l_kw88;qwPf+=TS{M9ExyWNmK4Ndm+3|@B_3Jd+ zQ^aMRdYj*p*sdS87YU;=o%lod%cJK-*UzP6GCy zQ~c6p|6%mwUeRauMD_2E(5R4^;YE7~3Y|b1$@zHBh3`QS4H?Q(fg+G_Ivr09+;1_y z;lzDT^X-0=1YJJ1*R#uE`1r>lIe&c_&w>j}vSS}r2ZP>h9t=5S`q=JqLOdH!FWJ#C zpWex&J`H;B>cE%7WaeGD> zrvBtfMpy8B8blz80uIW*0jF=bUtqZaZkH14*Q@dD=WzA{%2u+-3gdiSEuO3WJ%#>$ zIKY)ehG?j4!EdB(!LPDuI2Lz?VSF|_N9G((xlGEj!y2N%gv;3xM^Oj%KK?w8hT;v` zPx416r;>f9wi0K<^)TS96gDk9d3;jn77gU7i_(CE!U&Z`?om_}=-g4F2<(2VDvyH8 zZioS)qO-ZgM8YdusHtMaY+huMC1v=+?zALA&_o^ zhCFq_l2XI+vR5~-tz>U+jHf;GX$Df?StoQp9V~=&=B#t>d>So;^oO&~JLl8kLP#TL z9peVbQ~Y0iQM%jJ(cW`D?Jw-u3J7*1HUnt|1iKNNfwTgG-H6RVik)?Y;f?WRBA;X+ z{Fx~$EO9au=Ga?*3NASrKK_xjuKu|9GVX^l?KZahB(*8n8h9n7g398T?_d7#Lq*sp z?`ivF$3<$*ag)j%SE#=-Su4F`+dom+@(Tj+20>e zHk+B*o!{rft*1-!3lhgaqH;adK7SHs;%5B*Ueb5VVJ>n4;<@Dm$zdlt zLh%BpnW4ZF=ZMUllPMh8e$GV4Zo!*Vo6`_|RUCBLdO4)BI=61dRpQD=F)~Q8O3Hk# z3SfffM=O*mSZlJ7GO;05VaU*t`dx3VHjFc--=s&oRMn_zgi%y`EK;}p*vmH?V3LWZ zC)7(cM!<{Nu&}*8Bv$B^eSxOOOTc?GhyYIraHcZe8v^3Hwg8~xK1Tg`fXm`6OAHHLbu!M-+VG)X0)zL^M-o+kd^HsQ z62EGE8njMUaVP7W1rS@KGVXTvMF4qG!z!Er;42Kcw243(r_MJ$V}sXp4=jmKiW>W8 z?Gu+8^sEdh=p4eC)j%A9<;zRLn71pyzE)KALofBJakd+BUX(Vay8#oDo&h5f@`}m7jE#C`f;4EUD*kPK-u=O0K58a8-(80G~{mgRmB2@r;340rfqHm8L?&{FL z8hg+qR#5Y5eVrD;7O!1X(ojVt*Zygy!0W1jeBZ6>*G+BM_F-vOF3urWpEt}DixyQ`Ktkw6M(I9JsGMj=gwjl?}Swm_!Fgd=-{68`8 zUVw6hTtIqQ_BiMbX$$e=*mF=9^bvLlR6JODi0i{2VU1nj`2y^OCqp$DYk3M7RXHCR zG7PXS_duj+!%2KNHYFW(@std-*VOSL!mw~deA8fkZ0+Wu4C!Ul%TTWFABL1R8<}mA z>VB%5YDV`~>3^?fgKvdhmST zs9< zZk~%D7FZvBw4Sl6Nbr$jA7vG{xX3WPbRt01rUA58 zUP@u`Vc^J`*r(&=9JA%Niy-9J90#Zbc&93I0u(ZT$!ZWLzND-@pK{5#6qZm9p@eP& z{VyE5SDB~s57E1+WS*VV5`ViGA;h~5{f-H{o4^Z-#wg) zWwWn7=bH#UxoJ&VZC@!77-~BPEwz=l9Yc;c#Rbh*ZWa%6E~ai49~S*FL|&3_5Aizv zAH)Zhwxnw6j_p{x8eTww0R3*Lb_Nu>m-=GQb1>+aIkUEE51;Ukzqbrtuv~`b*LlHe zx4Jh+eTN&YFY8^&h?v&`#Xwiq2juQ7E4!-2Av1!Q!4s{Z1c*R-@P&su&4UNW$CUt52S1)N3SmwgU)fEjCHccenzPcWRx*6}&fZzYhhD zS>v)5Q)im9=CQ$56o{^UM9Vjzv->e;pP5r!oZZd3sPjBAA{3hyy0W>VmEAx0!Dwm$ z5h~>O2?;Mtr@<>mN@vR0A{&7!LQK~f2_qv(@OLw-obVf3vZ>fXz+g;Be-dl=a9OOG zNY0JakVS?UW#1GKnY6!^oJQ-rS*3RJZI=_RdA%{yb&Ae@WLL5}Sd)93I9He;GE(;t z#boBBfEUW*p1^G0Vk4!!rXB#q?_!L2nBCk>aTwo(>q3Aeh>sZWJ#+;Ioxkm}>0hHV ziRLq%YtL*WKJoCKsE+kC?5W^7P2bSxepKdIjdE=EBDT<&POj>kK2TMVl~*PcP=G4S zEPMedfR0rMGwPRA*>$m#Yip`$+Vgh}ySe}?)lbrDy!_6)d*}j&qu#n;vg&$=w}O$$ z#_oCo1#`TV7JPGP`_+M*_h9Ms@btig1l9qrIM7BOd+h)b0Mk>rONT$Y)CRn>M-ZN z!Xt9+&5?IJt!xuv?)Rn-EWBaoaubX?P^Co#|k7w0fbQaOB7FO7Fm(>JR1uQ}( z%QH{`8{Baz=lS1}^%NMsXJ6>8&5_eDC$aj2?weyn6}uvTp|n3r5GK}F>W-OoEB&*t z)stcj02BJT?2mgodC%uUjGoG>AWb5*f~MDK#uGJLb{364(;R zA$;Yy-PisFqkPr1FF%0q>{7&JqG?pVQt4GGY9M= zWNkPO3^~Q~ORJv+8K@?`I=T^?ycLAA8P5IE-8N#-D)+Pvos4hqia;BxVZBFKS6M1pBfJD zK&FX`D_bs@POM*R2y`EWqIJ2C*g0Lj_KPz-{}d&D!Ru|paAE6Njnk&&TH(ixBo)7lSJm+6hPV1^7C`Y|Fd zQ^;60wYHiO5)vLAiI{*|Nk8AoZ7oIyUia||RB^k*35~?)5Y(?{3r$q<2zNwAF7Uua zYKJ){jtaYPkV~3y$O-rAT`7;8$`F*|o?_z#(P{X?YokF7(bRgWG-r?vg()cM2sT%# zscQ657VXZ}eBEmB{Kg0tw<`tSRB0>vzp9&+0x?zd6;Iiti%F!Y;z9X~hSFWX1riTK zK|^{BHCCg8a&2;z@V8qBCGI1s9FsBY4a06F^2coKZ>FZk*zzp6H4Yh+R3^xC^=ZE- zOR)cO#Xd=oCC&5epR$_7ttt*n4Um@Zfj65tVfl6H0DpYC@OG*g+QGh{b`{Bd!c;}| zdW??U;%U{II-`#Lsb4JZwJ&9){?UTlkxOru$BmG1VI)II-;Cq6Yr}QR&y}{L!JgIk zHlgtaes&Aq;5V|HD?UiDgf}HY*Y%&G`$ysK4p={@U;j%`tA~gvgLiff(L~g^;V4qZ z5V5hXAnlU=DAFz8Yto*dhyOgHN3~JR{9{2aJl2Z^chdUe$KF4;l+!5hee!Un*ycn_oPdDBeg};Cx zO`va+&{JLv43uZ+`$_0~?SopUM9+r_y3{OFmyh}LbWOojRTBZvH;)a_#rqsWNSput z5Q~Rz&vx(we=8m6a$^RX>ACvcwJHjoL&a?T)@~lQhLg+he=3+W8+sQ3@rjOYCxtjR zfI7-OxErhXh!@@PJ6>c5WnYG-EvxL9%{`9v$00_t8}-h6eb}YyDxHke336cZZ7h7E z{yK&O%*odK&pZHBSzL*r-`!L;SHfKJE%yN%BM@v}thR5uZ=|y4F}){G-n((Cp5oi7MaLY_#lr+Xxxzua4*rO{BrOM$n zYUAfj(lsiKY)S|~-*vS7JN+H}X+DDj1e>)XUOBiRdascF@JBzuCQlakY9q~baQBEF z`ebqG%wek%z9Q25L1S5wr-KC+CF#s=nlBDoaVN^hU?*e7p>HO1X1hn21};4&eDW#& zgdg7pu$9d=m6_dHswaOtNQMm#mi(=rT%{vsr&&98*y@_R!&+a7^S!jf43hz*oUrip z{55h2q6QPy8fhW^p5(EFINqvPPZGDZRV758Ee-6gYh<}G&nSIm6O#w#l^>`rChLMT z$0CcHyk5UI3h|IYzj6ri$Ubwa&d+kZyDUi&bY8!duW!ZNR3RH%|HXfKl&?672Ts~? zu{$jfJO0x=PqAh6=o|7-X0jMKla;Ac%+^tAOJHMbvdD#BRo$k9ZBk61MAD;HY@SHv zuke_rD$l3hJU0BS%u;ZV$IK@G?#ljKNI=TE0`Nh$9`msj(*$Pnd8AgP{ zIFR9rZCPHh<>;9uEJ>u;$?x~NtCVJhyXSyEpAWD=jGpqRrHNT z6@)scxMUo;hb7GyIvMynwniBRYgwozw9*6kyC9(?jj2Wb9Fk$L>tKWj2|)NOwOE_#F(ez>UniEcYdQ> zZ=~xkK@6iOLOHB0y$IPGW@q4POY`ih&f_W&jIiG1g5^E>?ZGu}-yxWV8_e1_gB>9~ zNJ!|91))ZyiObeh+UnG+#MKC4g%p4I-!au3VG0Xw#7&+CV*L+o)dCM4asyr`)l*4?_k`$-8s zQovnbQ)I1j@s;)n+?jUlktK#0j6sulPExaK6nd!Gp zy2m`Y7lj=ub8S8TefLzn~GBU zn1^;}Qh$7EU&&%oEI-c1(5 zA!WC%c$?5^FI1IgVpX?{(D!hPe^pjrwmUfa z1b_UaX?&_8`10LJ0~PVF){Qp;XASM+P#J=aa#lH^iSmTZ*xgK}vlH8tqodi zhmK`ZJI)b0y@rLXDm+5Td2Uglkg;JXM{SrxCm~k1EWBMLpJ+k%8N3gJD5CvSPGU;- z(QlkFiGrAQG+gOh5_J9>!Edv*Q%?f+jm;)>0K`89v|wdYU@bIg~#}@y{(>3 zR4Nz;rI|Z9I2E4a4L!D4lF5Z24UXhP4BI zJ8Y_WK=+637NhV62c;xNu$=32B$^A4!C9QtOmBLz_Z5Ba0a%~pxA&M><3vdBBvSVz zzw`oaI2UOo+so=MSQ_`MAd%aeiV+8*S8V&*^-W5LCgJB#D>jcqeFVvE)b(VF$7kGn zHi1$GYf@iOtULEfet9us-=yVka1d zvdam`49<(<+9dr^_}izH@QOr_ zIAaP;$v*ZAq{le(jskTxvRojcU%i2D<*jS_R{sd<~5xlraLBa>3> z%q7kD))bQF4n%v;ATqZt{QLg556gt?!+k$FD}2%#r9=(QS^tdd-}Jk+8wjO`%w+IW zVs2M7&IU9`djIm3SeCw%LoXKJ@e9qQHQM_PzH{-wK)^II9Fyt1B2O&{0;Ocru){38 z*Rx)a;|Sy-LYGZg*jCVNF8fT4S3VO_vGMAG1*J(3kyNfi9Q>?lZ$lT#$PT)NXM-JJ zsJrS}C?%)}IMQ8%X7ya}7y?`1_0@EJNpMUq;c-K3NieNa+MEBKP}rjC47JEf$L1z0fF_Xr)4vS?Q!8^*TUU2`S9ULBdpmYZ?|;Ke zfLG$-;eq)}zS4h{uQomyPF?^ffQy%p|1Ucy4F(-g?DFao(8}E0 z?!Q_8_2GZB|6_0e+T6cJ{-4$;BavV_^r@}hz?pv&RD%Ox!Mj4bC;{}x1xegoE(TR8 zVRDSJt=YWPJ?c}uq79437cVy`thYng4?38NKJ!EUx6cu7Z>&_7`kUfIxt+**rt`Xb zcwv%8^D^nnwum*j7WQytF8y^dA0M{kSeNKA;P>g$;!P2ng0@hy8TulsF23LokO&A6 z9(KktVC4vVbwRQuQJBOm1xi_>nYkhaQ(Vpv^!gejV!8N1r`g7>zj*K`5cP0ENp*hB z@41YaHh<7{-%U;>sbV`odeG@W3PfwF8=?n^YRQp=DH8?_zqdCV)UkIk*F+#C@rojm zG9A%$MHM6Lx3JO=+OxG-L_irZQHhO+qP}nw&xw3v2ELDY}>|}{dPCm-TXIuwMw>bsydbKRCPN2 zR6nV_9|J|5pX{e_Yqy)y>%DzmPnw%+2lokB=R5NK>oCU+%kWgbpElS)`# zafanf_F!4;l-lboWRu^ZJb!YqcuZ94IPta0nBKyG=}ZZCS~?etg~)&##YyoMk_DWE z%_;KJ8rxB}aLp<-i!ad}Xh7h0g{Gk#=-V$aq^9Xhv9)DfzaBnrHFvX?Sq8!ZcgD+MDo9;+kebJV_5!Ncd{2 zA_Ch5rZ3gdi?a@5enqm<5A_DGJpnKe(O<4tljdo&qCtaCm9H)Wz9}+OX~tzCGxZ#* zlh(_$`*oo}I_KE>YRGI)0DxsECvPb5Hcm!R+8Sq92iL}_oC;sY)CzGWhNX&OeX+&V z0!q3K!el$d~Zbh@&piI zK9e$#99yhe+Iwvf`DHD|`Nk?q83fRTwmxU>I+0uXgxJ3|Kai zs-&~l*`2MV?>{JAQ*at$bj*@62kjVDNm_gx^imN2WsKLGeX)DH-vV zo#^BTO}9xJf6=d|ctZ6t-raiodSvSv`gwnyd=)BkpPKLL=OGFF=c&vm9#d$iFm7ur zjS69Lky&gw$PNy%KPRIYnjYXkfWz?so+C2YwxguiLSIxk)~qw_k~ET*UQQEzN_>p3 z2*7iy!ARJ}5IEdiQ;Uk^PX>a0%y||i@Yd*mCGzypY#;rZSE62=7r`?BCIAd{*IqO&$a)&IqYDf?DIHXT#2Oq!l^nGn;D97n@isL%1&~d zEungdJ|wGpL>LU3p5Zb_wUn3SC|TQ*e{#>pt|qEl@@7b?0Aw_;Han731wdzQV}azHY>+>S;EN~dMc`g`nCPdEQeH(O?r^(qp>Rf zI?GJqnveBS&$d<16gI8hQNp*w zN=`ik7zl3;gf8W~s+m#)JhzI$yGZeNxbs0@UEN%^{Zt!1=n{i$Gwa69=_O$o?GtBT z6#cRAo<8g}?S|32*CXk?*HQ-yiFGTs>(AAOzKY3lqIwBuq`8B3O zN20>RmMpR#u1x0D_J-PAz%~4XlllU$vvONC8?_}yPosQd!PwDtPFvylPt0n{l4xm- zC;QhqsLwNcyt~G!IwB#4Io?aC9TMI$!SS-wX_-8odHY%{CAqyB8X@u}xb_>U1_8RT z;2;4MW+)3yT?XtYWq+J`a^`~<-buDXUpXam;E0x63ox+d3b=Nt!Ec4Z)^n1>LdWzFg?J-_9b;)qA6yvGLd! zW7ePBgRAF^@q=tdA>28=a8Z?uGvdU<7(ga`<|(LYEG4cAK04thasXj#PKE)KV2Mpe z39%9>VMFXaU0P`TTL_U{kY7?)k_!OHp#rzfzRb;#E~@i=P5AsIGYD^3-4aKnO`5Td zGMoEukYOS7P+XATMParRIL!2g!}sPqm$FchU0Cq@#3Q^>OxK%fe(q8nOnafEOM3>G z?AtkJojfQo6;)GJphEEY7~@r#Gk?94iieux9k3K(HN#76$R|l0VHLGp1qZ)TAVncG ztV7diKkPnCKP?Ya*3Tgt3czCK--tqT`H>JdF|>J3zXLUs65VnU%R!DghUeEh%?b{@ zWaI9R?BF3;PhIRky(^*{n<D3{bHF^+?W^XEA6fh1FJ32@=U+)8&ZL~cdg zIy%%|U>}Q+u4YRBN%O-nlaXLxYAWj??<|3?gT(bn#eh)uZ_j4{2SunexxS<6PnK@2 zA9Fj1Wrd9UmQ>A*iTPV#ZJvg*OYGq4*v%lep8NsUXQzU!o5Hm?JxLH%81y!H3i$b; zD-$kF{G94q`k3Ye`53Pl_5$;HQ6?Z9-+5PELG^iUP~AgDa7_P2H9&dQ+))qB1rPLd z#y$2lQtJBximYC-#8OaeswMO3!n3W?Gn`C z1d(9}&e2Tu5Kw$29$j1v z=eGeHgg&5I#tGtNE@O`iFYY03Q+qC62CkSnlAW;X08Qbv%8PtD;`3`U%9E!R2@YWr ziEn}`QE?W%X6YW}M>$9OQQ}Dk%-A+QI|ZcNKxUa`U{T$+y=iROQ!bm4WE=f}bAdL- zSTY(Six`f=N(3~-Cok9NdQa~$P2Zuw_YUd!ih)5zoTD8kiivwg(2Yl&XS(9R_ysNw z5t_VPBkPNc(ezNSe!Ptj3iE)qnip7FjC!NHN63WHLedG1c&SsA4#~OORBRsp;bTFx zlZqlD2gTbVs**U__NT)-Z7b#YE@*K4S8FdY<{{XPE9AMusYsTqN3I6uYad4x#aIm8uJ9`~x8aX2I}!qpBh31%e8ETiays(bx*gK=ch#ElrV18w77_yog<|7MX6eT! z*I~Duy&#hM^N$oJTn9Q3d?vz$xTvrLz_^l74)Sz{TZRY#j#e5%n9L}BffU<}(xe4; z&O08w0>#Z9jU2YleOwNH1fdz4R#Qtzqyf#x)}SAMyH-V*L`w~QXk&HwW}jk8wX47+ z!1yYWV5RakL_9xa8s%d`I&fbRGk$36%DnWpMLsNlBvx6jo?uFMFpElIXq?TtY9+*& z;GT&vrf~>T8Hr@`4q7uh3F8j4huF*=gY6iAfdWB_@tpc^l&xBdim2u1)!At$c&HwQ zHf_VI;ItWt#X^qZRQmgq!}Y78zE2RYz}y>S*Q4kQOi3(=7M&U@0%dp$JF*lR?DdZl zak)uZvf5PmjJbcTWk5z*VTm$E9*zz^P96h=(u8yZexkQv7#wtE=EUbnq&azp6Yt^g?s=kubyJ#p=ZYfD5~=Npgn?+~Wz zUZ`CanbZg$8hcEzY+crBTJ^&?RDy=)by(t1V*5}M@X=e1WsKXNqv6=mVehtixmn@6 z^7U);KW+!;VGJRG^;ilp0`D{nUf%8m7?YWTADdx9_nS6%mUrfgMCn^%llmMG(sinf zQ$X?Do?HbfkD-UUp(QQ|!Q$>e+zC{C&|=2A4Q za?Gg18pwSbH%$o@tuRtte0Adrf8W>qt$Bl4GlAl#7YPzZF~ct!Xa)+pE0!Zkp43YC zYIg+JaO4V>MB7j)ia!l_OX$+hmi&$i8v}2Y&e@Qbn%az=O=K`)QC8rC7zu?*acMos z)6rq;h37USHj`jWIO$fHq+Qp1dT#q?Ok@v+bfAl5TyAYoGYr*FNz#La)hsXpm5*`n z(kL|R>eLU$IoP_fk;u^T+!!>NP;#b?J%x(G3*skPf)jJ1%z0wV1}pTW-L{hRVSeh= z?=4e5a0uF&qbr^0f}17MRuiFlNQd65iIT7wa*{~X_dQZ2e4;!D)U|q;JidFjS1gx^ z>NyM8V3G44ik|ZYggknNU*0iR*Bc5D;0IWv$ks*pi!^!+;R6pBPvCSg^pWi(VyYFR$#eg02W@HakBb1?TAus31#KJUZtfYUfm3ss z*NvL#_J_;_FG_>;gqXd2$OBdD0a8vgTk|qbI66333sfq$QMwD8Z40ni0@jd&h`&$2 zanaO|xU6q2gG3%^<72_B1xRf;L}UVbWSP{zQ=0b#zr9MNz>_Gk7h;y8e-t^ps+O!F zlz&;k(`bDI1$&5(agBo5))OCbO9oI${u*r&S99NIrjdda;W`>#Av!91%~LGK7uOw{ z5T_lmcarnxQATzvrEbtkdJ?Z9dcMgk(^dh38Uw`1>UoN0lOGUN>z~Zzj=QnsX_vT{ zs^!?*DQ!&A|Lk_2MQGP#$U;?$@yDz$QY%iIN~b?0z2k~;8)ErIX&RKRgFWek!1CO_ zHSMoKR#--kGwwwen7u!w+R*aFRIEf|WbqOVIkemytOaRne)Ro}0fkD*yrgzXqBwGv zvMQ;{V&P=~*b-AqOnjus0E$2gkTjgeWHNtiM$|_HA`k|3(qezYAj(Ad0`}=Uj_5m@ zy>mb3s$U%T{kv;n{eH!(E8Jsv>k3D~+2Dq@J2+yDpB>C?|4s1-&Xan(%DJ5cS$3e{ z6XC;x5(d^2U~wMl+|aEO>@cjs5`y~^Cv#&jl>aEN26&|L+b)^dV56?08q4@%*QME$ zXvk=EPxN#wZ6Jj>BXB}`nG0`bq>#CO!We)xCP1u3B46Fbh9w+MR^p&`(oO49LBwi~ zo%kb~wOo#qs3aE&OfeXLl^(SxHcV|=&VWJT6T~80jLr5TE8IUokpA7BtPTqIkt*UT zJKB3wo9t%t`378~lrJ+&@V}q#!{%qAjix;MMLKdbZ5+j0oJ3b5UAkRJvOti9RWBz}>bLHVV6G{oTYxxd#(WB4G_{A#ES6 zs%vzK-pJuz-xk0QDv;!k3!P7S`2Fs;{=Ses+0cGNh(NUO8tdxIYf$T`V;fZi{|VkuZ51orABV(N=~@@4NL?ok(b9Eo*0fRdEXbckQw z_xCN3-z4qG3u!j#C_MInr}w*08>s{@L~-kAjoA(vo&hR*g-zCyIx&1H`~DmKAu!Xu z%aie5jMpK4OmoLTJ*orS&KL97+LOa!FpzbDOIBJVLW6$6(DV=MLSrZWlAC8*GLfPf zq68m`y^4;3N>gX>x`Q%TX-52?Nz6p!KjSxsAY{@JRo1 zmsqg#wCMIA|LTIFn7K40GY+iz*1S(#np=S=N@b1k9f6TtCkRJ;QgFffRx=6%;fS%a z8go8SIaj=ZxR`UfQ9C&Kz&%bhM+9A&{Vm0n~i&8P_6(=yNl>q$-G^Y9*O)vblJyV?& zMMwm4h*Nk-2Q*)TjplNxQ|AypgSi?9iPD>55ZWB%tyHWx%EEJtg#%1#>73`=cRw+N zq|T233vtRIYbj^&p&4(DkcrPol8(1wmopBSXeUcvmP`W;mR{#jN<9`IpIn5n=VNs2 zIfWroZHRPJKUOT^6aGkqD9kWN%z$Z#dZ$EBTzG5p4goz)n2y^Nx!)#8o`OScRF7M{Y;)@Cdgu<$!?7MQ>2+ ze0`rh+uUJ=(PP#fSOZ!%Txu0S;%$&N)kD~rxsh$1^}P~}4kwLpaaw{`59k>hcUlU^ zImv1gqWIDhh+wDs$XNU!?soYxKKN}KYGcG;8VlUYr(rmfb@@t|62Zw_BM7xpG^VQy zQi~ti*V-4%7E|b9SzTqbh@uy`cLTN4tB9#HDYP(aL=VqD@q&q+0~deovKl~5@1@nWEN2K!?oMLaw| zU@it!A)T%WqSvkJ_d?{73=aEH^$6F!bXGNb7J2?z>Bh!`Ty|28$WNmQz+`x4Yz!4N zjm}sBKkB(*lmF>2cHcnKtt+%FWtpdtaMl<$kQZ!oIHk1wg0*U~io&XiFWfuzF% zt+)XJs(y}HJ-?0)56rUt_sZ$G3?KJiY_K)tqj#VzbA(%7poqP$D`tXfvE>R3Oz(Ai zfhILUYm#-9g%wyB*Vw{_9xMwV;5E_gV*E$g31j$9-E4-=wxMG(DNv*#LoQ^8?7lZ`&y2hp z3ANTRAas`GlOG%O#}cV~tYD3RUhMkG_!^)&Prn?C>oPKP95j?6jq`R|YM)$>!Hz}#A z*r>SVkhROAqz=)dZW`z)d8?~Y?C??2 z>H?(3IGt0LbI8y~-b5#cdx#r8faBzde;_qs)oDoVz^jDE57CNg2tSr}=Ia~d`A-E6 zQ@kG4Kw#s%)KoF+FPgZcoX{#V!I;_oNH4>JiuRp~#x@MJ#fy*-h=sS9cBu}m%tREK z8#X9~N{`eU;{ef{TWgDzCc4!6`kB@!{+eOmL|Tz%y;zZ9m8~QXZ>b?rA8F>Y1bL(f z-9$GdggKNr!aPIljlDL}>EJ_v07g>eT5>)JflCLl{P|caG?r3UqkAw;ptdnLUvjoc z*qK0@EXU}e#~ZJ43Cb-%wMaPkwKyGo&*(Bt2v&yawmk4-j|J5p*&!Pr@wurt^C@aJ zJ0MV#HUBEokr8Ofk>W?ie|wg^m!f^1 zn&YQquxb-NWD7_yDumNpvA7PMmqKDz0DkB)N@{jG?D?&RlT4e;N=87;zn%8^{>m(* zGH8GFCh>aQ8m0`%nroJEK&9u&e`UIBa0A{{cwq*+fexyc=?T{;xk5}iv_gF$Pm|?g z1-qDA|7zL`47n7VMZ5>xTLJFS>o{tp^lUL}l?^^;5ig}&K%nkFf}La9z%lGoyJ=MT zJFMtgUses20(_>#RU?yKC-Jzy^)3S^{>XM<4=Gs-oUGecpxYV`SqYDUG?JlQ_}ncF zCmpyM^g)ju=n_R#xLqJxWs^Xb78_CK9#NWRy&fwm(k|UBMwXTu2vfdf{1lm z*#?Z-49#CgMdT74Q)vB}WLDEmylnEfq?MB`skacxR%xR3D^83ETawTyRP94;M$y=5 zY|`_H`u@+}{)dC!07;&!MV2I3sw0$Jkcbq%{8$h5+ySmjOJmlu3IHKHbHxQ=1f(tD zvsQw!9^#~BRO~v!%2IjF9z@InBaE*B0tA;LxRPRQM+CAr&|?M3L`8_ z+G*i)AM}gtXP7UXDNQA*NnKWdvSd63;TXL11k}u*U^(Vu{)OVYL9+fOm_7{aS6gmD zR(?YpQ4VOANHqgNxaxq*YvDK_F}y0|zA<1TpglaPTozh33OB6af|a zNMvO-%dv}`P8^HC{8kKFxemKvbDT34)5%f+SYlTAk<-?wu}*ceC3*#fNT#xBBP;UPX|#{oaoA23YSs4SV^hgi(=WQxDE4|<=QQ}_7SG06|Ue66#DMpk6^VsGklkfRs80SnU3OM6GA_K1; zUZ}@n+;Id$zQk}7D3GP+F1PF{;RB`4#8~;n=+3LA&DEfQlfZ~oWe0QcvKHRbX7VIp@38j<5=YU+ zF;qe6xj9G?k`M+75DLF9;J?pnaq> zkRet509$g&Bz5XMH6HEOm70;MK=)G|$M4}hp&!URzNdsOZ+FQe2^*JJxIeU%k>)_z zqUAhElB_h`8#({bX$?Jufx%-Am=A3jWv`z;qHqc8znd}Ejd5uWd#=1Kx!LFq&YFSP zIx<6Kx0DoVj|63TZ24`qG2TDiuGxT~dtgp9=D8cAR9a8s`+7LACBKen;5Y{(Ia(tn z5GOMso_3Fnzrc$x8%^TgIV-~q9^i>8%O`c=Ut|6__(D6WRias;*J$)(@FuR(| zmi#2xKk)rNh)q+_DMo1X=yQlC=b+%zx%@OuvguhI(kU|3R+6XRfq1Buz((1jw}&Tr zb|{fyLsU%lqq~5$9mfB~hSgn^qSCl|7j>jV{iU=CjcS)Te-%hbxPbXeRcmb$X{XYAF6x~0sadOeae;`OKXew!^G}n8$7x;OBBK|&QewhQ zNA#M_k%b$V(mCCz?6r)ak+b2R$_UMq$AGTx6d$z=M@|A~Y3vlT(+LBeOG-p*2 zHQ1MhR`hBtoaheknMO_og(SEM=@u)VVmRuRbbp~FQa%g4BXiP>mJ35YD{^w#D8X@f zHBP;?0Qwdj(npw#4`J&;02DgcFA0(gR!mDv!-s(BxeJereYCp@CQ6xXAdKxk`iNEE zITpZ>$f5va!T#XM0Ydb(2_eQpyk<$h+=L89gu6^lKrK=bGM_D_MPqPY9_;N!L=Hhv z%!xO#Ki*Kg-SV=Y*{!S~=|iIZ zlE+Djy^$9UAL@#+V2}2#E0fEEJz(QMsk|sCR#;U{#>H5L2wlR#kNc4t)?j?-@5EFE z@w~tuD|UhEQEx5aHp5(SvStRc9ehhF!$nh=JSoRc2s|Er)GFmyF1F8d6+Nz zFjw}@c>Z7gMf%V81Nknl##2JW)C^p4PlGgV{;Xa8)IzzPtlH+`mu&IpSZBT7IBpYzW@d$Sf+ynU~l4d zqp+$qTMt_U4mL7czOeF6wD!#dGeQdeuvK zZ|X|E^razP%a1}>2P!cia)>$P1l$$WSV1b8(k)|SdF56(NIzfp8k@S3?q;nwJ%Q}& zpiR1VopM$BXUE28NCpd!67%GKOT};prFqJ(fmm6eF>YLhPT_Be{(fTTG;d@J(d*bf zVg2|e&LwINiB$#`(SBZTj_n_Ak{yvIUh~EL}gKUyA^4AEenwj)ydh7 z27X-AVGI_v1`EwvFeRj(YX9hq91RqLu@{Bca(kO6-#GLhsL;~$h)@Pik$Ms#4Gz?*7H-tNs zFyJ!$dh$X#QTA z3>CqeD6z73mLA&X+scznMQ(C0toGm+L{ldZs&J$G55mtzjgt<$B#?P(1+c6bL(pVc z{?FLg^aEh`n&i7-p5s?ipZP3adBnDw(&ElR!N}b69*Pqph09E~cv*4(p67ZtGBk|i zgA1YQM@>_M2O-H;U#h?KQ}m}@A(VlX&IkRitLIQ603)&YH4=8bLej(IJJKf9hIdRo z-Z0}k@q`BuOQPqr3l%5RCJzGqe%Im|1ew;48tc$eS-gz(u%uygD)On#BgOEOns-KO zY+62v8JtA;?igx~AKySvO4ddAEKT>6$KEz`x|yF?SU$ZP#0dODk+SD_?Ev!5?bVOo zpuVUD!G#7Mp1Ff-oM-SK`I;}OPyJaW3q&L3&w))|rnWcN%>q2A?vnppZFP+P`_h`6 zLf<#^nRCNQi_*$?BO?BsbVqWtXs!CjC-dv$Gxcpk>(6*$GWK>8>F`nuQvqNVPHx|L6E&?(_k+j!pUcduP);4wV>zHyCG?OH5UT!bq&`) zrfm@BSyn8XuR(H_pQJVuGVp#U!Owz5`c~tz(VPY#)E5rZo)v%|3C+G#@wIB2(iN6?N@ldR6We9=XQJ%aaiU)zC`*O@F>j+J61h>0)p$tYI(CY zC!r#XnDIxAI}br#fROPI@`|pbaV_0^|6)jVY4)*z87LdM#3lxfM=*ns3V;WBQt`P=4qQ2p9Jd&ru6OFgQlpEkQUV#x zrF?7A??*D+~G2l{FaKYz)`SHSM9baJ{C&!k#K?0i+8 z?rv8LUYLZwg!QBJQiMcP60W|KA|}W%ybq=P4K{tR^4i=oUqYq@u+VJ?;^fG~;H9XI z>=6rUGdhSrm!DJN0L%1O?S7nE_75Leez#n;OE?uIf?W!_IifK<=g=1J5-bvak(@OV zwJ$q`lo4#d4#W0GTxTN*uEgrvDnV^sZGD|%{qBf8R@o-YAn*FF;I1u1(-N|R zvSM5jF%jX^g5ybM`p@&@25xGYg?#@{SJ~RwU+}_>vH7N0`Mr=y{`d`vAgg1lc!s0c zX|L-kf9(n=ITMl^7Xw^7Dz61bjst9qs3I{{hc|nATN7o}D$2M}q&N#s7y)=Mh0K;_ zQ4q+Vx0WRcr(Ffbkv>V?o35(*$P1#x8rUhJ;hO2*JP?7cR{LSjDIhPaQ;B&r6 zbKKB}g#RcC1MU2-`T z_$hdGMWN&Rs20Mj^oUG^Xy~=1nDl~!7+_8XD3HlrgIQKrw=7?8+9vu7DoM-O7@|CERY^0l&l^p=;ncON6vNEaTeai5-ZCN zjaQh9^;X;;jW>2uFj}xGu=o`Z@n*Y2kTX(y?WQ!BvgbWyzApb6N*bYrSn;UsAMxCZ zhLOLSlVNT#H$?n6dMpUpxU9z>Jl~!H@harYFbv7dsL7caEXCHE+;@B?a#6fUfeuA% z8dMzz#Fw}l8C6$R7ZL$j#}Za5z;l$G|HZWDPT{YsnhZqL96&z|6D?O11=9kzkyI@; zMQ$P=?-C)PzX5)^^~QdI?|M9WY;%gPZKrCrqCtz%zAM+A<@*Wc#mBS_-MtnJmu99) zI(~8f{iQ6;rhT428vjevcpmN`-J+=1$=z6ys#BmIKkVsw=h*KD4)& z$b;`dVk3dxX_W0>)6A{`+G{mqPR0p}0Uhixx(ZIsSB^WZ1rXUe*^zVl7>%bWOm;%| zh7~#mluiWn_(dZO)v;9qm2QfjpjQOAbvmpNq5fJ*CxA*q))dvw284DokL)DDR%kuK znXDwCvb19WvraOLC5Dryt;b}ky2H^mF||r~_*&9`2#!3R(HY)ceSPrN0I8|D=7of`m6|mCVm}8KbouqT+hF9tI3-KQG+<(XIWq`|L%NBY zGWmPc%*?53M-c|8;B^Gh!hnI7|J}$E31ONUFR91D`8W7W0$XiR@o~)mVZQ6Rmf7gv zu`McV2tn-oDb3j&@gJ!QNJhh937f3trZoBICW}rnVyKY^?R!XWdtn{qq;)`SaMV?7 z5td)&5^ZRw+%i5mQe2iW2^RFF6`5?T+&Rb^jyio}tha2z50u?-el@5Le+wf&O+p`w zx6I(+IFyAUN|l038a@E^Uc9R{W3|yD5=bSgb)|mlEnq@sIN7fC(3NOxdIu9S(eRF- zmq!T{NK+(D;vCP7%*70aS$O~)`4V0_BmnrC)cL5&XdwCUnr?nb#~++M?38-l&VO1& zhijR5GXr*tu5~N#Py3qzwpfuM>Z;p^Q#_x;j_9mu{>hx$?F6zx`Zy#TjWs zf*m&hV?D0TI0#6sS-{dwoTkqbwj*VbQI-{tkp;aN$o4>H49Smz9#g`21*BaZF$!fG|G_0Q7zQY0u(F)qE znB%??TyjF2*-ZX6mVZoLw5`01^S)p}cl(hrb+$;=i7|Xga$-+WBIO{_8dccs zm+|9dWiH$-$$HsY0Z7(Z5uM0csZPPD%K#M8BH#T0Aa<@Xh$euNXLQIjY>X@aUdBL* zR0KH-vbX&kKE$PRx5-o#;c>@OGh7J4@>rO79N=ETJUX!~R|xycVn;)XXz_JNrF8Mz zF9;t}m^M{WUikNxj!9@IIV`#`=XmXZwsFiw zZ4<|K*BQB~QCfT}Fdpweus@)VPj`AtTH|d(B1x3!|2p|3k4w--Ev86eQWePb3T{PZ zZUfLbVGsf4sE_LirrO!Oy!`giOPRsByDH%bTYqsTg%DwkoDk~aAEU}}Ls_ymtdC>3 zbTmz@(#fFMmstj(AXmF^kRgphbjxI;@GoK!F_eb_8FaZ~59bf-kAkksDsBlbo^OA` zAVoOG{(Ck>COSpP@JZo~ySenL>X60I` zL3kb9LnYo51j->hw$2h+l?81DaQ+7-7NL>0Y@?Mp6?8o@!73rJ9a4$(qRU5Km{|@c z(8ieBd8*K_J3~_bjX!EVd{iBj>-MjJ%RktULf{e%!y9s%>-7d)v3A8F*4OEpqIg{o zR5Ipdwx|DnK!7$&dWu`9)N_7#Z)2*YCs#@gv|{_tJ)ih1Yo^D3;K0FZ;h3vyIc~MG zMe=vLV4K>;GiEct$ZAe={B8+e&1E8t5-m|3FO^KuZrl zQD`504)%T1IewII*59*AyCGtX81OSSYLY1E{?l74CNemEAUf0{iM~Rr&zVg>M~)Qd z;FU<+M^A=ZGpw`bPr9df{=5Hqhgy>PmL0Xt*gOeN>9^Ouh*Yr0dT!k;XmQt02W4!r zV6|S2@D9(|$(R?WqS5eNOOR#cQtNfz#K(YcvNJ)vx}is)_>r9+5kV9*fmPup z$Xa|Fp=ju(zD3ps6lQdA?{W7#q{S2p);@IMGpzY>?zk3A&vGDx(m2GDKj3g3E*81} zA$C6vfV3|+=gq~L;AGeBK+dkm?iwq_#_S;-GifNf`wK-n;XN$kD3P+CHXPkJ**Eq^ zn^IYs2=9E~Jw>$RrLdN-U+B^Pp0Xgx-{89C{j7+m)7>Ex&tfP?4tYgkw$yMW$?)~> za|Im}Uk#H`FrX!Uiv4m-UAtxDzRoR7I*HokKwC$m#9#x{oD9&4Lo!riEuH$$Gn@z1 zx}7GXRmi}jE|#gnyG~k0j^tu*Och|B8z(b7A79P~_zlM*D&D<);A~V~d zsoFi<3WN{O+U!qlGI3X%HNkq~6jhC;6w`|XF&R>g{w$vL!u97O@w|j{jC@amQRS6J zXU4K}NiRC;cQDxUW^SO0PP#&^|GMk!VEb4@+M;p#!5tCnJF3Z6gS1#x3`ExfTb zU771xyECbCt5E(}meV0cf*Rk-r1?e96ZLoiAlafn94oOB{Pw8yL#>|6OJq9|Y}f$^ z+v3-XH86F6V(XZ}=AG&p*dO!6g#|aaj{~VL&W2x?1udK>#2_B@grI8?dm32S zAxFGj%Ca!BjF1=^h=Zk+v@EWP{V}XXu>Q#Y8K5`UU8vlSQc2KjJP;qY>?NJ`-DtHT zpK18=gH?xNEwD)S`YGXhNraVK+*oz&!&(Zb-^xE8;NSk%o#LDcC=?Z-v2wq;!EnCR{(5#&K)$S(ptQq$|ftMU>;me)J(x zp86*|ZODs)p=uYX3c!mAt0`xc{P>jqYX!W+$)*3)QJ*5-0(vGBsxia6TlpB@vCBPe z{U;#rWj<+S&M>Q~45>Cf_0((*>@1n=jcvC2H%216W%0^TGGl^PNN`3lNht)Z{LR)c zrfc}vCeNJ<%{?;rP2{lzhE61Y9?xP-sFVwnl#5;Rx<5P`a#Yx-&{9-cT!dC60>*QxZlE8C;Hc$UpmoY}XS`HJ-JE!D|wc|9< zOLDBgdCv@@#Z26!=6MIm2e}4EonE9RKt1hE=!ZQC%D|5y@k9mYJ5ph6cKqkW`pc`(YZl?8NlzUI_gp2;iyQFwVX;*9E(`~E6eim zxJ_A^9d33~MJ=~INo7e9_L^t0xj-`)N%5sfURs%xtf^WmcT*5%z^ibAkN!NZokF5{ znyP{-;#1Oj+(VW3^J-F`K!6pj{GD?*rnO;VPp3{^XZ)W4K0v|0b{Q{oKwE`rl(<$$ z)jsT5`Ws_SlCk(CCt-|1YM0dc$uM{k4|5Hf)($EnxY3BJ6LYkONj^~8!_gj}v-+&D zFj>@lpEEIXDNiKE+!z5(aS*lgXz|ZgU!OKe?1cAnNK}ZcLB{EaY%0E>FY8$Kl9|H9 zv}Ce18J$ZUss9qn!A%oRYFe$jFm0L;C#%2(h++x#7gc-I6Y?j6X@2+VSzi&|2RP?bV2=pW3x*W(-t2V{JSEf7D&dE~jNcF9+ zt(H`X(p62Q2Bp()7Pnd2n~zMXHze5f3_+G87|=B;BQ&vEbW#^qzCz#+J)tz;7X~P+ zXEM_BTevcqDATy%lvm~crFU6Il^Z~JPi(Y>xKo+G+31Xhug*T5@zc9WmY^Xn8QZuR z%(?%TGne0^1H%U_yheQ6+;7cV%&pzr8@7-zo-ZF+UNB=9^MiXMTtKpU{B7_fuUT>8ur!d0snaQIqQD()5t&upUhh5{gi$g$#TaEa24F@#k48SSi zGq7*2xOxwseDgcsn{%O=ye7e(G{>94e9F}Ctwr1mw$;6(q|h1R&PoR}h! z*&n_m|!AKXv&4AbPH_s@)(v0R;n(mz;A>!iSrFr+V36wujbJ*3E4Bhw*iG%w@ z#-N#@+zOIg6OEEFx~DyF94S23=z!KI$&5(SI7Sxpb5bq1pwxhS=SWj3^%D8oaiDeR zxb!yHixrQCCGRRKu`E=Rj$~-g?I4L+B`Gv*Ytde^vOhVwT`$3%7pK-dEkbYEgrd>xJzevX_W}brElo7 z6Z%XHt&=<%Ly@Ud1Qx|bPKJ_rZPHhbBt^{kQp%V02~VyPmKW6-^_;FHqL0K`fE55+ z>GtNhe1|IakU7G`JNsyDO}@2Z2@UF)YgQ2hASd z5dRUcWp;DA5bwFxCN@wsNuES2YEj1&;TzA$r7D>$hQshaXlS$-=y{okz8ul2U9uv`^$ zE;f_vA1qLpoLq|4(qXyr3z@(hRo7=i4o%4q-e(OcTXG*#$<2z<3N;FcwOJ3nKu9jY z%8*nCbjWH>mR4{w(>J@7|E++prb=iCsez*v=ZVzPjC@BIH2%c`B~vRX6ntDWu3)2@ zR$A^xI_0{0s%#sZWD_xVIu0aiK9d5eXbGF9xh`ulv_XT~LgPjNUc8rVLQ{2@R?m=M zX6=4PhfnNmto38gpX^)tp~X$G>l#21nBE$mn@mu==mkqhStjKz&X4zxrI^FvA6^{L zkzQKMH@tC6o<3J*{miLzW;Z`BfBp69*J0jWeizCyt=cPS>2fA5BABo1hQgF5d5lo!!gLN3O7Ay2(O4mCx#Hq= z0AQ?gg+a^Uc~Y=tuE+IHJ@d`n8MH*^(W1&WLxo<IMFpFn6_lNH-Gk#Hp21BAVHU!VR1p z$hY)&H@*AYUxZfjkuP_>AWd_uj>1{*0ejG`ZMvK!Lxl1;noE zJQsGJF?^GYFJkqH)z(lldZgDIK{9}G(|(udu4 zsZ&~{argG@`&PGOL6n15Wc|MVaIvZOOwA)URz#bqYa}ELC;TC2^bI7sFXMzU4VOkF zMnBHIrW~XsTj!Ez8)R;+<&3#Xtrr*?Nn3f%q1vtar(B>9C(8JOord@z-3{d>S>Oi1 zmPQ=Zmh`hPB!$5%hD9x(!~l%%iy6asF&7Nz*{kMSn8_uX@?9p%P(04oj|`hel&G+2 zD)gGlm2-iItb^2KPpFOzSpYwQEIB7mpkgOE7lQKq>RQyTHjL?fBq#Tqvg|y|V*+y| zsx&q13ETuMTX?W?W!Q9nh~Wfy8jr4UBTZ-Y=uS<@)V!I7n-)Ry4Mauug9$l+v?gRo zvO@(9{e6ULzi^u|J0m_1hmoz>v^c(mtwJxNBFa#oiyk$b@*QkxmbRH?K0}FR({%w; zpA1Q$m`q6Jt~fBI>E?4qvmB^=&c3vTddTNBQ;|f1)cb}?_iEp2G;0KSZi2g62=@G= zE+UoYGS?|?#ePxi3eN+mL*C1BE58vQpHo9l%eS+7BkyekQO8pZ5n z3>$%`p+y{?5tZtIG@b;luSSenqNS|P#o`~=2bDRQZexHlPCYXi&+d%`*!Y{%of(2K z7oBCSs=6Gz2SRu-{v6J))Z~p8!WkhiHsX{=5EEqK2W}eQpG_(Pmp90(7N>@e7yeZk zx?#@O0gaPkH3alJW~o{NOgzpwCDJiQG$jjEMrz`+7cnQ!GkC(kE|#I*h~#pyNu{1< z*y7kI?H$AhL$?-93D=k;7A}byX^^U5v3`J2B*t^a)q}8ax-d{L!2|!p8YLk&u%_0Q z^*Rw125blqcdKG)idzmEfxyHS@Hw#65dyJ0Nfy1BrWobDi8zM)OuIOoH5p82!xaU^ zY#c5cmlm>25#uzTN@e9;-ij(R%b=2ZcR7%p2~z@eRpmr&X)J9pQ7QO_Nv>uWL!Gj{ zBVBELP>d%r3nzlGkwmq7C1ZWo6RPM;D3~V82V%xCRslvIwcq(;i*1C7zlm_Ld3_3P6B2Q*TSfz3 zvBI&$&7q}S%YuX(4=S+oWa@8TZf0KxrezK0ALSxRy z?$sA%`Ou_gY{8AHIqZ7myuTO$B0MbD#SnpPLtJBc`x4sIcf=W6*e0g(~LB? z@?t*Yxw$y7HDwh|ecqX?DN`%(%hW-s4S?7bq`#8YScuQjnK{)uE$vQa=jJ1oJ4uc*lUmQca{jAVu(D!p=fmjnog=(CdOUm6@m z>JzR>7}g-Flk_7x)n1mT*tX5`aROMa6IZB>SBcZUj`OQwc3oUe7f3KOWV|p{B7}-d zy>}LynLW&5X*WjY5gRb!kya_~#G51`wfkw^kKeCV1#iwuu|g8#UX?@4QqZ-zsWJ-Mwk>>5rZ-k6 zwWJw12mKFRzjdn-yFOVfMp*d3iT~*D?y9yYD#}VYBb!~=%20&0ejl~4z;#c?VD${) z)=rEz@A+l}jk?m@hbAf435r@1Gb_9;3a0OIl2X20*qMFgGO-(&xZUpOQ_`hzV|0&m z1nEeFAJm*-WfP%GEPuOp!!_%K0zzF2v3)D75o9JB!l~8HE)sH~A`wK0*_xn|v1g5R zYXBlDTW-1D$&K2%*qdLF5Tl2)s>gzlWm{!~ok++dE_z_?-OBR+`R2@w^p{ySvyof$ zqs_3hHH(EVK?UF1COdqi%H?byItNy@g!qOn5g>wZ zpPZj*6MHZsjji{43qZaoG?T@_w~ekfn!2>2mUfy33OW9{pY&WQxKi#}VhyARiVkA7eH>l5pd>u zBBA$I`9zt6oXDG0ax%iWyIXNvG)$PHc+k96MVvM(uA=BVOPoQvHzb`8@%FX`LW9;d z^^$hYnkJ^69*(8WFu56e;JY~ku-f-=u5ur*ffXn<==jP>g9RzEvOAdO?trpeUt*U= zXlyWIJeByGhJ#+dKn7SNQ^M{o%zXwSY>(cCvt(!{mD!7AG3hCBXE=RTQmNn%atE&q z_s(adUNgW_7a*05R&nLJxI0PchYHmS^Uz(2QO|h|3m5U-^}Tu8w1b5olZQ(EwN^Xv(kQh8I0O+( ze7`2ae2EKSWmhc>@Mk|tV96MA#pFY)zV{RAs-hf`R3rM!66Bcw2(l{|GGKQ5sMa(J z{W)zdB*JEGmZSY}yd+^pQ*}HtPAdAtV}y;{7#Klcmmy{|z!I%yX%#rSv5`T#T+`Le zDj#~~9X!7Ql8}}56{Z}8gtEAmzJ2>PT{hi_d?qH?YrD|aNt^HtCYsJfZI|=FVZW`g znR@B5qQX~&KR#reOtj)8<&Y#{v@8I#POQQ2*+s;1c^-S=qsJWH(lSm%rVCmI(b~m0 zyOSqi^q^KWl6^-f~I!*5er<+`#?y68lQow zjcoPnujfm6SmTTzTekobHZ35iLoE3e)%t%j2>o7{A96bMjqa8mW=MG~ip zE>N^|&idK(T`ot5VClB8Rx;xqN4-2_sUar0VAFKCq*$_jkY(e4RiA8lEu>tfxmq1`U%zdwYjKAC>oKLKUrHfN*6&cgO zPi)|tI^6ul-NS~x2d&)9+4OZ*wLX{R$1pkILdtr!EaOb3Tm(flvr&>>nN(A&mU5z@ zs<)iwf^(F3z=B7Adr^bsj>&uL`E{ikMA`Cw9V44!+~p`n2AQSRB~0>$Bq$9jYibp& zz^j6_5}2|R91p)9Gzn!ne{;o6zUJeJU1cA<6jobfs}Q4{mosB`%_+bvd5CGqtE(&0 zt1YWpni14H_I2=j_f+dEn`kmW^k-5^Rh+rv!WtvQDbNzL%QX?>1#RC={*~6M)byg# z;@bdMK%e2JhcZLdtV}~O*VgqP;)uZ?k(h{00@}Q%J8zdlp^y_G_ z$~a62;L^IW5RvG5YoRm&mdPYyIOZrpzEU)fzNmN4q1D zF3^of2~k}eHplxYbih`@7#qKYSKu)ySzulPy2*JPS=tyBV%L?t)lK3!j1 z+w_ly0~-!r1czSuoNU?w_-ui%qO7{!7@fMWZl1oYdwTEnSt|&;5s6Cw@!46uvDZ*x zJR75QFa5nvGNAnue>9#+WVcreC@Cd+O64AykP1#9l><}Tmw|ReYiC1@Yt|AdDUi1g zS?jD9e-k&8F%T@b+sM~jR-Cf5FXztZ>Oy0>56hM!p6gwQypYu%YIH~_%b+SuEdUw< z@6fZ$yv1dYYO|DqBEUlTn4TSJHosf5Q5%~aE~}B)J87n(!HNWcNu_Im)O|fF<`Oj~ zp;$p83(&mLur$m~wohz&!lDoAay#Ke*|?k8DI%)4hfe(V9uBP0jW(ydBvG!SblGydqPu*M#OngLT4LYs}1 zhB{^hTyNMytZh3dkrZt`_x#$rogEv=nWfnXDa1V{GlWqh7MQ{di8X&{pe-ju#adlK z4-_?7qHA$!b5Ugk%EgTB-e8HxgV#kW7W7y`6#0_N)b}db@hP{@ogb{96r^5E{bbd- z$4_iw3hz;=Z&HhPa}a_3fuN}|+uskqfZO#J{ zK{#`XUhaXdSv{-JS}mgWU5r_|cY)f>#P~xzXh+{{cycHy?Jdp2N#o0r z9-SYF|@VtF=xOedK?BJ`v*UwsKZEbsV^Q$%anf-TtZDZrB zwe|JwjRy}lw()sq{lV7uSHap>zrs(2IC@&j%`lEfpLy=*zMtLPzsS#?6-SVhRx`?< zp#5|qw$~y+Lmb`37-R&439A=tDLrZ%m;{ zuY%yL0|X}TCQOk_XZps{N=u^ZB9jdrn6GR+G>YfZ;w2`>HRCj2b4MEE$0Ih6eHR*x zE_vB4ATDW4E$;dox1{u5F>E!6h$@S1A%2e-G`e=Tu#Z(iMwaaoSNGkluB8DtjR_94 z)Fa|~Z-$!VYIj0MG$75HrWESaCz6-(jGCy^sArm^G&;v1!Hoev7Iiaj=u?+6HHi+U zC3ma(RWaluS8>A^vm$Rhh&t^u5#rEQ)XQ-_w(ZhU1^@X$aCZFk{LSv^L2!5$oSYuN zKHNXp50-Y%=i6MFCE@p*7`NJNVUJwFaGp$>I;K<_nH^Hch> zMY}vbx39iAJUeIwyQha|IFP5O$22^SlioPyLFm1g2QmtdI;h>unN z(O74A*?*XB^Q*g`-~P|(!S4QxgAm%wKZyT#I$K+v8UDY~+1R?{|G&o1~_!=5Rm_&A@QbDn^x_U|cv+8oPKL@-+IBjr^@t=8URb0Uh_I7*E;(<_KNHQ4@ zA>sQ@gHhKb`%kedQ9@04bK+_~a%F3br*)trKc*-VTY^@2N#tp(LrCf*hdvos=TP-a z$6-x9?VU!gU|3U|f_v)o3-hG}dG@r93dbsXdDsi5hsquN;l+^&Jj{Za__}-yt^aCj zhsO{St_2Aq%k!zkmIX~?rb0|)m#bS!u=;mgiu@IO+Bkw%%)-9zIG_I{p@$|1R+84e zQs7v^FfK@q=gY8}WrjvIE2lAp2V*d7VvEv{qDdl%VODuL#kG-oreXCxS=^R+UU|b2P>8wZ6ERtpPAdT zWo)FBkiw_A9xjLNOnailB8RB{>3(*TasfN_58*5A95`1Ri~X;c?9g-1@l3CZ$SCw@ z($-Jg6T&i;7o{eQqUeRV*&^S2%@DA_DJ_M%IQlK*x{1q0BQkvh{VHvym;nrdJHdb6 z{0Q~=ovVe$+O+16vq@pehNR(_Fz?zjNNk|8CUGVdH`>2T>gc;Ne0>>a$ru!fyjBzG z@L01UDG(g)OL> zy8L;GNa87y(qy5sN?2cvmz;^i<7@xVU{v@H46YY|i{t^6+VCqL?R%) zi%TprPg*hQ>$5OHpNI70ZcXA|SxM$#>Sa5(;qdv(j}YA2c|6#me^>RZ3w%Y}fgcawzr(w42)Rr|Ig`SfcMXZO zZ*Z+m(jgIbqEjPrxzhZ;xz{Cq*uKs${B$|Wih}6$%+uy$eVTWC;+b!S-tTH*A!QC6 z2LXJz?kB;sJQSmSmi;arybgy?*a_Gl!Ih+Ya2b|yF5MmABq)9&(PtM4T5 zTwdkWWae2v^ZI%l2iE3Px%N5_vS9|{tc9O>f1}L=j9=U|FP=yZ;-7hSv#qs?`QA9?tzNR9OP&47!#2ynAR^e1wc2Q^Mvz6d7 zi?r0W*^z6aF(?LdsL55b`XnccPTULswoCl9F{Qp(;Fn%+SthN0g1sDqK2iN2zv+JK!TmR@-EZFoZ-$vA!f-*TSN~L! zX7I}Cl+bm5R9$ApCwb?ox;ss-ISEcsQoQ^HQVQ~``Y>oWFwID6H9ZHuN$Hc{W1DT< z6b|m&#pAo&a#j*lWzccwvT(mC`IFy+2DHandKFK@empaDUQ2M08FWAwVeVdu5|*mr z+*Px)G~19jo+mkP?CkmBlil-OdF_QhD^=4N={jrL(iCMba5YC_&Pg*4eA|2Q&4*+h-pC)nzodPQ zKvKSKoQemypcfdH*2A@M4T_#DS{IDroL%1=H`D+~DQ03?!hL2hu28Pq^x;1zMbuTTaDnu8awcAGEE+NmWSPEvvL2Y_~U9zHy3Xn2ff~aw8|8j1suMhB0c1fZ8w&3-6T%q4C+uNKv$%F&)%cJrL}M@ZR2WW%ZLq&|;cp7)}3R*2VS7?H>xwSZw%x9(Yu{Noy8ZT@)?J3l;W~+La2m^n z17xc{j8tu`a$}IFTgp)Ot*d3cy5D*w zDh*kY3TzEiR8!i(bf+3L#Q~DF1t3&X_SS9_^_CJ&&Gzn!?Bta;fskm{$TpdgGHB3y7h>GF z_zSH!)%8lemnNloDQV3lB&mTdyqejj$+$Y3ZFVljZ6gjR)jm5bQnA%c=enIsQjpje z)TlL(bPs3MFHLO%zwfD+Dkt_C$Q}qN4-RDjI~RSyW&XH>EALyYo-P_f6eE*G;2HEa z`x&Wd3r3FfTt|i|qlL+MfN`R{*0y}SZRNEPC{F%!_hxR=Ly*sd)f*pT7?=b+WJcYb znq3W?#I9!};%rq&v6*2|G-4^eB$e;exxqak6`UesKEI6sSe!jyH+qmKj7dfV+=a^*)#COt~ZkD)YHn46OscnSKERa{UY{ zGml{-!c3ultt6+}QfkxFb?7s?S7<%hXl(FEN8ljjQ%Pj&$2z^g9UZ34r37aNn|yY# zmX;rMSyZjhjBhePXQnv#nJM@JZ1yOFSPIjnHucbuNpTeDjIfHzEHwUeb3GcWC{f@X zHWz;^7p(U~*42W`7t$p90>gY*c_*CcOesU5c9W0ExEg!yq-m+9N0u~GC|s3s&9~Az z$M{&Ya`m}Fb3ah!#H4=LXV7dkA_LhNHsiij;nV?3WQH*&BO!Wh3U#=}?VY>=c3I}4 zc?BFX)$a$JGAptN{MpVW%yMp9xwaVM_PTO=rmCs6y75UiW-DG7q1JVY-7D>}oVsa* z#_kQt^@+41x4|TM;mibuF7iym>?P@7$7qtxGz;kN=(iosfsvza-m}MXKiFLHj!1WB z1`v1%`~gzd0uc`S`IjDd+)JD}0E?D9$pL86u17vtnSFJ8X2JBq{1x~x+eT`k0bH)` zdZ7?&AfFxrg)dP{zE_wwqUuZb#1p1pPi(Q?mO_gu9AsmD8S70s2X__`I}Rve_ z!?Zuxa*4M3`aBMqchRNn0P9L#02c59@z5lNIR2{@VN=Z6n8q88=rQ zwP=R1&T!7kqG@-;X(a=o ztcNe_pn~;<9rI*{97na{=`N03TGAvW8T1jxITuBs!_y~mX%6B~_4UTRVdk>8>rLa` z2*x|5muJ%Kz?ue5g!aFP<_r5<7Z=k?lO2+~unJSGA2jp6`TRcb^!};+v&rnu`@W2{ z$s&`_UJS=-yb>Cqx1rpc80HtYHr2RA8!>R#lF{!AeCv(Q-=AJG3r4)B`Y4_teCjPh zrdQ123Jtfe!)DHyWNg2M(oC;t@1kmW=03n>ofU3oZ9Su_$s;#yzK=!TvSSg@xGMARHa-`gmQJBD0b zdg$#5LpMmbYf3GH6&K$lsBMa>dSK6EXd%@a-<%sXul0mv(aB^KrrI%Uet5yEFgQ+w zS84K5g4MK#+UyJxYvSOY{dSpD{3by7-SguY2dj(_JYHlMj92$r^OOsF04B7~<#uZpm9yD!LmOQN?usQ85i>-p!1cW|5jn#Om)eW|7-WBEHeW zD)93rk4GHVKPlHV7bLA17|0rzX8xkAn`>1|ftShQqspu%=gX|`X_ z0IuQ=hohPx(0M(TPyJS8cr!buYg#BNY;*4zah&OnF~W-IB7(Vh%^Vz67!2{Lo|dIB z&8$^%GdhEn@megepaY9%BH`6>MZJ2yp+|5`3j_M1Z7NWiWBfy1{PXn`?=@SvN<3}{ zo`LtZNnqC*AuAl8oO>K_&$mw-Yn9fstOWuarPd!pYrV`Hlo<^@E309gYTJ3)*a zAOAOc(4k@WPr;uD>7V7{K^pv}KA057kk-Q(`JFekEZct`T*RLAl0J(agsbk^yZpR= z1pQzCmFa(H{lOjm|0kvY_q68=YdhJEhD*}7pW_Vl8M;t32PE;O@eTb7`Z!1p+5GW; zh41czbeb=jE}Wh28PX_phv@1%pJ18?LhayT=#fsfMC5ISh?0Fph!z)s?0&%3l#KH( zAMGK{Vn4$Feb^*1Qq@fx1a!0uDe*SssKM8REi25(|^=$t4 zCcSY-|9=(wZ%WU7Qh-v-Cw;Qr~UiEBuerEF=+n_as zZ|HKJ^G`P-zFPLwS~t0iacXfG@s&7(s zA+#ZZk0xdk1FeL5$eIz+GOyeEFA_FmZY3E=DS(_isO7Qq=+0NFlpe!*CBeZRiEr_0 zf$}`IUx)Up=K>wO^>+5ygVagLr3E12@^~V>dL^d|QPim6CERK8?U}Z%^~0k^sGX#PcD_S2$b!4ORInzRIHAr$pYf= zB~ZrZ{w=^fLq?NPwzK-;o)mkUtN>&53;&;K6QUQ|gCp zi;8VCi34;_oTc2dJCIH(x`&(C^kJzbCD^7vx-dQzB$?1q5@IW;fOEblSs34iHoDv# zp?twJTkv%BfZ^cf@%h0HO3t`7Yd9V5%bY4_%q25}YYQ2U1gmXYuJeF{F(gWzL8D2S zSR`HG%6L*vR}h7vWy@*@HUrxyl7Ph!bZn+P!F&%ldU3YO!j<==6`Q&ZQRL!zmorNkY}Ib^rGP2@E6)aZio4EL#x=M6ruV3gmc569=|+?OK$1y z(i8McBMD=S9u`q>7Ny18r566^M`_dwcJl=Bsn6rlb&Q@PEfP7>qK%qegQZ5}?EH^M z2Q<<*-|U^8HKO1rZZkg0@}1z`+S*g7l1Kq;_v2nBwW@ZAI;AnR%0{#^M2C#pOAj6_ zeu>MRAm)tU>}Gx9O(k)O3BNta(y~1uL>NtXg8#%{#ee>ncH6wn5!_8fKYhwWyXCF@ z7x!<2<;WxLZdR7r`2T0` z%ln(gvIYMheF~veIySLo0=2y7CeR@Ck_v5J=2yzg&esakD$J4Z9T^g_3$-*l(( zq?F-QX8hp6H};HW0ceVx*P`#AXVWp&Ba#|=n|}cMq9jTllO*%7F+oW;zoHSl-MXXe z=G>~hrCp4s$ptLe2;Gl!X9K?Z#%i5N*pJP_(}i%Up^$!N$Nd@vU^Wm6oyt`ySQ;%k zx=LXJ&yVg-PcfoFwd|5Y%hvCf^bfoymJp*6WX9b*yt&b?K5m4lU0jWUvq1WVdbzioWbT}#66nv zV#g6BPN?jbg-0K`*v5R&vsI(AW(|<1-tuOU1fzLvYYWzKD&2jP)==o)BfFM1c%ZVSB{O%T!qk(Hj+{ROA^V-2OO#6H$;e(0`7i&d27Vm&_d zfI8|hiNi3z?mnPjGo1hA;XDFt_BH(X4gB|Qb!ZRu&>l7qtqQ|ch%T( z0apsFD3Mo>C|uXcQSSq`x`i#s&u(c|569&=c!D!|G1%D~9Kql#v)KgFb8xW7pS{P} z1Ui8{zKo;s6LEt=1odQ{{#k$A<467k=PRPXkX__M-){%IOz3qn0&w69*|#0w!RcY! zfA(cJ!y?jcpgu;13GyC2XPtrmq2pBn$oM`BA-Hq5?Yr=M@4~2qQ^-DwMKay zr_>%d$aqM{+T0HQ8oiH>>7~=i&+wYd20WBr&wqUHbQc{8Pd)7~qSe1;c5yL{j|u2n zKAa>S8o~c)#Rq(kUZ>M|R(XZf^sINuq@@!8g%@!--~gh}uJ`SR-KKqN7`Ags#mcDg z53TNs3c++3060|Y-FSAF1&Ob$;iAC#)-lFFX0|ZJx2Y61bft&bRQ^tba~cx`+$4ez zf3B`Kjw~dQ3Y8DmHt=&KmJe>3QMH~QAaNDcW)dbyuFCv&mCtx8xZ4!&(lZbE zmaZ?+Z*^7IHw`eJ&Epi+AT1xx+!6q1*W3_`Qn8L793Q?p+8qpc5BCOW)qj(p5q~;izTP={X$#?d!O(ms<@9&fnRYV1*u^Ou|Y%Moah;S=c9@L0ukNl@4F; ze9!DO&fR-VNgxI7Z*M%<04{1em3u)yBbB9|dAz~ag9m_SM$@P$wl|pU-k<@L`IE<` zMvTJf$IQp zc}brCh_uIcU&K;w2Son{PxR_HFP9o~0C$`{CmfXp3)XaWM^7-Eci-;ad|F4RUv$L3 zT=({$_ebvw03fH7@Bb-1FXn%4J&x2Rz@^rMC%Zo!Kkh|O+6Vy6wX40tbAIc1Ut#*Q zBpxpt^SGQ1XHsT;br0}_tErbA3!4(wSL=&<3p@D4BMA1^e*GUHV_xnYA2*+kUkJU` zvmvY549K?v?>c>gg^vRz zsht!4cG@!4o(GoK zmFS5Xl2oxqgKuykEJawoG_SZ!(^#zPtCqwnW{p9;#c_zSTH!4p#=Z(h{)+S!YCP6x zbR)M6$8=_mM!%HCr1JttN55eZD@F%z)JRR(1V?M@U#28$)I3Y8bvAcZMH-r3!1l2Y^<2M$DTE4dHC~8@U z^AeTuMV4Q$`!feyx@gjFhu_g9X}^|s>5yTPy7(WS&@{L%fL|iU^n^~%fxP5G>ln>i z0g2Sxe|~Uya<^7w&EXdXAu85uP4!U%iKNh}p|6Z=sjpe;jddxwzR?bzFlUav_-7h~ zxgFdbg$-vzb<&pNLcmE}YTeY7YlJJ~_P&dpC5C6JN%2@jUXF$`7@i5hIO5PQ3eusn zO*_g8t?TQQp$ogPd&d`uf3=j>1s469H+t@VAi;m|qrZh5`bS{Vhyd_@6O8A(x{KxmY zU0?K%D1(82x?L8;s8z!rb~WXUCu!}YMQPudmGSTs_kZK5-d2$IKJPDE&aNWtkB@d0 zm)jubX113XfaTjuMBBfOSR2|QaorP-(j}T8#@7SpT^}+vMNqT6~$=wbs7= z`q85(`g4PhM%PPFNriHX+^YAG{`}cDrBEI%ay_fmqeo+_sdw@972JVtp-1rN`SXS$ z=xQnMR<-T#=#OceQ?O;ZQ)r9+Si{WYi}=I5($u%#@?=yYwq;mSsBwjT)+*m=PQECw z@3M1HwkY$@7)2g8Pwa6|AV>*5N$TmJUr^EQ;Oa6dH8!FaD!#5->%m~a?mCX{ z9kJ8F$??sfC5E7*fvlN4(H2^!Db2opK%A>h%&azyonXIigTEhnL#xY0Y zJi-v3luKnBbwyVRl0eQ$dE(F+yhT8*;2kduobL zSh_9?WAIe^tW zXYQJCu1>sZ)Kn(TxR9e^X}6)UZM z$?4!O;?Pm`FnZzNW~lbeDtE7rhx5e%|KH30f1YP$MuFOY9}m!5{6D|`?m;d7*VfjT z{BM7d|L38~@%lB$Z1afwR^oqk@wD%v=^uE zDV!KEy`tRkHzt@YvDkoDbkF$WQ0JfQ9RC-(6}*Uw%P@_v$SMQHal@Qh?!M#kL!U9& znBZq1;9BS}L>g1EsrU<-g>U=%y}Wi^x3>M$Gx?z0hSV!US<+9OUPkFCZjIx4v7IK< zj{hgJKWR5M`e_?O8dFeU{I}BnF$O!>0=3Ru^Yp9+ zKLV7e2{IR{_4y2acqdUZ^@F`E-6;Kc& z>YbXR=~(@gZ}^Xanor|TzHG<1ZH%~J_SW`<_F1hgth)ng_pceuvzSXD=1~!@V(ND=%f(HHBMiM@P;t zo*?vdkEL2jUeizQd7y_iFpP{&U{NZFMK=ya{K~2d`$2h_K}}8v;62XIj;T z(K}^sIp{QcwFQJ7+u;n$RF;UUHl8^geYoOOn)=9R)$6Nezgru{bbmn7Zfjl?N(Vp@HN*LpoGV}(rm=s| z+3rAj-3A&ivCimnoaC(_49#neFLaa#N`6Aq1Ql?Fc@2jo3mM|HzIvcDm+*G~s(717{}biE_50D7x6uFJJ>07K z|86~a_=W!eBmRVYWB;!Upy#(9b};Syw_do%2_fLR4-X5bWVW`#hv7pnJihb~c3us< z@LUq20OveCoq_%}x3> zd})Wa8%U!HD-uoYle1LSYp(ZawsQinQxApGxFxnQ#?8WDc ziwlCOrJ!P^)H^`l=YY;^wkW+pQ?9U(riY(7!x7-`_dciB(lbReQoYA0RC?7*nQ3Ep ztMiw2np2nks^K){IE2X{NddaDvWO374~O!A9+c0zHT;?RWl(m{u$`iWX`Lalt|srlKN#g-*KcjngiDE*S1 zhs()@E`9E)A*-zFm2U5nY~AhG?|AiYew1!F1KID>$7|_B64o{>S@m*nT98;;Q6RmO zlVy!}Yc_VNKX>bMQubR~X-dOhAK9SNvQDXfTjQURfL$S@{S*Tt-F9=mmk~)?J?~|9 z;R~D7m_1Lb{X?oz=2LYOO-n7y3`r~#*##;gwE|;s-BxlRhs{s zx!syF)ge$3W?P<b=*ZRsbxy9w+Q8rJnIjK0H#0gVVR7kEtl~cRpiFajT=itT` zrWA-zdi=q_1u6=?6=@N59idQONY%@DI`>Q-P<&M2p`a8Phrz(#d3k*3otQM}v39@Z zrJ3M@D3-*EjR#YnVm`X4q>GtU62&FZK|RIxcJW6=MT%EOX)HkBN6D1HAtMznHTLoy z837diUJq3p;RWo?;yg?;YSd>|Vdu@si^C&e6?RghoaVrc5ZiJEBfQEJz;kdzUeou# zCNuxXILVQY-}#6Cs`P(OW`DWjH*lpCF`6-8!>{M8n3+W>kQ_d?#qk}-s;%89DPg4k ztEkKhX>G*s!Wq8%%RjTrEQGc66affyNfM=+kZa-jlAL*z02k0q2IX=LObKg)ox97Vd$@qvjK(3DEpVimD;}46pu@ybtqCcl+jik(LY9?U%r8|4sT|ofrMTCI0U> z4<3E}up0mOn@3;rfBZrEU(K~WCu+d+o>Lf544^oj5@C@`>Ux%uM3kx&N{RuA6RlA_ zcu0ywiB1_$2vn0RSTw!nkfhW2BARmCM@l*+5i8(QiZF7liWzJrX+J;}8-~BUirGGn z$cV;)vgF2XL8j!9&43`ma+bZAtp=oqFSWH_i?%MdY+8nfo7@H z;l6*I0Qq4zLt#ymDX}DF=CR!AnuIx;fEBKRQ->$xB%2jYBf{v)K-2?+E!mfW8bTfz zM+ysdoOS#w9P~v-jBuG*m7h{#T@r|SN-idegDJ54%CMYVo&x5wuZX8OU`cpO@j44u zYY~)ic)@nZiqGjP%Uc*V*yAb%*5MjOdr4H!memofRwz~QHY_-$Gn1L^SZR<)(?~8X zlPr7_KW~cL2h2>KOPDK70m{Kfo1EJO1Y#6Hnz_t`ho#7}oFt3ZgoeXQMFjb4*LDGp zKxGXgoiLaK8{?E)z{X57+56%j3oLUEZ0ftXEZUw4udD||%Y{kHb2ulh?I&$BEOK!4 zPsNC0tE0>*9-evLeF}+t-`|-c3wv?NW?yoErdjr`&~T3-GTvQxBx5%nV2|XhKF}~U z39{MG7b9kYDJid&nEG9OjTQTPxcHKc*M%~GC6+Syr4e2*>MwOqc9_vrl7b@>VAcfX z#xQs4-ZCoTH>Z78-flN92rpR+OSV1lr))tPq=_V4knoG3lSOE1ZTaw4gtbHwVl->C z5g0`nrP;Qu!T8(U0_hAXY*AnD*amsKq55h4>QqMQn@!u1W|E>`+2qFJKgJs@Or8)V zRI+As|iaGE&le&Xs29jSro(?IH-2DIa`nftL`LIcca@kVIsLb zcuU=t5iEZWKwP~woUK(myX0_dJSE7qY17RXlfGYFjK|qbi_8e#4H@C)3z+2DOk(>> zWPdtSBEIKyL?~M=BTl_g;&%l%?~?hPWUvxx9;ufp8ueX!wD%k`ergYi2p(%gs1l8h zB9KXZ@k%9q%Uf4GR#XQS#VSP!{VLqW$JpbqnDxNPS3ju^iHRIs>@i~xMcQ~U^-CrY zQce4W9*Hdsn3xm_yvTT|S`@MpoV2)uO?=*Ldkih*Rptv~;I)-PQJ8HKz;B+zFF`Lf zX1Y#!#h~v>L7EWhhc2_Ll%S9km13tlrMFH{T}yyk%~y)Q+$-9$JF|drPYLG~B=S9u z(k}`ur!l;Mp{=l5%%R9QMnf2$r?;tPeVanaCxqH8KVF~WKy@#1=FWmx$s7oP)t1o7 zSIr_^ELvJK&SDDMrcb@x&4tfP^`}RqV&$Q8rflA7ILY= z@dOB=v>)#7_{+B-XjopFBw;gNti~N+N3A(!)D4utdPvK1KjeBHw;KiMHs!CB<`ov; zh^&bCg42q1Q691Lg}WFAsTmMt5}oKjZB+nAVSY`%Kn2|v^oR-U=?CmE|2R)nu3u%= zv;#EQZZ^lWwkxt$J*EAWX-0h%Hcc;^e9}baKqRl^1=@Er@pw9$5Sp^a=nH41?5VRu zlBt9!rsTp?H~NVAXgsxbnzFU2=DVo|2{R?s=WVJL*lbh#c5)-N1B#fD8=^KS4^@3k z(!n7Ba856V#ZlYK^wE3>Sbd1^obTu8?z!SSz(DOg zVlgJwH=PfgT8e;MF9sqgIOKa|s+NWhPLg^SBpo8GR$Jryj*gdt&?>ZcJi4hhxU%Gl zp{D|@I$u>oKLo3ksR_w+(KQK&&-}Y)2j~pU6cfPEtl1@c@{glQT=FuJI7n=o;m9NM z^O@&g4Z~7v;iYbmfLuAeZG;FIje9{tOLY?v|7Kms*BSa8z89E4;ZLyPIELg4Rz0Q-2@~tUv3 z9Q;5c6IerXHGl(3=N03kypwGqQR+K1Z$+M;WpK>{>G+BVy>6+92M8_o3=z}9Yd@wA)|e3$?83@9@cP{ z%!l|s8mFKw9+5DN(E1TkFa2}Op@d|6)Vv~nrjkqwE)L{ykuf;*qoor$aIwK~P6 z;Q*O(zl>*9q8SFh&+vlLtz-6ES7f)g+KV)lvpr!4DvfA%MRZNrpW$AbIK>H&6ih^j z%!v5`y$|^II@e$=!|mGxK!6s6XB`wJyWx7MlVHdc+H0m5KU&=mLBGt@8YIH)>Cf3^ z+JVi5LH-r7LxeId6seEtIF6!)mUP61YBF+MN?WF}fnto11Xi+z#vN83NJ@mFvvheR zZetAzipn^58vkZ~P*SIr>K;VJNG_7)O>+WesS5@^7|=f!a0ww(hH?eb?4U`omQC{X z0$P^y1exgb>>RNC4A$}tc%s(-h8D<%i!86+BhFOlmt&+bv5R(i%oP-u7MU;L>N~%^2~;Q zQYgjcV$K$`)Q%j6{nXQ$GX+UA^R8ujqU#Ysux2Wi03IzI6qO|A4VaWSMMkKYVpNRj zb(QY2GsWS)79`O@w4mV&-Rt;ihHap|o)(})vTsJb)bUUI)WDFR`dD4Oyjadbt!p45 z`Enw}QB_&uw^(GA2v>owZtakoNnvUv?J!4DsiycgP}Hm07+!9+fza)0DRj#kHlt)c zawVFTRYQn4$%t7k3Zs{3=(1x;W?5({oEagu^BAbv1Yr%42|5M}{~HNiZd&?`Rc7wH zLymKwY;Tn3W?Nw?#rMxN;`pNkFLBeWg>@%4+Wn+yOJx~&+CdqxnG9vOJVz%Wg=Hm$ zCTIU+p_O1cnZ9l@!0x#n4!PcCGK|p&SLJ&`_++&==Jqjgf}9)CgG)#t(tt{pSPYXf zkK;b;7Os-w(v~MX+-HH^4!zw&ZbJEo{hk1M8?L71c!6wW zg_X7{q4Lf`9HPTkIMh-Z7$XO-s(D0dw; zS1E|QZ6V69kb(W5v!keX_kW1;1UZ`SG)^x>c&6^+lPa;P?^9zTAP0q1=tglbr~ z>Vo{PJ}K`_>?15-zlLSj;&1Jm`!U`YjMGR*&TLan9$#j|$QP;~oq-E>Z!$ZqJ$o=V zGRAbUGIcYTN~Bla2g>A+_RIoXEeol)C-%JXjr^l6u8Y*fol{1gsQ$$_ALp<=|G$H9^8(3(fc`>_0V<UGMq0RXF@rOou{Kg`LR7uvb!tGKgLRYHCfw9Z5myf5G7h!>?vy$ zJh=&603^TR)bfCCW^>~Btqk0e&YX^bMlx!^K%TlGnZ-ubF-?qhie+M{gjrWHZ5 z1I0{bey8Sx*)>^nqK+8HZ<2;r1`Ma**`joP8absmWhE!fi32qv1EtBM?;Bx8CQzpv z;b@~t4~?p4j+}PmcU`r#)?U$dPR-G}*^8B4Tbwc!MiIUrz_i%Nj7I9vfOy(DATLdY z={e!ZRn)W~90e>ACi@1Gw6NR_Zx#{Q3PPh+7&O$Hjsmi;<2_!KnZc>rI>U^aT!ss4 zKiFu)w8borw!APO49w9em0;O|EEMy><*@+t|2}r}yvz2<9&1=vsuELj%;VwmjB_`6 z0XKaeY+dLuPgjq%9gX%BvsS%Ap)H8HL$8Y1WANr(8CiC{uA!CP7T*~=XY;=GL-d3 zA5?E53Zp7T&D?~>)o7ZeH0H(x3Cp(p-rF$ysz;}d)xtRRk9OP)6Nsi*oVTF->EFY% z&98bLACD);<2h^p!c(fOP@e&fhF3f3H-{)6emBHZY5C)K#G@HOOw_VUkPMr2AE$Gl z<0X}iqN%81Z<`lT$;No^a1$_#q8Q=0h>Gss@TKdcDIa)msLeYdd=@$sOvnw6e z^QB(SSK2;#SmUznS(K@q6Wka=E-gcui}j^)lWr@?dZKc)@EP^oa0{EVkDE%0qvYds ztl7U)3rGvOz0Bq-%Xt51lDLzthycAYE-aMw8H$q@GdhSU2vTsTP$f$qF$xW|GGxW? zP+w#^Km}P6Aj^l%kl(7RBUW%Y6qtCxeZp`q07+}$q_&jEDnTX)_W|ZDo?f^o+DOqD zC0dLB=OFeuzz;V90*X}+_;QViRc#du~uiep)lA(f{FDq%RI(V83*DaEKi0$ z>};=h2$xyAVM0wjq{gp7Q8J{t;C1na(FD-f(D)nVmVX47VWL7WI$zVg-mI7ND$0-8 z*9+$u@!3X)EbPYngkZ^2dM-k19VLa}8%SDH`hFahHosw(#KO(BUE%4PZPTnDIa7%G zhCCMa&O?7}9}3Gnu!w9OH<74dS{)#fXR=}&#&j&?Q54~9!sbnw4*+uy)Tkz`%!U2# zr0aLPfQ)yazufu$_=X=U#(X#alLmC{`x14*>6wTP{iaT1WTYBLLvldx7^y@P+WPkM zXbn+^k;YecTM9(Xy0Q{^(@bbnHq4U^W8}4~Ty?!;2iqtYUcW^_vxv(fv=pob8e#EW zpI)sM#{HPttbM5s{YwKt-GAPvwPd3HB@roN!21m!&fN9}T(VnJ&s-)Bt*1-1Ul|&xQ*-(g_vF&2}@`{A7$cjo7 z9jU>gJ)EW5h5M_N55lzSyMtz~>goxbx*SZ2Zd?3FnSq~6s!6dbsMK0Ri6Hszt1F??{}s0TYv-84&@~Od-#NqgzyC zNwtNv@WhI+;ypz;?;;^h3ev)t4R$1WXo(>AS$Lsu8VUcuu)A`hePsBqi?br($ZsI z7WRzFO18F}kbV#sndJ3EW4o$O3s7&Ig;rReE*2b#v?qP>)0yWT2`kU!B@=8!Rw)}YGfrhRKDtccvLy=v&bn)F zHPeOqD4E&}P#A7M^;&Uw5%O~KKmryiXl1kvRt<-)VJy9A8f=H&0i1RihjCbA%Mm5W zCl6<3(5YnuY;d9)W!E#qF(@58*+!<(ILlL1LO2scdJFFgGdEs_Sjo04t#Xr|l7vUj zv_!ve8WRzUa;PXQ#~kGvsoYIQ+1!MUu=Ytad+aie1iliBShCQn^DP>Aj7s#vX3{V< zv_2aPb-bh$9!lI-i#RP}7G@G3YBkP7g+{1(nVIoek;p|R;D(S|whs!;qAiZ%6d*mD zc%}zhS~BG=I4Dj82tZ6%ESQk>q-e}XItrD@*pyIrF<0Bd%3&kCBim#H&&nL50@p@% zOoB+gtYj|91Qo0u#(OP{w9>Q9W@>O?q?Qr{PON5}LWS6qN6d-gmQn~=x~x!;n&{1G`ROMhelHOjfz@WSPqC7(9A{haK%*+yp(ZDl~-9{aDJs6UIH{k z>kk?kK+}Dwh@S#oFi>x9Eoi^JwO~VwZlS+hC6*U*OJN}dKyJMyz{F9NXc5|`swww5 zRdoPyX9a76bC#`fA)FaHotxXYwoBD=wY97aq_!!wp(rQRm+0}yR|Ngk_I=2B5n}~N zl%j-9>2o#_e^cLAp7YG=mJ-BQ3dCMyJX^f7{=6 z{RUrBmSgKB#{$Knpu{~Y(9Vmje(~-W18q%oYhjcaZB5XMLp6K4fuFa+{CtC5P#@w? zAbSpT-B{#f7)qrEXl&%Z)Pk`eq9-;Yhe3*|v~fD)tcTJcRO|zy_~_qw-ZM1oE9$=9 zOl>A4&5hu?%QkzPBxspONlx+{)_*SY>9vQ!DfkXGF(HPq8^9Y(uZPAEK?!b5Yp(OP z(r!13PJG{%)Ee0#hDz~E(%}Jm2WI;{UcVEgDll#X*kq65ZnKb|b5nJE3F_iSv-9L) z!HQrC{g5XVY8PX*(a34KK2Nu5ds~PCRTFU{X5VD91?4oSjbId9c#eZFk+dp07W(;I zQOp~ZZ@BHS8mi)EFEMqdwVhN8ivi}`IS}`Lc(8E-fBPpd_K)w?y@KtYC6C>jZ--9M zwzza_Q!KHh)DbXHso%aw+3d8m-5!OK$Xo)C2jGU*I`LSPcCZTuT-ftQQm7P`{f{Ag zDyt-WU^{AK6OMm)=;pl<^KtPOu|osUB`35>k9Guji~c9AYn;z8Lyv77fOMkgMro=NZkC@j(LK7HFNQ-zm=O(a zQ*{l&gqftnKmm%JYj6a#Isl?185=>)roee`(~PO(&9e9GW*y@;kY|!?3zpp|ELUH+ z5MskBGZdi~01;g5#YAP}+1G9sg&44KMgkVtp(9sMTIa7LR4<(OCRx@yCxe*f6?%3- zBNK$1Z@9dV9ayX=#}k~3ali;Y^^k$<*rJ&{X0IPqq&p7k=x@jYz-=QAwY*^^wg&+R z%e|1zw0f|-OSFE@R#g~TiBWHRR-omUK6ccDG>5z&{j8#j*8-KO7LZC)0r@( zsExi$7ZD?+lC z3V7Ame&6$@Uvxe(=L1>FaXgLLb!LuI$jF|H&-Qw`3EhFhuWogV!UEV1q6)&OiAD5{G(*Z zYOvgl7L?-r*-``TYw=%aFMX_c`0Ux>$V^kZO(>bCPJyVU51GnjW1ta*2_)*B=M=~W zupOzN7b$8=&`GDHi2Npylq|OLXvrONjzyuFy2fN;1O;laWXz?G_v_0n<#-y*7tiUL zeVuI$RzW%wt*9(B<~3;~-E+!xuVenBO9Lf`)Ze-~eL>YtoTW=}(~Pu_9IX<`!|MJA1DN6t5Dsm9OxC*FwV5S^5%G z^e*u~8Pomu#Q)s-dTZ-JE&k^>U*doMLGeF-yu79>?kTXB?>cbRmi{bed}XK&qZ_B| zb>HXE9fTppz=mw^2vd3z<8yywMzk3E0VEt?z%l}7eM!AclwPA=<%;ZUDO|z1#2H|@ zIUIGeD8*1E`-I+#=vsSv!)!K?#Up>5d@*|GvF*(@J54HIW(j6Tb343DGW6G&#@A%T zh+>5qG+jnhHk~~ODk}i{D7)l^GKm^(S$c+8y0!UT4 zV}KokX#%~6>BlSsfuAI=FmzDNhTbD6=`&zg6VbOn)8%#6W!H8l$K=5 zN)3yVE6)BY#a<#wC3S{DO2*MOHHE(N7?7Jq8>0+6r>I{a_|{|h`ji8MO^6PArPE;u zlZu}gxx>Jg?2}WXxl)8oUrE~_4RT=j@gi4@&Isxk+Axy*N%Ddb{64}YEcY}*q|e5o z+J@4jkWauLu}#5*nj^ z#>Jc@kzV}(hF?SpGGDK*&BnD*i#$Achn6l<%i3WfHR=8k63IPOp@O5w{w zh%4n0U;+{P^=L;_9-C%UEKZ7}p-dTKa*TDd-{UYRx|)my7X*W?(%wl757qxD%cioO zfRk}wIGiRTbHxSd!awf(nlsaf`>xA5qG899&6}u(&-|pRwUk%yEWi(Ld>un2~Xg z;9qsBBJ$BO2>3^FC}G|vU!X%lxkyu6YDdmFc&TvCHt(4T5EBA34EcjTJRDe9h6I4WkizwC956&2+t9c@ET&$BA@x3)AgVl(`)XtFo zN3+&_eaqvr8LEcRJS(SpS)3J7!{CsYF@^Uyipt`iCJ-{RkBu&1oE)zTjcdkZCK}Lk z)A+TaCmp`ga&{8En+&dQ&!qQ6u;+{@A=9Q9M}d2mLGb`!Smbb=lAV4_=!f0o{d;XB ziX!sF8;ixTlv?32m~a6_%sQNsB*^!XckR*fAChk+@?kLJ%Z}`lB0UI+#z^~I<(YVnD7~N+R5GukL;n03T5OQPyoQ)w#S^#@M*ir&XIRRv%lA|l5IZDTv zg#g|dy$dCfEgZpPcp3gmuyhZ%DXy6|+-*guYQF z-Uyiq=axF>Kin zima96?OI2JKtfK560n+xh@P&W6q@pt5Y5#jt4R=^5wY)j-Y z&ytD5MY%ydu-;IK#>Q2k#_Q>V0t;v?hfV`PB{A=11#g^jCfX_xMr}+h;PIr_h}`a(z9*nm+#(#S$=f(_+KZcNzLmn=l`6o$*GGhOB`h4Rvdh zw)L(uO&mA{B(k3JLl*6et3*^_EML7{zpmr4Lu{i9p|KU0C=q6fMrv)9o(MZXcYOtXqQpp_YrLz=fxamPFrD+OxrWy*i8AZtXM>_$?Z1d~rWWL^eD^#+|+ zPPyoj$vWaip(yeCAc?4Xo-fX)=;4!)9{Ol!2RQ^B*Hu!)+@6@MB+8u0rTpW3gf=K_ zldRmPl}cQ=CdqW|p;)&^hVnhWX)GzKOvuhuG{X=n2&v-?Pu)8pwL6}IID)SG{sEE$ zNj{cvd(5A=2!--{%RATaciUV=fdrh2(x*ftz<&Pi)k_pfO))}di3MK+_e7CNF%KW( zMe%DF!C8TH@{frGz}3E3)Fo#Spvx)EtiV9;wUkun0z}^!@e_hKK#d_|uf^O!aa{z) z0-8Pclxq@Y7We&)37;xM%?tl0r1O*<32Kvpn)Y-Qt)!Ixw2Czzf~J&kz#*TA#VIS$ z+5O6Kxsb%7rFKvfCghm?vW~Mnzt+}pR1LNr05ZL>f|X#ZO%Wh=l$76Vmhww(R5Bs> zqGkJk^$#Ew@=*Id`#}BQci()oMF02T;loGYR`h=lzx(!!{_hX@vv!ZNqMj#d4`>u} z;FZI@-?rRihbGVG8AoDgr z({Rrq4c7sD8xv!QcJCMH??jg?BG3Z0YUij6Q;MhgH8iJ8Fp6waUXh7BqGx0ASJC~m zJrW`GW2q6eu^VV=9JALhepMf}1q0$wn1i^DYcF2)c?t}PiuDIX&6-ckqpT%5G};bx z3ixkKlapJ&V;pM9J``S#P*X_ENiWNxwIU{hf`Z5km#s!9EKG)L1Y?k;;+Q9wa(U_5 z09CW*PZoI!-7?l5XGF0;ugY4*)!Ue0O9PJ#O{Nx`#_je9{^8ai9V6Wp3{`UH4aD40^9zkRKuU^00AHduF zgWZ>J_Vy3H_n$${gToX5<^HSv6KMA2kh+w{_6Nt<+^fOS?hAO_dA9#@|Kz6*H1&M{ z8A?!iJ2m1%lkD#BytHHrZ2>rr4fA9l5 z_{T4HUcSW6pf$-745RdS4`2UuwEz8!6aU5G%e?`-d^Uj5?L2!q;Lc!byDxY4Uv>Pw zomV^G52)55w1YFmf;>k5#}@;9iGA+C|94OJ4-arMyN3rSNATEzxgMS9%0KQO4?6zN z(f%5zpp!zqyWc{J^#axShB0!RdOAHsg39LCOB-ugM2g_5rPFBcRr6u7AN7h2#8 zE%1dF_(BWZLJNor3Q2%Jv)oargCPZAK#w;f6MABJ7ue*(IRNY=xd_ZFJo5|GZCUTw ziJ`>0`rRx`lQPS#H`%{_wzModi47&lW0npvs`Ui0!ELqRuOV;U@=>5q*AVdK ze6f78^CDi1vmu(CE{eNNXn8RcL~96FN|LT@Z|O$_q2cW%R5sGpMafZnb&+u~9h&HL zt2-so9s(e)F18ZBM8P=ZSYk_yp?>Rnh}y2DMbPSHbqUnw49QV^_1?0}@AAP|%)!z! zsM{x)gX6d6_lq){W1cs(Es0j`^|S>=>PwI`u}bh<87yRB|73Hfx~&0O;>ydA`>-* zLkWA;Sn`&uM%~I5v4JYnT~_wIOw#y}Vr&g4_y{`k0aHOa6;!}L`qCzc-!=036%!lO zW}4Gu(%rD%F4}gGqdPn8DqRybVB3y##5uO#->Ef5ZlR+3WG8q|*v#g2J5KO4U;8kk zO~)(V7WX}_)FCaDiY{?di9u}7r&V6h#gc~9${TDRfPtHbtUZ^^c;eNE!Kf1OxG^10#t0uI1d6Z2Tv(y9v5YK7T1g97R zDCnziL#d-0d#OSa)&h5k@j|PTys%~})NU9uv^1oahMc}zIy(ec`NSj%he6e;eokMdd$2{*qtc)s)I<;n19=f4Ke_g?}Zu`RKSeZEsk z<=;_nj%sgI8Mrm-#qcG)I}4G~|EJ!KeWY}vDTfhX2KKx}K&$wPE-pP3i@89x@BfAK z)+kY;ywqWb;Y)3j;dn8x7KCzXGF5L;ZHowz1Ds+br)TOLzk@xnUrJb3c=z!}y>rPd zO+H9~#Fz9IQH&~YgT7Cx(nIzfr>_<8uzQcjW9g(7;6C`ZF4|2cCwDH1E4!lXUkq5m zu#QjmfMX2d-BbO&a*&|Z;NXYT0C!}#d-(FrtApd#N`D(OC{a6&PBz!*e&a7%UUpVLN!K1+OU} z{jgtJ)T)dv!eA6%ngjl}(ta7taZa3e3_K210hy263d< zXpR!fD9vu`Q-4=Wt2bjDpD!+kQ8`2|Y&ZexWs#c+0UnrQP!w73A+9&$HOgVtUbbPl z>bEv8{`re^im3t(qS+ffd-Hv8rb`KROHK6(&H+wBu$@w3@JitU?Zn zlZJ2SDq$vrzPI%2wtv$AJu4QLW3P&nr!uwURbsy?vF|J{7v(s+N}bEjSySc1YIxr8 zf{dXRgKMw!&)GT2L;>e+`+X^(j_Gw0PxYC#+xs~~2lA5F%wnbZC(`Y_~=Y7x$E{7vGTgGyT`Ss6`L z6R4L%Sm^tvtr82UW`;>R!~(VE%$}Z5$rrqGdkkB|(c4p#g>4f|!pi7Dt=@+UtYGk* z$QL@_WTn)c0&^k?QK+255+X?vW$$LA6Ne^He_eF6r6QuxwR>*efoK;a=t!#UeV zUyExy5<7VaG$s5V=htv_I;Jjr3IWEJ?2R4$N`n0QeZ5T`LGLR3uWlsGIC@!!g#&Ow z!Y{%^(Cbhgl(IYMZE0v1@mIE-!f&#&=-OkQYDr>tQ<+v6)$HM#NFm& z_8Jcp?zlQP)hR+*4#`t2E-omRha6?rbal6CF;B@}9i>R!U-`$-`kde>vizv5?9eKU zJLN|uAq$-V3XClR(oKu>uiPzMpj}%pj?FB@Gf7d0R(Yqc!sk%1h^LcN&aEylL+-J4 z-_XYnRa|d+*@$|7Z=L@A?djQOyY;mH_Oun=Z@)cjW7@BOiIWa8;)Q2Tzzz%Rf3>A4 z=oy=53}t#>J@i}>oSW&@__KcXB>zA9un`B94J|F>seI0-4;vLUn6kl{XU#P;I+qx!rVN8c}c~uiW07+ zTrn3Ft|Er+TaySVz_#7^!0<^{Q!-i(TT9}6w=qR#(zl^}gG;t;bv8Wb;H1NBVwO;s zv382O5=Ssf3~_Gdu0tM_NdapImF%Y_;Se*H?~ZX3uhA$*^1!t{!y~R3P;EP_Yh?{q zh#)3E?3Gc8t#xwZ%4l&EOP8%S0=l#OVC^G038MKB5<&NZ>iTQY9LFWbVzl-^nxNo` zNKOJokUsy0@&{c;1*`X;)~mFR+lp{9e1*Ec^zB{8 zv@6G7Ta2Zpf&Yaq2UG%pyR@tsl;A9u{zMFT3&1vLFQ33OT^hxp(Y(N}O&jfoM(W~;A0rGwN&!N~Cae8| zJoy}Tfll(qk0PIRjO}#;t$}qJCoC zAqsQq%PUl&TH-3Brx(s44}u?ejt=$@zVG`RYaex&HyfxYH*106)cj3LVidfd#! zDWIYrAXbEffu|mp+^xb2RDdr%hvne4rd)_)hg^Ffo9sEtIL+tV%f%DwLX)aZ=t5n} zF4n+`f;ChDde>N&W99jvO@9%eyUv9)s2o4w!%t{5Mr!dDAb`h{r>ZVSHs<% zSTYFejoC$O!bigxh$7koEwx8i z99o3s1Im^A1WkPjaq`fv6cJ90z1Gb>ZD8h&JwO$|NOY1Cs3$y6%GzMr7$P=F$hpAA z`-sS`Z(@Tg1zS_LRn=?~3txC${Ue31`uqry%2CnKrTJzz<$Pts5xw0VlBaz&?}J zU9@I|a$y01ZEb=x#KL)EmH(IO&Jr8idw5aEsaU6y&*K2mXnrdUe>#7 zA880T1%l6d0arxFQB+kI#rA@y6!_yV2Mq;77z6N~M6{UxQDXebSq~lroyCv%)#=pM>~Ybht3ZJg zK6?qu(B!=`gUm*iF%k^;77RRkP{`KTw;MAS+^U^)U=~xV`N5kM!)&A!wUOzASvHQD zrl}p=n~jxJZRG?t5V5ylND-=F=)3KD*``V8(u*|t@DzYs!r{sg`u=}Bs9kR@sq`2S zMH{O8#{($G?<}#76qfoH?%s{2qXnlVztrJ(1wlyUNsYdp!PKrj_cL;DE$7v+fD1;i z5W>9s8PQo2t66KK*7f>_kMy3f+ruZlas0lQ!uh)419ZA2R#3OJO;>S4+w^{f;pUvS zo15gFtG04LZ!Sns^PlL;>D2G`QoWTub1g)(o`S58R0kMJB2I=C%r&b!5 zpU}|nQ#Oy&_IWY>G`haP??pDn1WKQh9O_)o7a!WahVekjaduVIhx8*F?}qAg1NbYv zs^rbINR7;#2)N;%Fn}Kf4woxM>jXj4<2&rXNrs zj}`$)jJ2sjUJv!iT5Gu38W1j{yuZW@(o%85_+k2s|)2Ur(T{@>kd2(x?LD1N)fs{6>=#! z#`{hu9_nzAe>lHPM^I!%w4lcHWZCQ-t|3XQiRbAA8I0~;yVB+~nw^g$+?MyzbWx!= ze18eSz3o$Jr|^ySbk?a%NlR$9PY>UmoK+__NO`?c_G|<~KDkdy9u@{@xNO+4wM}lY zZfU~i1OREL+M{TXY4`g*;|&)m@mob?$u*+C<= zCv|z5Q9?cRA4hI-G4GaHcZ_**+{RX~gkA_`KhUrcD<`7Zx<)WHKq*F5>Gb+Hg1vj6 z34Ds|r}f_RPhanxoD7Z*YEZZ*I z8rafY%I8CtmMYOqcm317{iDI|$>GsYwYlzIM(G8`z|&MJ!=yRbqelaBomUuv~&e@>A$P9nkw10B{U% zTMfX;8r07ocbB+E8vXn;M&Ds>Q^oItOW~IvN!FeJ#?w+EE@5UcwZUgi%@wBm=+76Y zI%p=}=^Qtf8DPsU>6V$>(_B4|pR@CV$NsZ_dhq7ev%ygfj~q*2VwEtEjT%ivQk@k| z7KN-6qa0Nt)382Eb-hy(P2I@u>o+j<9P|45Uw`%l&6?XIIyEUwl;g ztI{{=th0bFDD*FTZj2>({jHaw|5ZPnFN(`M;R|h`N&}r$M|i@C$4zF|!q+u!ABbAk zsxhpr?&^`HS(jIWM%GpKtkn^A5AgdQ1>#?kuveLnXB zJnYE!pK%v9Iv3n&i~vkAU)=v_AjWVNr@0wJWMc(#$_d@Hy{6(V*Y$>UxbX``3{qWRn5-3HJu~oJ zFNVj1*E>f$z^Qx&MRB#+F#=1Rc(cx$7-MIWX5M*VPuD2zY?Mmv)lBU5&%vYWQK89oMl=0 z-w9>0B`yI(Z8#LfTd*4Efr~KIxbjO7BDZ!5HZX~8hM;VSl1GfJidrO%vJpc?66NJNn@nE#A=iSw*Nwb-E#L3 zB$sJ0OwKlVg@)xVw1J7HZQmg4I$m60iVTeV@vj~sw%+}a zBY@l)t}RcTJCitSB240#r|+BYK7A9bJRCaBk3}>V4V{kAeh>G*Sx zf+M1b`IR+L6Zq{1(ey9KOvQ^}#%K5`U*9|lM0{eBbtDq$Q& zPoio3_-`-yrweuoU@g^#d>#P+*Mze3h32|fQI7r{j935Gu+MayIee0?<*Qo1@PJlL zl|N$=XH7clm5XY-nu-u(srp(MMK{8#<=;~K!3OF>EEj4)EhMN|2=mVJF}E^{%V->x zk-Z9ay>`PK>nqTRujK8V<1sH;0#{av_5gEbU~Z(Rwt=M0UyxZ@z&Jbb8qu){ar70J zt5$_80ASFzL0nPaST@v+!D=XNpbxz(&V2&oOZiwAMGW&k&e-rj3(J^Ki0TA z)<}(aaWs|`=j7MEEEW=GVI&LYqS)0i7KGO=Lozt%uBqG!oAO&Wh&UGfJpb|2ME;ww`TXKOprnZe%B-(-qZ6-gd@rgIHg(&F* z=F7{o6al40p?eNrpV+=IAvrtqhE~m}j-9lT$lqZ`Xx2(?ieO>W1jwR1>6Fm!G9JB? zHc&Qtzam1y#Ks)&J;QJ3{KX3PVF@l;6!VhZdx-(r{_5r7&fX9uKoZGe%&!J}!{>vY zlQ&0$<2q=f8-cHzA`3D*#+`C0AiMu$BJFBtI?D}$#$XJ=@X>%US@)7`on0i@`v_lj zeA|SUp+*>^lazZ1Boxf~A_<%5&7?j+&dqfKrSgd?^52S9n3l0{Oc*R_v&#f0c` z?pZ9O2RBsKz_q2PXq8pfK03@z{T6MDUw1%re6Cf1HGyH z)>foGaK>Ci3XDx+#W8gTR||+#cQ%y|9o-5Yo~GS4)}XC>jjVjd{i4+*&VW7BGF7B2 zDs{LNP3%v9;)A1C^l8g{H6U{P`s`GlaSQPZa;ij@>pMODIdZ*y(iHOL@?j_(%@z}*Kpj}(R+qXzD^nx}!ceJE>GbM>t?Qp;*3NT$WX#XK; zT}ZpzD1tL=fjLMuGk)tEYN|}6zvG{dPX@07GQQU2h$&rjuCvW)&1kKGRtIU{{(wgs z4Ad(Ywe~dJSy<-nj~-SBY0>NEfZn-bbDiUXy3CLs5gMX>D?8AzY|0OVgEw+2Q56bV z>?4;XMWN#vcd72Ikg&0jS{}14A<|~jE7CRyg zmt8V>i=OVNAH9k(U8(IJ{eO@G{XZzvx2I$ADU@l462WFZ(CYPBYwy=m@hs;JEE4lO zFa-96EHkmwCiXN+ucZ-T>Tv8*y=!w=iaByv6QYKRij_vl>9~aEQ{Z!Rjzuy>1DR`c zu5OFK+2AX>A^E+6)_pCRpMi+ zCaZmN_#`5=tKEmiWim0mXNp1ZaJTflW-;2_xqjdi&eB2w@UnM{IZYG~r+kp`S_XC~ zz@AVGC2oV$oDS*jhSx(^WH;(}r3O(WtqNOp>)0@-bv(BHXVsTHW@Sagr^@(1S51yyK8;e(O#Zv~Aj5drBkCI9OdCVQ&ne|q@c)|dQG|NZ%& z>|9B{7+ag*Rpv7ERb~lbyNCZZ`01EVdBu%9d>3CA;YA+LTRn`=8Fl}81}J5ceE7r$ zpY6B*?6q|>C@Md0YKGKV#V{&c_f>c8aFHhe(AF8J7T>D`Z$!WihiEE09JY}QMkR;D z5IuhLn(~7V_H?&;2%)Fqco4l(0O{ZgMEsjdk;x~&CS;me#q#)P@gb(hlt)Lw?2CW@ ztDdMss>2!{4RBFc-amTt?5E-2;QRf90n@nF3-V{7 zRs(lqhGMjUcXEEO^>(MV_OW4fH*HLPKnSh>cD&iXmpIzxi3zu6VyzhsiPC~s6?k{J z0zZAK8JbpyUL!{h7{t?f_Q}V;5d>75wr}|FcI#;TkA~do?~?`mw*21@zNzN_`}*sL zU-EzdJLLZ+!RUqokPVhC@M$jm@+#vO$mth;Yxm_~=YS6N?#shx&jv?y!l4-~NK#X= zO6pT=fJJEIn(nge>(Gbsl;Ng%(LjQoL@uV)0hm}i&0L2=2)_UP2t&E%)K>> z6()g$PjV400l@}&q;B8_rrq>?8ZYkUW)#)A5T;8)Wk8acd;?TXQYzd6BSx7I@;nx^JF7ZI4-i zhH>DHkd`{%ItMVM1=JE-wJq>2DGRrWd5*qunAZ?3HvC08huw+CoUATv$|D(uJ=ShJ zsauL zz8b97eNLfTdE;l82;SDPbLdr*fP%h=ta*5mrD%q5rxm(O#j3%BV~$`7TSgDI{e*g* z$M1z_bwrJ}1%x6PU9*L1_oFDqu-rpAZBHx3&tWd_u-qwji6m!mW{fl3vN9-qS(8{V zv!@%9eszcz z)#EX?-uC-_H$C%daQ}Yq{=bkA#~D*1ODR5hw?9x%oIX&l7=`` z4A&E^Pl9%+LiP|jN-Z_1@KJ(#<9TTPj^0;vGALbMj1trcm7O`@pixTghk8$?BKj2H6_$>v%#B?cajviWt33GH@6mSFy3BH+J| z@&rd@QF-vn(04^X8nQh(n$a(*JOs9&1rO#TS0?DXdPtK{)Rum2r8KR!S#X;b4+_^# z#{#pF1FzEikN@2I=FxXO6!3L9k$IQH<8-r07a*|c z(rK6iyP>n&@6H#y43`b^W=pVVlt(}p@iWKh6%}p+PgX0V%s{rkR;P~2Q21A?l_t)~ zSZ38bvw1t6bT%$W!HSHfMzsYD#Go9x5&u&$aLRIv+tYKZ8&qQhR-Ie&Us{y6aCJf^ z>a7SF5nEzi>bPwvN>h}{d<@s*KYrZZfM)-^(eafi9)G>uKY(AGTb{i@8~OQ&1pgbA z9W%>9lH=DecTS!k9=$?heFH_%8&-~C+~D^~G{pDAob#PD*}D?8UyFOYA#rav&PRkA<`=V z>mi4khO=apXGJ!lAnv_5?JkNQa`s6Es7)M0;SDxcU}HT-u)R?-8_mYR_ZB^vau*&I zRq*tE5?^hb8r?_X1FsT)o3qTqWK1m94O7GKDl5dGI>+uV9?b)^Fe3}pp@R8Ebz zsgqvvtz%{L_1hHx7wDF-=f3jVbC=V{l3%-uBd%^5;K_u=C`wzsx8u!TTOtc%EVee> z3kapH{w7&0)?%sul9S;cZ4Bkz+UVi!(UUJ5ZBaN*NF2lwHEu+=tFIXtD4Kr!%E36O z5e=F)_zk)mbW{BM@+wSWU>gkI@qhi_I=S%V?}99=!_!6#_pYg*4iB>xoOiC z{~A+(rb1P*CnhDJiv8v#S~*4=L^jAwdqa0v2NVF4IGbSN1au1PtAfkuu|NMVVmQtJ zxkjtMDGPX;{O9Yfs{Z%eM-RUH!vFmn@_)+GUAu*e8MI_*^f%dhn6j8N`zAGBvMn?V zeby|4aSVy6U8^WLn4MtEQg}%&=1IEgIR@mGCG%apy`Xfv!sz_}EZ;WgznC&NmvDZ$ zKkWQ(J=)s(x_15_eX;-ex3K@fBjxWMzx0(Jy$BmL_oRAUpzeJbe<%a5hB#PqjO`?N z;N>%keCM3$y71RfPu20)P@@I^kOqDpjpB|Um!r`4G1?beB2ZJrAzx>U4Ro%0N8T>z zp+z<(*`h4aO^>4BWOJV!c>H1n7c=4|9?NrJ9wLLspeZ6Q3CT3LZo#l+&^UobnayD8 z=;Uziai)6GDUNNKH_TS>UAL?A&$H?gJJ99|Y=i-wC3DPeM5sS^dsla*eIVSi#j|yNg$?=BmXEt?fn*=oEAtJdoF>R#kf&3#?L=$EILvCN< z3yCKt=m(NVQ$%hI84>#j(>Zay8fgUfxHo-CHy-&I3~*|9gl8f3ck&!ch*KlC8``a@ z0dM*(-3F`wp}ziF;Ag8bwylw2ThlZPEEr&{Y_lvkPpf;z4yu+LDEL~Uz{m{agrK;% zo}FVNES>&F5(K$z?^s#E^|VaOeWx(PiBYDnU!B_8bV;vEb~h70xGZPWK)+TLePhR| zJG1Dv5%kfTigN3o_C>IChLGAXV*o8m_C$*%k!sdN6cL8u((#;RqIWYrb76tK__ARNJi<+j-1{gx1Oyb5lK=Z6XBUv{emY<|LHJi#N z@=9kDfRRIy`)O9*_b(Pu0EjoCnrkgdGZe|nN>V}=VFZ|2j*NPXqX%FB<8x9=Xi6Hf zeyZYMaa#GLY_A4cfU7#Ui@^6cwTw)J-nfl0_e6X@%OhqS{41s!NWk6{eDTKO_n)VJ<)m?8a?{sjJX! z@iMZ_U1Gh^DV}9B{vajK$-up&n68p?{Fm*rmJ>AC!JWxY zzA%Ojb?Q^*K)cM&QTz$*-2%vBZ^7#rJE5^DFwHnAMo~Uiu{TsxRta?EmTZ@gF^Sd_ zYPoyzxJOTZ3teI|!$&IK2D20b_sl+ZcFjFq6YC)NpF0C<-$s|Ph4F$<=$jOf<_R3V zB5;o-9!In;rZ@#>4d;^ND_E*naYC`PmOZ$J?Q-CB8j*LQu7C;b%~N&b_Bo~&xfDe? zS`KOvP(iX~WX7FnCA23Ttx(z+Mw2qmhmM?@rPqZ{?gT`v1Y<;50CE4*?5fZis@EhY z3VXv4+Xs6J^NJ&6#jh#cvqFkol%lRtcstzS>sW0(wXCi#H`0nI&CxjqMLR6isa!

_+kG)0`f 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

I*-fW7U~MOFJFAV=OmQJuYG7S~r8U3WF9)Bdg< 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 literal 0 HcmV?d00001 diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem new file mode 100644 index 0000000000000000000000000000000000000000..98f9a48ce6d1b1fd431f8bedcfa2523ea334a9d7 GIT binary patch literal 167936 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

&;l`z>!7E|X9z1!;PcuK-hsOJ+Sf(SV*zoZ$ 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¥p_>;3bGvV3bou|^wDuS8fw>; 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 E1={BUjsO4v literal 0 HcmV?d00001 diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.7.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.7.gem new file mode 100644 index 0000000000000000000000000000000000000000..ce97509006fd3d0129e90188bbd809b299cb62e9 GIT binary patch literal 82944 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%0A+kzZ`jm9WrmLHQ1f=7M%fxS-o>;Rw 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 nIeQ1}r7wP literal 0 HcmV?d00001 diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem new file mode 100644 index 0000000000000000000000000000000000000000..a60935045757b8694c9a7e9298f67513c2b112bf GIT binary patch literal 40960 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

-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 1.9`. + + Resolves [#63][issue-63]. + +## 1.4.2 / 2020-06-23 + +- Camille Drapier fixed a small issue with RuboCop configuration. [#59][pull-59] + +- Applied another fix (and unit test) to fix an issue for the Chef team. + [#60][issue-60], [#61][pull-61] + +## 1.4.1 / 2020-06-23 + +- Fix an issue where diff sizes could be negative, and they should be. + [#57][issue-57], [#58][pull-58] + +## 1.4 / 2020-06-23 + +- Ruby versions lower than 2.4 are soft-deprecated and will not be run as part + of the CI process any longer. + +- Akinora MUSHA (knu) added the ability for `Diff::LCS::Change` objects to be + implicitly treated arrays. Originally provided as pull request [#47][pull-47], + but it introduced a number of test failures as documented in [#48][issue-48], + and remediation of `Diff::LCS` itself was introduced in [#49][pull-49]. + +- Resolved [#5][issue-05] with some tests comparing output from `system` calls + to `bin/ldiff` with some pre-generated output. Resolved [#6][issue-06] with + these tests. + +- Resolved a previously undetected `bin/ldiff` issue with `--context` output not + matching `diff --context` output. + +- Resolved an issue with later versions of Ruby not working with an `OptParse` + specification of `Numeric`; this has been changed to `Integer`. + +- Brandon Fish added TruffleRuby in [#52][pull-52]. + +- Fixed two missing classes as reported in [#53][issue-53]. + +## 1.3 / 2017-01-18 + +- Bugs fixed: + + - Fixed an error for `bin/ldiff --version`. Fixes issue [#21][issue-21]. + + - Force `Diff::LCS::Change` and `Diff::LCS::ContextChange` to only perform + equality comparisons against themselves. Provided by Kevin Mook in pull + request [#29][pull-29]. + + - Fix tab expansion in `htmldiff`, provided by Mark Friedgan in pull request + [#25][pull-25]. + + - Silence Ruby 2.4 `Fixnum` deprecation warnings. Fixes issue [#38][issue-38] + and pull request [#36][pull-36]. + + - Ensure that test dependencies are loaded properly. Fixes issue + [#33][issue-33] and pull request [#34][pull-34]. + + - Fix issue [#1][issue-01] with incorrect intuition of patch direction. + Tentative fix, but the previous failure cases pass now. + +- Tooling changes: + + - Added SimpleCov and Coveralls support. + + - Change the homepage (temporarily) to the GitHub repo. + + - Updated testing and gem infrastructure. + + - Modernized the specs. + +- Cleaned up documentation. + +- Added a Code of Conduct. + +## 1.2.5 / 2013-11-08 + +- Bugs fixed: + + - Comparing arrays flattened them too far, especially with `Diff::LCS.sdiff`. + Fixed by Josh Bronson in pull request [#23][pull-23]. + +## 1.2.4 / 2013-04-20 + +- Bugs fixed: + + - A bug was introduced after 1.1.3 when pruning common sequences at the start + of comparison. Paul Kunysch (@pck) fixed this in pull request + [#18][pull-18]. Thanks! + + - The Rubinius (1.9 mode) bug in [rubinius/rubinius#2268][rubinius#2268] has + been fixed by the Rubinius team two days after it was filed. Thanks for + fixing this so quickly! + +- Switching to Raggi's hoe-gemspec2 for gemspec generation. + +## 1.2.3 / 2013-04-11 + +- Bugs Fixed: + + - The new encoding detection for diff output generation (added in 1.2.2) + introduced a bug if the left side of the comparison was the empty set. + Originally found in [rspec/rspec-expectations#238][rspec-expectations#238] + and [rspec/rspec-expectations#239][rspec-expectations#239]. Jon Rowe + developed a reasonable heuristic (left side, right side, empty string + literal) to avoid this bug. + + - There is a known issue with Rubinius in 1.9 mode reported in + [rubinius/rubinius#2268][rubinius#2268] and demonstrated in the Travis CI + builds. For all other tested platforms, diff-lcs is considered stable. As + soon as a suitably small test-case can be created for the Rubinius team to + examine, this will be added to the Rubinius issue around this. + +## 1.2.2 / 2013-03-30 + +- Bugs Fixed: + + - `Diff::LCS::Hunk` could not properly generate a difference for comparison + sets that are not US-ASCII-compatible because of the use of literal regular + expressions and strings. Jon Rowe found this in + [rspec/rspec-expectations#219][rspec-expectations#219] and provided a first + pass implementation in pull request [#15][pull-15]. I've reworked it because + of test failures in Rubinius when running in Ruby 1.9 mode. This coerces the + added values to the encoding of the old dataset (as determined by the first + piece of the old dataset). + + - Adding Travis CI testing for Ruby 2.0. + +## 1.2.1 / 2013-02-09 + +- Bugs Fixed: + + - As seen in [rspec/rspec-expectations#200][rspec-expectations#200], the + release of `Diff::LCS` 1.2 introduced an unnecessary public API change to + `Diff::LCS::Hunk` (see the change at + [rspec/rspec-expectations@3d6fc82c][rspec-expectations@3d6fc82c] for + details). The new method name (and behaviour) is more correct, but I should + not have renamed the function or should have at least provided an alias. + This release restores `Diff::LCS::Hunk#unshift` as an alias to #merge. Note + that the old `#unshift` behaviour was incorrect and will not be restored. + +## 1.2.0 / 2013-01-21 + +- Minor Enhancements: + + - Added special case handling for `Diff::LCS.patch` so that it handles patches + that are empty or contain no changes. + + - Added two new methods (`#patch_me` and `#unpatch_me`) to the include-able + module. + +- Bugs Fixed: + + - Fixed issue [#1][issue-01] patch direction detection. + + - Resolved issue [#2][issue-02] by handling `string[string.size, 1]` properly + (it returns `""` not `nil`). + + - Michael Granger (ged) fixed an implementation error in `Diff::LCS::Change` + and added specs in pull request [#8][pull-08]. Thanks! + + - Made the code auto-testable. + + - Vít Ondruch (voxik) provided the latest version of the GPL2 license file in + pull request [#10][pull-10]. Thanks! + + - Fixed a documentation issue with the include-able versions of `#patch!` and + `#unpatch!` where they implied that they would replace the original value. + Given that `Diff::LCS.patch` always returns a copy, the documentation was + incorrect and has been corrected. To provide the behaviour that was + originally documented, two new methods were added to provide this behaviour. + Found by scooter-dangle in issue [#12][issue-12]. Thanks! + +- Code Style Changes: + + - Removed trailing spaces. + + - Calling class methods using `.` instead of `::`. + + - Vít Ondruch (voxik) removed unnecessary shebangs in pull request + [#9][pull-09]. Thanks! + + - Kenichi Kamiya (kachick) removed some warnings of an unused variable in + lucky pull request [#13][pull-13]. Thanks! + + - Embarked on a major refactoring to make the files a little more manageable + and understand the code on a deeper level. + + - Adding CI via Travis CI. + +## 1.1.3 / 2011-08-27 + +- Converted to 'hoe' for release. + +- Converted tests to RSpec 2. + +- Extracted the body of `htmldiff` into a class available from + `diff/lcs/htmldiff`. + +- Migrated development and issue tracking to GitHub. + +- Bugs fixed: + + - Eliminated the explicit use of RubyGems in both `bin/htmldiff` and + `bin/ldiff`. Resolves issue [#4][issue-04]. + + - Eliminated Ruby warnings. Resolves issue [#3][issue-03]. + +## 1.1.2 / 2004-10-20 + +- Fixed a problem reported by Mauricio Fernandez in `htmldiff`. + +## 1.1.1 / 2004-09-25 + +- Fixed bug #891 (Set returned from patch command does not contain last equal + part). + +- Fixed a problem with callback initialisation code (it assumed that all + callbacks passed as classes can be initialised; now, it rescues NoMethodError + in the event of private :new being called). + +- Modified the non-initialisable callbacks to have a private `#new` method. + +- Moved `ldiff` core code to `Diff::LCS::Ldiff` (`diff/lcs/ldiff.rb`). + +## 1.1.0 + +- Eliminated the need for `Diff::LCS::Event` and removed it. + +- Added a contextual diff callback, `Diff::LCS::ContextDiffCallback`. + +- Implemented (un-)patching for standard diff callback output formats with both + `#diff` and `#sdiff`. + +- Extensive documentation changes. + +## 1.0.4 + +- Fixed a problem with `bin/ldiff` output, especially for unified format. + Newlines that should have been present weren't. + +- Changed the `.tar.gz` installer to generate Windows batch files if ones do not + exist already. Removed the existing batch files as they didn't work. + +## 1.0.3 + +- Fixed a problem with `#traverse_sequences` where the first difference from the + left sequence might not be appropriately captured. + +## 1.0.2 + +- Fixed an issue with `ldiff` not working because actions were changed from + symbols to strings. + +## 1.0.1 + +- Minor modifications to the `gemspec`, the `README`. + +- Renamed the diff program to `ldiff` (as well as the companion batch file) so + as to not collide with the standard diff program. + +- Fixed issues with RubyGems. Requires RubyGems > 0.6.1 or >= 0.6.1 with the + latest CVS version. + +## 1.0 + +- Initial release based mostly on Perl's Algorithm::Diff. + +[age]: https://github.com/FiloSottile/age +[hoe-halostatue]: https://github.com/halostatue/hoe-halostatue +[hoe-markdown]: https://github.com/flavorjones/hoe-markdown +[issue-01]: https://github.com/halostatue/diff-lcs/issues/1 +[issue-02]: https://github.com/halostatue/diff-lcs/issues/2 +[issue-03]: https://github.com/halostatue/diff-lcs/issues/3 +[issue-04]: https://github.com/halostatue/diff-lcs/issues/4 +[issue-05]: https://github.com/halostatue/diff-lcs/issues/5 +[issue-06]: https://github.com/halostatue/diff-lcs/issues/6 +[issue-12]: https://github.com/halostatue/diff-lcs/issues/12 +[issue-21]: https://github.com/halostatue/diff-lcs/issues/21 +[issue-33]: https://github.com/halostatue/diff-lcs/issues/33 +[issue-35]: https://github.com/halostatue/diff-lcs/issues/35 +[issue-38]: https://github.com/halostatue/diff-lcs/issues/38 +[issue-43]: https://github.com/halostatue/diff-lcs/issues/43 +[issue-44]: https://github.com/halostatue/diff-lcs/issues/44 +[issue-46]: https://github.com/halostatue/diff-lcs/issues/46 +[issue-48]: https://github.com/halostatue/diff-lcs/issues/48 +[issue-53]: https://github.com/halostatue/diff-lcs/issues/53 +[issue-57]: https://github.com/halostatue/diff-lcs/issues/57 +[issue-60]: https://github.com/halostatue/diff-lcs/issues/60 +[issue-63]: https://github.com/halostatue/diff-lcs/issues/63 +[issue-65]: https://github.com/halostatue/diff-lcs/issues/65 +[issue-70]: https://github.com/halostatue/diff-lcs/issues/70 +[issue-91]: https://github.com/halostatue/diff-lcs/issues/91 +[issue-95]: https://github.com/halostatue/diff-lcs/issues/95 +[issue-100]: https://github.com/halostatue/diff-lcs/issues/100 +[issue-102]: https://github.com/halostatue/diff-lcs/issues/102 +[issue-106]: https://github.com/halostatue/diff-lcs/issues/106 +[issue-107]: https://github.com/halostatue/diff-lcs/issues/107 +[pull-08]: https://github.com/halostatue/diff-lcs/pull/8 +[pull-09]: https://github.com/halostatue/diff-lcs/pull/9 +[pull-10]: https://github.com/halostatue/diff-lcs/pull/10 +[pull-13]: https://github.com/halostatue/diff-lcs/pull/13 +[pull-15]: https://github.com/halostatue/diff-lcs/pull/15 +[pull-18]: https://github.com/halostatue/diff-lcs/pull/18 +[pull-23]: https://github.com/halostatue/diff-lcs/pull/23 +[pull-25]: https://github.com/halostatue/diff-lcs/pull/25 +[pull-29]: https://github.com/halostatue/diff-lcs/pull/29 +[pull-34]: https://github.com/halostatue/diff-lcs/pull/34 +[pull-36]: https://github.com/halostatue/diff-lcs/pull/36 +[pull-47]: https://github.com/halostatue/diff-lcs/pull/47 +[pull-49]: https://github.com/halostatue/diff-lcs/pull/49 +[pull-52]: https://github.com/halostatue/diff-lcs/pull/52 +[pull-58]: https://github.com/halostatue/diff-lcs/pull/58 +[pull-59]: https://github.com/halostatue/diff-lcs/pull/59 +[pull-61]: https://github.com/halostatue/diff-lcs/pull/61 +[pull-69]: https://github.com/halostatue/diff-lcs/pull/69 +[pull-71]: https://github.com/halostatue/diff-lcs/pull/71 +[pull-72]: https://github.com/halostatue/diff-lcs/pull/72 +[pull-73]: https://github.com/halostatue/diff-lcs/pull/73 +[pull-75]: https://github.com/halostatue/diff-lcs/pull/75 +[pull-79]: https://github.com/halostatue/diff-lcs/pull/79 +[pull-80]: https://github.com/halostatue/diff-lcs/pull/80 +[pull-82]: https://github.com/halostatue/diff-lcs/pull/82 +[pull-84]: https://github.com/halostatue/diff-lcs/pull/84 +[pull-86]: https://github.com/halostatue/diff-lcs/pull/86 +[pull-89]: https://github.com/halostatue/diff-lcs/pull/89 +[pull-90]: https://github.com/halostatue/diff-lcs/pull/90 +[pull-92]: https://github.com/halostatue/diff-lcs/pull/92 +[pull-93]: https://github.com/halostatue/diff-lcs/pull/93 +[pull-101]: https://github.com/halostatue/diff-lcs/pull/101 +[pull-103]: https://github.com/halostatue/diff-lcs/pull/103 +[pull-104]: https://github.com/halostatue/diff-lcs/pull/104 +[pull-105]: https://github.com/halostatue/diff-lcs/pull/105 +[pull-129]: https://github.com/halostatue/diff-lcs/pull/129 +[pull-147]: https://github.com/halostatue/diff-lcs/pull/147 +[pull-148]: https://github.com/halostatue/diff-lcs/pull/148 +[rspec-expectations#200]: https://github.com/rspec/rspec-expectations/pull/200 +[rspec-expectations#219]: https://github.com/rspec/rspec-expectations/issues/219 +[rspec-expectations#238]: https://github.com/rspec/rspec-expectations/issues/238 +[rspec-expectations#239]: https://github.com/rspec/rspec-expectations/issues/239 +[rspec-expectations@3d6fc82c]: https://github.com/rspec/rspec-expectations/commit/3d6fc82c +[rubinius#2268]: https://github.com/rubinius/rubinius/issues/2268 +[standard ruby]: https://github.com/standardrb/standard +[tidelift]: https://tidelift.com/security +[tp]: https://guides.rubygems.org/trusted-publishing/ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..184b5fb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at [INSERT CONTACT +METHOD]. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +. Translations are available at +. + +[homepage]: https://www.contributor-covenant.org +[Mozilla CoC]: https://github.com/mozilla/diversity diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md new file mode 100644 index 0000000..4bcde4b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# Contributing + +Contribution to diff-lcs is encouraged in any form: a bug report, a feature +request, or code contributions. There are a few DOs and DON'Ts for +contributions. + +- DO: + + - Keep the coding style that already exists for any updated Ruby code (support + or otherwise). I use [Standard Ruby][standardrb] for linting and formatting. + + - Use thoughtfully-named topic branches for contributions. Rebase your commits + into logical chunks as necessary. + + - Use [quality commit messages][qcm]. + + - Add your name or GitHub handle to `CONTRIBUTORS.md` and a record in the + `CHANGELOG.md` as a separate commit from your main change. (Follow the style + in the `CHANGELOG.md` and provide a link to your PR.) + + - Add or update tests as appropriate for your change. The test suite is + written in [RSpec][rspec]. + + - Add or update documentation as appropriate for your change. The + documentation is RDoc; diff-lcs does not use extensions that may be present + in alternative documentation generators. + +- DO NOT: + + - Modify `VERSION` in `lib/diff/lcs/version.rb`. When your patch is accepted + and a release is made, the version will be updated at that point. + + - Modify `diff-lcs.gemspec`; it is a generated file. (You _may_ use + `rake gemspec` to regenerate it if your change involves metadata related to + gem itself). + + - Modify the `Gemfile`. + +## Test Dependencies + +diff-lcs uses Ryan Davis's [Hoe][Hoe] to manage the release process, and it adds +a number of rake tasks. You will mostly be interested in `rake`, which runs +tests in the same way that `rake spec` does. + +To assist with the installation of the development dependencies for diff-lcs, I +have provided a Gemfile pointing to the (generated) `diff-lcs.gemspec` file. +`minitar.gemspec` file. This will permit you to use `bundle install` to install +the dependencies. + +You can run tests with code coverage analysis by running `rake spec:coverage`. + +## Workflow + +Here's the most direct way to get your work merged into the project: + +- Fork the project. +- Clone your fork (`git clone git://github.com//diff-lcs.git`). +- Create a topic branch to contain your change + (`git checkout -b my_awesome_feature`). +- Hack away, add tests. Not necessarily in that order. +- Make sure everything still passes by running `rake`. +- If necessary, rebase your commits into logical chunks, without errors. +- Push the branch up (`git push origin my_awesome_feature`). +- Create a pull request against halostatue/diff-lcs and describe what your + change does and the why you think it should be merged. + +[hoe]: https://github.com/seattlerb/hoe +[qcm]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html +[release-gem]: https://github.com/rubygems/release-gem +[rspec]: http://rspec.info/documentation/ +[standardrb]: https://github.com/standardrb/standard diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md new file mode 100644 index 0000000..9053019 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md @@ -0,0 +1,49 @@ +# Contributors + +- Austin Ziegler (@halostatue) created diff-lcs. + +Thanks to everyone else who has contributed to diff-lcs over the years: + +- @ginriki +- @joshbronson +- @kevinmook +- @mckaz +- Akinori Musha +- Artem Ignatyev +- Brandon Fish +- Baptiste Courtois (@annih) +- Camille Drapier +- Cédric Boutillier +- @earlopain +- Gregg Kellogg +- Jagdeep Singh +- Jason Gladish +- Jon Rowe +- Josef Strzibny +- Josep (@apuratepp) +- Josh Bronson +- Jun Aruga +- Justin Steele +- Kenichi Kamiya +- Kensuke Nagae +- Kevin Ansfield +- Koichi Ito +- Mark Friedgan +- Masato Nakamura +- Mark Young +- Michael Granger +- Myron Marston +- Nicolas Leger +- Oleg Orlov +- Patrick Linnane +- Paul Kunysch +- Pete Higgins +- Peter Goldstein +- Peter Wagenet +- Philippe Lafoucrière +- Ryan Lovelett +- Scott Steele +- Simon Courtois +- Tien (@tiendo1011) +- Tomas Jura +- Vít Ondruch diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md new file mode 100644 index 0000000..c57c3f1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md @@ -0,0 +1,40 @@ +# Licence + +This software is available under three licenses: the GNU GPL version 2 (or at +your option, a later version), the Perl Artistic license, or the MIT license. +Note that my preference for licensing is the MIT license, but Algorithm::Diff +was dually originally licensed with the Perl Artistic and the GNU GPL ("the same +terms as Perl itself") and given that the Ruby implementation originally hewed +pretty closely to the Perl version, I must maintain the additional licensing +terms. + +- Copyright 2004–2025 Austin Ziegler and contributors. +- Adapted from Algorithm::Diff (Perl) by Ned Konz and a Smalltalk version by + Mario I. Wolczko. + +## MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Perl Artistic License + +See the file docs/artistic.txt in the main distribution. + +## GNU GPL version 2 + +See the file docs/COPYING.txt in the main distribution. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt new file mode 100644 index 0000000..fe58c86 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt @@ -0,0 +1,115 @@ +.rspec +CHANGELOG.md +CODE_OF_CONDUCT.md +CONTRIBUTING.md +CONTRIBUTORS.md +LICENCE.md +Manifest.txt +README.md +Rakefile +SECURITY.md +bin/htmldiff +bin/ldiff +docs/COPYING.txt +docs/artistic.txt +lib/diff-lcs.rb +lib/diff/lcs.rb +lib/diff/lcs/array.rb +lib/diff/lcs/backports.rb +lib/diff/lcs/block.rb +lib/diff/lcs/callbacks.rb +lib/diff/lcs/change.rb +lib/diff/lcs/htmldiff.rb +lib/diff/lcs/hunk.rb +lib/diff/lcs/internals.rb +lib/diff/lcs/ldiff.rb +lib/diff/lcs/string.rb +lib/diff/lcs/version.rb +mise.toml +spec/change_spec.rb +spec/diff_spec.rb +spec/fixtures/123_x +spec/fixtures/456_x +spec/fixtures/aX +spec/fixtures/bXaX +spec/fixtures/ds1.csv +spec/fixtures/ds2.csv +spec/fixtures/empty +spec/fixtures/file1.bin +spec/fixtures/file2.bin +spec/fixtures/four_lines +spec/fixtures/four_lines_with_missing_new_line +spec/fixtures/ldiff/diff.missing_new_line1-e +spec/fixtures/ldiff/diff.missing_new_line1-f +spec/fixtures/ldiff/diff.missing_new_line2-e +spec/fixtures/ldiff/diff.missing_new_line2-f +spec/fixtures/ldiff/error.diff.chef-e +spec/fixtures/ldiff/error.diff.chef-f +spec/fixtures/ldiff/error.diff.missing_new_line1-e +spec/fixtures/ldiff/error.diff.missing_new_line1-f +spec/fixtures/ldiff/error.diff.missing_new_line2-e +spec/fixtures/ldiff/error.diff.missing_new_line2-f +spec/fixtures/ldiff/output.diff +spec/fixtures/ldiff/output.diff-c +spec/fixtures/ldiff/output.diff-e +spec/fixtures/ldiff/output.diff-f +spec/fixtures/ldiff/output.diff-u +spec/fixtures/ldiff/output.diff.bin1 +spec/fixtures/ldiff/output.diff.bin1-c +spec/fixtures/ldiff/output.diff.bin1-e +spec/fixtures/ldiff/output.diff.bin1-f +spec/fixtures/ldiff/output.diff.bin1-u +spec/fixtures/ldiff/output.diff.bin2 +spec/fixtures/ldiff/output.diff.bin2-c +spec/fixtures/ldiff/output.diff.bin2-e +spec/fixtures/ldiff/output.diff.bin2-f +spec/fixtures/ldiff/output.diff.bin2-u +spec/fixtures/ldiff/output.diff.chef +spec/fixtures/ldiff/output.diff.chef-c +spec/fixtures/ldiff/output.diff.chef-e +spec/fixtures/ldiff/output.diff.chef-f +spec/fixtures/ldiff/output.diff.chef-u +spec/fixtures/ldiff/output.diff.chef2 +spec/fixtures/ldiff/output.diff.chef2-c +spec/fixtures/ldiff/output.diff.chef2-d +spec/fixtures/ldiff/output.diff.chef2-e +spec/fixtures/ldiff/output.diff.chef2-f +spec/fixtures/ldiff/output.diff.chef2-u +spec/fixtures/ldiff/output.diff.empty.vs.four_lines +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +spec/fixtures/ldiff/output.diff.four_lines.vs.empty +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +spec/fixtures/ldiff/output.diff.issue95_trailing_context +spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +spec/fixtures/ldiff/output.diff.issue95_trailing_context-e +spec/fixtures/ldiff/output.diff.issue95_trailing_context-f +spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +spec/fixtures/ldiff/output.diff.missing_new_line1 +spec/fixtures/ldiff/output.diff.missing_new_line1-c +spec/fixtures/ldiff/output.diff.missing_new_line1-e +spec/fixtures/ldiff/output.diff.missing_new_line1-f +spec/fixtures/ldiff/output.diff.missing_new_line1-u +spec/fixtures/ldiff/output.diff.missing_new_line2 +spec/fixtures/ldiff/output.diff.missing_new_line2-c +spec/fixtures/ldiff/output.diff.missing_new_line2-e +spec/fixtures/ldiff/output.diff.missing_new_line2-f +spec/fixtures/ldiff/output.diff.missing_new_line2-u +spec/fixtures/new-chef +spec/fixtures/new-chef2 +spec/fixtures/old-chef +spec/fixtures/old-chef2 +spec/hunk_spec.rb +spec/issues_spec.rb +spec/lcs_spec.rb +spec/ldiff_spec.rb +spec/patch_spec.rb +spec/sdiff_spec.rb +spec/spec_helper.rb +spec/traverse_balanced_spec.rb +spec/traverse_sequences_spec.rb diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md new file mode 100644 index 0000000..6583803 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md @@ -0,0 +1,92 @@ +# Diff::LCS + +- home :: https://github.com/halostatue/diff-lcs +- changelog :: https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md +- code :: https://github.com/halostatue/diff-lcs +- bugs :: https://github.com/halostatue/diff-lcs/issues +- rdoc :: http://rubydoc.info/github/halostatue/diff-lcs + + + + + +## Description + +Diff::LCS computes the difference between two Enumerable sequences using the +McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities +to create a simple HTML diff output format and a standard diff-like tool. + +This is release 1.6.1, providing a simple extension that allows for +Diff::LCS::Change objects to be treated implicitly as arrays and fixes a number +of formatting issues. + +Ruby versions below 2.5 are soft-deprecated, which means that older versions are +no longer part of the CI test suite. If any changes have been introduced that +break those versions, bug reports and patches will be accepted, but it will be +up to the reporter to verify any fixes prior to release. The next major release +will completely break compatibility. + +## Synopsis + +Using this module is quite simple. By default, Diff::LCS does not extend objects +with the Diff::LCS interface, but will be called as if it were a function: + +```ruby +require 'diff/lcs' + +seq1 = %w(a b c e h j l m n p) +seq2 = %w(b c d e f j k l m r s t) + +lcs = Diff::LCS.LCS(seq1, seq2) +diffs = Diff::LCS.diff(seq1, seq2) +sdiff = Diff::LCS.sdiff(seq1, seq2) +seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj) +bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj) +seq2 == Diff::LCS.patch!(seq1, diffs) +seq1 == Diff::LCS.unpatch!(seq2, diffs) +seq2 == Diff::LCS.patch!(seq1, sdiff) +seq1 == Diff::LCS.unpatch!(seq2, sdiff) +``` + +Objects can be extended with Diff::LCS: + +```ruby +seq1.extend(Diff::LCS) +lcs = seq1.lcs(seq2) +diffs = seq1.diff(seq2) +sdiff = seq1.sdiff(seq2) +seq = seq1.traverse_sequences(seq2, callback_obj) +bal = seq1.traverse_balanced(seq2, callback_obj) +seq2 == seq1.patch!(diffs) +seq1 == seq2.unpatch!(diffs) +seq2 == seq1.patch!(sdiff) +seq1 == seq2.unpatch!(sdiff) +``` + +By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will be +extended for use this way. + +Note that Diff::LCS requires a sequenced enumerable container, which means that +the order of enumeration is both predictable and consistent for the same set of +data. While it is theoretically possible to generate a diff for an unordered +hash, it will only be meaningful if the enumeration of the hashes is consistent. +In general, this will mean that containers that behave like String or Array will +perform best. + +## History + +Diff::LCS is a port of Perl's Algorithm::Diff that uses the McIlroy-Hunt longest +common subsequence (LCS) algorithm to compute intelligent differences between +two sequenced enumerable containers. The implementation is based on Mario I. +Wolczko's [Smalltalk version 1.2][smalltalk] (1993) and Ned Konz's Perl version +[Algorithm::Diff 1.15][perl]. `Diff::LCS#sdiff` and +`Diff::LCS#traverse_balanced` were originally written for the Perl version by +Mike Schilli. + +The algorithm is described in A Fast Algorithm for Computing Longest Common +Subsequences, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor +improvements to improve the speed. A simplified description of the algorithm, +originally written for the Perl version, was written by Mark-Jason Dominus. + +[smalltalk]: ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st +[perl]: http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile new file mode 100644 index 0000000..0bfe927 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile @@ -0,0 +1,115 @@ +require "rubygems" +require "rspec" +require "rspec/core/rake_task" +require "hoe" +require "rake/clean" + +MAINTENANCE = ENV["MAINTENANCE"] == "true" +BUILD_DOCS = MAINTENANCE || ENV["DOCS"] == "true" +TRUSTED_RELEASE = ENV["rubygems_release_gem"] == "true" + +Hoe.plugin :halostatue +Hoe.plugin :rubygems + +Hoe.plugins.delete :debug +Hoe.plugins.delete :newb +Hoe.plugins.delete :signing +Hoe.plugins.delete :publish unless BUILD_DOCS + +if RUBY_VERSION < "1.9" + class Array # :nodoc: + def to_h + Hash[*flatten(1)] + end + end + + class Gem::Specification # :nodoc: + def metadata=(*) + end + + def default_value(*) + end + end + + class Object # :nodoc: + def caller_locations(*) + [] + end + end +end + +_spec = Hoe.spec "diff-lcs" do + developer("Austin Ziegler", "halostatue@gmail.com") + + self.trusted_release = TRUSTED_RELEASE + + require_ruby_version ">= 1.8" + + self.history_file = "CHANGELOG.md" + self.readme_file = "README.md" + self.licenses = ["MIT", "Artistic-1.0-Perl", "GPL-2.0-or-later"] + + spec_extras[:metadata] = ->(val) { + val["rubygems_mfa_required"] = "true" + } + + extra_dev_deps << ["hoe", "~> 4.0"] + extra_dev_deps << ["hoe-halostatue", "~> 2.0"] + extra_dev_deps << ["hoe-rubygems", "~> 1.0"] + extra_dev_deps << ["rspec", ">= 2.0", "< 4"] + extra_dev_deps << ["rake", ">= 10.0", "< 14"] + extra_dev_deps << ["rdoc", ">= 6.3.1", "< 7"] +end + +if BUILD_DOCS + rake_tasks = Rake.application.instance_variable_get(:@tasks) + tasks = ["publish_docs", "publish_on_announce", "debug_email", "post_blog", "announce"] + tasks.each do |task| + rake_tasks.delete(task) + end +end + +desc "Run all specifications" +RSpec::Core::RakeTask.new(:spec) do |t| + rspec_dirs = %w[spec lib].join(":") + t.rspec_opts = ["-I#{rspec_dirs}"] +end + +task :version do + require "diff/lcs/version" + puts Diff::LCS::VERSION +end + +Rake::Task["spec"].actions.uniq! { |a| a.source_location } + +# standard:disable Style/HashSyntax +task :default => :spec unless Rake::Task["default"].prereqs.include?("spec") +task :test => :spec unless Rake::Task["test"].prereqs.include?("spec") +# standard:enable Style/HashSyntax + +if RUBY_VERSION >= "3.0" && RUBY_ENGINE == "ruby" + namespace :spec do + desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed." + task :coverage do + ENV["COVERAGE"] = "true" + Rake::Task["spec"].execute + end + end +end + +if MAINTENANCE + task ruby18: :package do + require "diff/lcs/version" + # standard:disable Layout/HeredocIndentation + puts <<-MESSAGE +You are starting a barebones Ruby 1.8 docker environment for testing. +A snapshot package has been built, so install it with: + + cd diff-lcs + gem install pkg/diff-lcs-#{Diff::LCS::VERSION} + + MESSAGE + # standard:enable Layout/HeredocIndentation + sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md new file mode 100644 index 0000000..16854f6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md @@ -0,0 +1,41 @@ +# diff-lcs Security + +## Supported Versions + +Security reports are accepted for the most recent major release and the previous +version for a limited time after the initial major release version. After a +major release, the previous version will receive full support for six months and +security support for an additional six months (for a total of twelve months). + +Because diff-lcs 1.x supports a wide range of Ruby versions, security reports +will only be accepted when they can be demonstrated on Ruby 3.1 or higher. + +> [!information] +> +> There will be a diff-lcs 2.0 released in 2025 which narrows support to modern +> versions of Ruby only. +> +> | Release Date | Support Ends | Security Support Ends | +> | ------------ | ------------ | --------------------- | +> | 2025 | +6 months | +12 months | +> +> If the 2.0.0 release happens on 2025-07-01, regular support for diff-lcs 1.x +> will end on 2026-12-31 and security support for diff-lcs 1.x will end on +> 2026-06-30. + +## Reporting a Vulnerability + +By preference, use the [Tidelift security contact][tidelift]. Tidelift will +coordinate the fix and disclosure. + +Alternatively, Send an email to [diff-lcs@halostatue.ca][email] with the text +`Diff::LCS` in the subject. Emails sent to this address should be encrypted +using [age][age] with the following public key: + +``` +age1fc6ngxmn02m62fej5cl30lrvwmxn4k3q2atqu53aatekmnqfwumqj4g93w +``` + +[tidelift]: https://tidelift.com/security +[email]: mailto:diff-lcs@halostatue.ca +[age]: https://github.com/FiloSottile/age diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff new file mode 100755 index 0000000..bcd89d2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff @@ -0,0 +1,35 @@ +#! /usr/bin/env ruby -w +# frozen_string_literal: true + +require "diff/lcs" +require "diff/lcs/htmldiff" + +begin + require "text/format" +rescue LoadError + Diff::LCS::HTMLDiff.can_expand_tabs = false +end + +if ARGV.size < 2 or ARGV.size > 3 + warn "usage: #{File.basename($0)} old new [output.html]" + warn " #{File.basename($0)} old new > output.html" + exit 127 +end + +left = IO.read(ARGV[0]).split($/) +right = IO.read(ARGV[1]).split($/) + +options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" } + +htmldiff = Diff::LCS::HTMLDiff.new(left, right, options) + +if ARGV[2] + File.open(ARGV[2], "w") do |f| + htmldiff.options[:output] = f + htmldiff.run + end +else + htmldiff.run +end + +# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff new file mode 100755 index 0000000..f4734f5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff @@ -0,0 +1,9 @@ +#! /usr/bin/env ruby -w +# frozen_string_literal: true + +require 'diff/lcs' +require 'diff/lcs/ldiff' + +exit Diff::LCS::Ldiff.run(ARGV) + +# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt new file mode 100644 index 0000000..763e17a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt @@ -0,0 +1,127 @@ +The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. You may embed this Package's interpreter within +an executable of yours (by linking); this shall be construed as a mere +form of aggregation, provided that the complete Standard Version of the +interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whoever generated +them, and may be sold commercially, and may be aggregated with this +Package. If such scripts or library files are aggregated with this +Package via the so-called "undump" or "unexec" methods of producing a +binary executable image, then distribution of such an image shall +neither be construed as a distribution of this Package nor shall it +fall under the restrictions of Paragraphs 3 and 4, provided that you do +not represent such an executable image as a Standard Version of this +Package. + +7. C subroutines (or comparably compiled subroutines in other +languages) supplied by you and linked into this Package in order to +emulate subroutines and variables of the language defined by this +Package shall not be considered part of this Package, but are the +equivalent of input as in Paragraph 6, provided these subroutines do +not change the language in any way that would cause it to fail the +regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always +permitted provided that the use of this Package is embedded; that is, +when no overt attempt is made to make this Package's interfaces visible +to the end user of the commercial distribution. Such use shall not be +construed as a distribution of this Package. + +9. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb new file mode 100644 index 0000000..bc07bf9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "diff/lcs" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb new file mode 100644 index 0000000..5ee8937 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb @@ -0,0 +1,742 @@ +# frozen_string_literal: true + +module Diff; end unless defined? Diff + +# == How Diff Works (by Mark-Jason Dominus) +# +# I once read an article written by the authors of +diff+; they said that they +# hard worked very hard on the algorithm until they found the right one. +# +# I think what they ended up using (and I hope someone will correct me, because +# I am not very confident about this) was the `longest common subsequence' +# method. In the LCS problem, you have two sequences of items: +# +# a b c d f g h j q z +# a b c d e f g i j k r x y z +# +# and you want to find the longest sequence of items that is present in both +# original sequences in the same order. That is, you want to find a new +# sequence *S* which can be obtained from the first sequence by deleting some +# items, and from the second sequence by deleting other items. You also want +# *S* to be as long as possible. In this case *S* is: +# +# a b c d f g j z +# +# From there it's only a small step to get diff-like output: +# +# e h i k q r x y +# + - + + - + + + +# +# This module solves the LCS problem. It also includes a canned function to +# generate +diff+-like output. +# +# It might seem from the example above that the LCS of two sequences is always +# pretty obvious, but that's not always the case, especially when the two +# sequences have many repeated elements. For example, consider +# +# a x b y c z p d q +# a b c a x b y c z +# +# A naive approach might start by matching up the +a+ and +b+ that appear at +# the beginning of each sequence, like this: +# +# a x b y c z p d q +# a b c a b y c z +# +# This finds the common subsequence +a b c z+. But actually, the LCS is +a x b +# y c z+: +# +# a x b y c z p d q +# a b c a x b y c z +module Diff::LCS +end + +require "diff/lcs/version" +require "diff/lcs/callbacks" +require "diff/lcs/internals" + +module Diff::LCS + # Returns an Array containing the longest common subsequence(s) between + # +self+ and +other+. See Diff::LCS#lcs. + # + # lcs = seq1.lcs(seq2) + # + # A note when using objects: Diff::LCS only works properly when each object + # can be used as a key in a Hash. This means that those objects must implement + # the methods +#hash+ and +#eql?+ such that two objects containing identical values + # compare identically for key purposes. That is: + # + # O.new('a').eql?(O.new('a')) == true && + # O.new('a').hash == O.new('a').hash + def lcs(other, &block) # :yields: self[i] if there are matched subsequences + Diff::LCS.lcs(self, other, &block) + end + + # Returns the difference set between +self+ and +other+. See Diff::LCS#diff. + def diff(other, callbacks = nil, &block) + Diff::LCS.diff(self, other, callbacks, &block) + end + + # Returns the balanced ("side-by-side") difference set between +self+ and + # +other+. See Diff::LCS#sdiff. + def sdiff(other, callbacks = nil, &block) + Diff::LCS.sdiff(self, other, callbacks, &block) + end + + # Traverses the discovered longest common subsequences between +self+ and + # +other+. See Diff::LCS#traverse_sequences. + def traverse_sequences(other, callbacks = nil, &block) + Diff::LCS.traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block) + end + + # Traverses the discovered longest common subsequences between +self+ and + # +other+ using the alternate, balanced algorithm. See + # Diff::LCS#traverse_balanced. + def traverse_balanced(other, callbacks = nil, &block) + Diff::LCS.traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block) + end + + # Attempts to patch +self+ with the provided +patchset+. A new sequence based + # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Attempts + # to autodiscover the direction of the patch. + def patch(patchset) + Diff::LCS.patch(self, patchset) + end + alias_method :unpatch, :patch + + # Attempts to patch +self+ with the provided +patchset+. A new sequence based + # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Does no + # patch direction autodiscovery. + def patch!(patchset) + Diff::LCS.patch!(self, patchset) + end + + # Attempts to unpatch +self+ with the provided +patchset+. A new sequence + # based on +self+ and the +patchset+ will be created. See Diff::LCS#unpatch. + # Does no patch direction autodiscovery. + def unpatch!(patchset) + Diff::LCS.unpatch!(self, patchset) + end + + # Attempts to patch +self+ with the provided +patchset+, using #patch!. If + # the sequence this is used on supports #replace, the value of +self+ will be + # replaced. See Diff::LCS#patch. Does no patch direction autodiscovery. + def patch_me(patchset) + if respond_to? :replace + replace(patch!(patchset)) + else + patch!(patchset) + end + end + + # Attempts to unpatch +self+ with the provided +patchset+, using #unpatch!. + # If the sequence this is used on supports #replace, the value of +self+ will + # be replaced. See Diff::LCS#unpatch. Does no patch direction autodiscovery. + def unpatch_me(patchset) + if respond_to? :replace + replace(unpatch!(patchset)) + else + unpatch!(patchset) + end + end +end + +class << Diff::LCS + def lcs(seq1, seq2, &block) # :yields: seq1[i] for each matched + matches = Diff::LCS::Internals.lcs(seq1, seq2) + ret = [] + string = seq1.is_a? String + matches.each_index do |i| + next if matches[i].nil? + + v = string ? seq1[i, 1] : seq1[i] + v = block[v] if block + ret << v + end + ret + end + alias_method :LCS, :lcs + + # #diff computes the smallest set of additions and deletions necessary to + # turn the first sequence into the second, and returns a description of these + # changes. + # + # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate + # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a + # Class argument is provided for +callbacks+, #diff will attempt to + # initialise it. If the +callbacks+ object (possibly initialised) responds to + # #finish, it will be called. + def diff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes + diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks, &block) + end + + # #sdiff computes all necessary components to show two sequences and their + # minimized differences side by side, just like the Unix utility + # sdiff does: + # + # old < - + # same same + # before | after + # - > new + # + # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate + # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a + # Class argument is provided for +callbacks+, #diff will attempt to + # initialise it. If the +callbacks+ object (possibly initialised) responds to + # #finish, it will be called. + # + # Each element of a returned array is a Diff::LCS::ContextChange object, + # which can be implicitly converted to an array. + # + # Diff::LCS.sdiff(a, b).each do |action, (old_pos, old_element), (new_pos, new_element)| + # case action + # when '!' + # # replace + # when '-' + # # delete + # when '+' + # # insert + # end + # end + def sdiff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes + diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block) + end + + # #traverse_sequences is the most general facility provided by this module; + # #diff and #lcs are implemented as calls to it. + # + # The arguments to #traverse_sequences are the two sequences to traverse, and + # a callback object, like this: + # + # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) + # + # == Callback Methods + # + # Optional callback methods are emphasized. + # + # callbacks#match:: Called when +a+ and +b+ are pointing to + # common elements in +A+ and +B+. + # callbacks#discard_a:: Called when +a+ is pointing to an + # element not in +B+. + # callbacks#discard_b:: Called when +b+ is pointing to an + # element not in +A+. + # callbacks#finished_a:: Called when +a+ has reached the end of + # sequence +A+. + # callbacks#finished_b:: Called when +b+ has reached the end of + # sequence +B+. + # + # == Algorithm + # + # a---+ + # v + # A = a b c e h j l m n p + # B = b c d e f j k l m r s t + # ^ + # b---+ + # + # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ + # and +B+, the arrows will initially point to the first elements of their + # respective sequences. #traverse_sequences will advance the arrows through + # the sequences one element at a time, calling a method on the user-specified + # callback object before each advance. It will advance the arrows in such a + # way that if there are elements A[i] and B[j] which are + # both equal and part of the longest common subsequence, there will be some + # moment during the execution of #traverse_sequences when arrow +a+ is + # pointing to A[i] and arrow +b+ is pointing to B[j]. When + # this happens, #traverse_sequences will call callbacks#match and + # then it will advance both arrows. + # + # Otherwise, one of the arrows is pointing to an element of its sequence that + # is not part of the longest common subsequence. #traverse_sequences will + # advance that arrow and will call callbacks#discard_a or + # callbacks#discard_b, depending on which arrow it advanced. If both + # arrows point to elements that are not part of the longest common + # subsequence, then #traverse_sequences will advance arrow +a+ and call the + # appropriate callback, then it will advance arrow +b+ and call the appropriate + # callback. + # + # The methods for callbacks#match, callbacks#discard_a, and + # callbacks#discard_b are invoked with an event comprising the + # action ("=", "+", or "-", respectively), the indexes +i+ and +j+, and the + # elements A[i] and B[j]. Return values are discarded by + # #traverse_sequences. + # + # === End of Sequences + # + # If arrow +a+ reaches the end of its sequence before arrow +b+ does, + # #traverse_sequence will try to call callbacks#finished_a with the + # last index and element of +A+ (A[-1]) and the current index and + # element of +B+ (B[j]). If callbacks#finished_a does not + # exist, then callbacks#discard_b will be called on each element of + # +B+ until the end of the sequence is reached (the call will be done with + # A[-1] and B[j] for each element). + # + # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+, + # callbacks#finished_b will be called with the current index and + # element of +A+ (A[i]) and the last index and element of +B+ + # (A[-1]). Again, if callbacks#finished_b does not exist on + # the callback object, then callbacks#discard_a will be called on + # each element of +A+ until the end of the sequence is reached (A[i] + # and B[-1]). + # + # There is a chance that one additional callbacks#discard_a or + # callbacks#discard_b will be called after the end of the sequence + # is reached, if +a+ has not yet reached the end of +A+ or +b+ has not yet + # reached the end of +B+. + def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks) # :yields: change events + callbacks ||= Diff::LCS::SequenceCallbacks + matches = Diff::LCS::Internals.lcs(seq1, seq2) + + run_finished_a = run_finished_b = false + string = seq1.is_a?(String) + + a_size = seq1.size + b_size = seq2.size + ai = bj = 0 + + matches.each do |b_line| + if b_line.nil? + unless seq1[ai].nil? + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + end + else + ax = string ? seq1[ai, 1] : seq1[ai] + + loop do + break unless bj < b_line + + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.match(event) + bj += 1 + end + ai += 1 + end + + # The last entry (if any) processed was a match. +ai+ and +bj+ point just + # past the last matching lines in their sequences. + while (ai < a_size) || (bj < b_size) + # last A? + if ai == a_size && bj < b_size + if callbacks.respond_to?(:finished_a) && !run_finished_a + ax = string ? seq1[-1, 1] : seq1[-1] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new(">", a_size - 1, ax, bj, bx) + event = yield event if block_given? + callbacks.finished_a(event) + run_finished_a = true + else + ax = string ? seq1[ai, 1] : seq1[ai] + loop do + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + break unless bj < b_size + end + end + end + + # last B? + if bj == b_size && ai < a_size + if callbacks.respond_to?(:finished_b) && !run_finished_b + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[-1, 1] : seq2[-1] + event = Diff::LCS::ContextChange.new("<", ai, ax, b_size - 1, bx) + event = yield event if block_given? + callbacks.finished_b(event) + run_finished_b = true + else + bx = string ? seq2[bj, 1] : seq2[bj] + loop do + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + break unless bj < b_size + end + end + end + + if ai < a_size + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + end + + if bj < b_size + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + end + + # #traverse_balanced is an alternative to #traverse_sequences. It uses a + # different algorithm to iterate through the entries in the computed longest + # common subsequence. Instead of viewing the changes as insertions or + # deletions from one of the sequences, #traverse_balanced will report + # changes between the sequences. + # + # The arguments to #traverse_balanced are the two sequences to traverse and a + # callback object, like this: + # + # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) + # + # #sdiff is implemented with #traverse_balanced. + # + # == Callback Methods + # + # Optional callback methods are emphasized. + # + # callbacks#match:: Called when +a+ and +b+ are pointing to + # common elements in +A+ and +B+. + # callbacks#discard_a:: Called when +a+ is pointing to an + # element not in +B+. + # callbacks#discard_b:: Called when +b+ is pointing to an + # element not in +A+. + # callbacks#change:: Called when +a+ and +b+ are pointing to + # the same relative position, but + # A[a] and B[b] are not + # the same; a change has + # occurred. + # + # #traverse_balanced might be a bit slower than #traverse_sequences, + # noticeable only while processing huge amounts of data. + # + # == Algorithm + # + # a---+ + # v + # A = a b c e h j l m n p + # B = b c d e f j k l m r s t + # ^ + # b---+ + # + # === Matches + # + # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ + # and +B+, the arrows will initially point to the first elements of their + # respective sequences. #traverse_sequences will advance the arrows through + # the sequences one element at a time, calling a method on the user-specified + # callback object before each advance. It will advance the arrows in such a + # way that if there are elements A[i] and B[j] which are + # both equal and part of the longest common subsequence, there will be some + # moment during the execution of #traverse_sequences when arrow +a+ is + # pointing to A[i] and arrow +b+ is pointing to B[j]. When + # this happens, #traverse_sequences will call callbacks#match and + # then it will advance both arrows. + # + # === Discards + # + # Otherwise, one of the arrows is pointing to an element of its sequence that + # is not part of the longest common subsequence. #traverse_sequences will + # advance that arrow and will call callbacks#discard_a or + # callbacks#discard_b, depending on which arrow it advanced. + # + # === Changes + # + # If both +a+ and +b+ point to elements that are not part of the longest + # common subsequence, then #traverse_sequences will try to call + # callbacks#change and advance both arrows. If + # callbacks#change is not implemented, then + # callbacks#discard_a and callbacks#discard_b will be + # called in turn. + # + # The methods for callbacks#match, callbacks#discard_a, + # callbacks#discard_b, and callbacks#change are invoked + # with an event comprising the action ("=", "+", "-", or "!", respectively), + # the indexes +i+ and +j+, and the elements A[i] and B[j]. + # Return values are discarded by #traverse_balanced. + # + # === Context + # + # Note that +i+ and +j+ may not be the same index position, even if +a+ and + # +b+ are considered to be pointing to matching or changed elements. + def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks) + matches = Diff::LCS::Internals.lcs(seq1, seq2) + a_size = seq1.size + b_size = seq2.size + ai = bj = mb = 0 + ma = -1 + string = seq1.is_a?(String) + + # Process all the lines in the match vector. + loop do + # Find next match indexes +ma+ and +mb+ + loop do + ma += 1 + break unless ma < matches.size && matches[ma].nil? + end + + break if ma >= matches.size # end of matches? + + mb = matches[ma] + + # Change(seq2) + while (ai < ma) || (bj < mb) + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + case [(ai < ma), (bj < mb)] + when [true, true] + if callbacks.respond_to?(:change) + event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.change(event) + ai += 1 + else + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + end + + bj += 1 + when [true, false] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + when [false, true] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + + # Match + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.match(event) + ai += 1 + bj += 1 + end + + while (ai < a_size) || (bj < b_size) + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + case [(ai < a_size), (bj < b_size)] + when [true, true] + if callbacks.respond_to?(:change) + event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.change(event) + ai += 1 + else + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + end + + bj += 1 + when [true, false] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + when [false, true] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + end + + # standard:disable Style/HashSyntax + PATCH_MAP = { # :nodoc: + :patch => {"+" => "+", "-" => "-", "!" => "!", "=" => "="}.freeze, + :unpatch => {"+" => "-", "-" => "+", "!" => "!", "=" => "="}.freeze + }.freeze + # standard:enable Style/HashSyntax + + # Applies a +patchset+ to the sequence +src+ according to the +direction+ + # (:patch or :unpatch), producing a new sequence. + # + # If the +direction+ is not specified, Diff::LCS::patch will attempt to + # discover the direction of the +patchset+. + # + # A +patchset+ can be considered to apply forward (:patch) if the + # following expression is true: + # + # patch(s1, diff(s1, s2)) -> s2 + # + # A +patchset+ can be considered to apply backward (:unpatch) if the + # following expression is true: + # + # patch(s2, diff(s1, s2)) -> s1 + # + # If the +patchset+ contains no changes, the +src+ value will be returned as + # either src.dup or +src+. A +patchset+ can be deemed as having no + # changes if the following predicate returns true: + # + # patchset.empty? or + # patchset.flatten(1).all? { |change| change.unchanged? } + # + # === Patchsets + # + # A +patchset+ is always an enumerable sequence of changes, hunks of changes, + # or a mix of the two. A hunk of changes is an enumerable sequence of + # changes: + # + # [ # patchset + # # change + # [ # hunk + # # change + # ] + # ] + # + # The +patch+ method accepts patchsets that are enumerable sequences + # containing either Diff::LCS::Change objects (or a subclass) or the array + # representations of those objects. Prior to application, array + # representations of Diff::LCS::Change objects will be reified. + def patch(src, patchset, direction = nil) + # Normalize the patchset. + has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset) + + return src.respond_to?(:dup) ? src.dup : src unless has_changes + + string = src.is_a?(String) + # Start with a new empty type of the source's class + res = src.class.new + + direction ||= Diff::LCS::Internals.intuit_diff_direction(src, patchset) + + ai = bj = 0 + + patch_map = PATCH_MAP[direction] + + patchset.each do |change| + # Both Change and ContextChange support #action + action = patch_map[change.action] + + case change + when Diff::LCS::ContextChange + case direction + when :patch + el = change.new_element + op = change.old_position + np = change.new_position + when :unpatch + el = change.old_element + op = change.new_position + np = change.old_position + end + + case action + when "-" # Remove details from the old string + while ai < op + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + ai += 1 + when "+" + while bj < np + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + res << el + bj += 1 + when "=" + # This only appears in sdiff output with the SDiff callback. + # Therefore, we only need to worry about dealing with a single + # element. + res << el + + ai += 1 + bj += 1 + when "!" + while ai < op + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + bj += 1 + ai += 1 + + res << el + end + when Diff::LCS::Change + case action + when "-" + while ai < change.position + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + ai += 1 + when "+" + while bj < change.position + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + bj += 1 + + res << change.element + end + end + end + + while ai < src.size + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + res + end + + # Given a set of patchset, convert the current version to the prior version. + # Does no auto-discovery. + def unpatch!(src, patchset) + patch(src, patchset, :unpatch) + end + + # Given a set of patchset, convert the current version to the next version. + # Does no auto-discovery. + def patch!(src, patchset) + patch(src, patchset, :patch) + end +end + +require "diff/lcs/backports" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb new file mode 100644 index 0000000..663918a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "diff/lcs" + +class Array + include Diff::LCS +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb new file mode 100644 index 0000000..6543c8a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +unless 0.respond_to?(:positive?) + class Fixnum # standard:disable Lint/UnifiedInteger + def positive? + self > 0 + end + + def negative? + self < 0 + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb new file mode 100644 index 0000000..226ed6f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# A block is an operation removing, adding, or changing a group of items. +# Basically, this is just a list of changes, where each change adds or +# deletes a single item. Used by bin/ldiff. +class Diff::LCS::Block + attr_reader :changes, :insert, :remove + + def initialize(chunk) + @changes = [] + @insert = [] + @remove = [] + + chunk.each do |item| + @changes << item + @remove << item if item.deleting? + @insert << item if item.adding? + end + end + + def diff_size + @insert.size - @remove.size + end + + def op + case [@remove.empty?, @insert.empty?] + when [false, false] + "!" + when [false, true] + "-" + when [true, false] + "+" + else # [true, true] + "^" + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb new file mode 100644 index 0000000..2c5a779 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb @@ -0,0 +1,327 @@ +# frozen_string_literal: true + +require "diff/lcs/change" + +module Diff::LCS + # This callback object implements the default set of callback events, + # which only returns the event itself. Note that #finished_a and + # #finished_b are not implemented -- I haven't yet figured out where they + # would be useful. + # + # Note that this is intended to be called as is, e.g., + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks) + class DefaultCallbacks + class << self + # Called when two items match. + def match(event) + event + end + + # Called when the old value is discarded in favour of the new value. + def discard_a(event) + event + end + + # Called when the new value is discarded in favour of the old value. + def discard_b(event) + event + end + + # Called when both the old and new values have changed. + def change(event) + event + end + + private :new + end + end + + # An alias for DefaultCallbacks that is used in + # Diff::LCS#traverse_sequences. + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks) + SequenceCallbacks = DefaultCallbacks + + # An alias for DefaultCallbacks that is used in + # Diff::LCS#traverse_balanced. + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks) + BalancedCallbacks = DefaultCallbacks + + def self.callbacks_for(callbacks) + callbacks.new + rescue + callbacks + end +end + +# This will produce a compound array of simple diff change objects. Each +# element in the #diffs array is a +hunk+ or +hunk+ array, where each +# element in each +hunk+ array is a single Change object representing the +# addition or removal of a single element from one of the two tested +# sequences. The +hunk+ provides the full context for the changes. +# +# diffs = Diff::LCS.diff(seq1, seq2) +# # This example shows a simplified array format. +# # [ [ [ '-', 0, 'a' ] ], # 1 +# # [ [ '+', 2, 'd' ] ], # 2 +# # [ [ '-', 4, 'h' ], # 3 +# # [ '+', 4, 'f' ] ], +# # [ [ '+', 6, 'k' ] ], # 4 +# # [ [ '-', 8, 'n' ], # 5 +# # [ '-', 9, 'p' ], +# # [ '+', 9, 'r' ], +# # [ '+', 10, 's' ], +# # [ '+', 11, 't' ] ] ] +# +# There are five hunks here. The first hunk says that the +a+ at position 0 +# of the first sequence should be deleted ('-'). The second hunk +# says that the +d+ at position 2 of the second sequence should be inserted +# ('+'). The third hunk says that the +h+ at position 4 of the +# first sequence should be removed and replaced with the +f+ from position 4 +# of the second sequence. The other two hunks are described similarly. +# +# === Use +# +# This callback object must be initialised and is used by the Diff::LCS#diff +# method. +# +# cbo = Diff::LCS::DiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# cbo.finish +# +# Note that the call to #finish is absolutely necessary, or the last set of +# changes will not be visible. Alternatively, can be used as: +# +# cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# The necessary #finish call will be made. +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.map { |f| f.to_a } } +class Diff::LCS::DiffCallbacks + # Returns the difference set collected during the diff process. + attr_reader :diffs + + def initialize # :yields: self + @hunk = [] + @diffs = [] + + return unless block_given? + + begin + yield self + ensure + finish + end + end + + # Finalizes the diff process. If an unprocessed hunk still exists, then it + # is appended to the diff list. + def finish + finish_hunk + end + + def match(_event) + finish_hunk + end + + def discard_a(event) + @hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element) + end + + def discard_b(event) + @hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element) + end + + def finish_hunk + @diffs << @hunk unless @hunk.empty? + @hunk = [] + end + private :finish_hunk +end + +# This will produce a compound array of contextual diff change objects. Each +# element in the #diffs array is a "hunk" array, where each element in each +# "hunk" array is a single change. Each change is a Diff::LCS::ContextChange +# that contains both the old index and new index values for the change. The +# "hunk" provides the full context for the changes. Both old and new objects +# will be presented for changed objects. +nil+ will be substituted for a +# discarded object. +# +# seq1 = %w(a b c e h j l m n p) +# seq2 = %w(b c d e f j k l m r s t) +# +# diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) +# # This example shows a simplified array format. +# # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1 +# # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2 +# # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3 +# # [ '+', [ 5, nil ], [ 4, 'f' ] ] ], +# # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4 +# # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5 +# # [ '+', [ 9, nil ], [ 9, 'r' ] ], +# # [ '-', [ 9, 'p' ], [ 10, nil ] ], +# # [ '+', [ 10, nil ], [ 10, 's' ] ], +# # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ] +# +# The five hunks shown are comprised of individual changes; if there is a +# related set of changes, they are still shown individually. +# +# This callback can also be used with Diff::LCS#sdiff, which will produce +# results like: +# +# diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks) +# # This example shows a simplified array format. +# # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1 +# # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2 +# # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3 +# # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4 +# # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5 +# # [ "!", [ 9, "p" ], [ 10, "s" ] ], +# # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ] +# +# The five hunks are still present, but are significantly shorter in total +# presentation, because changed items are shown as changes ("!") instead of +# potentially "mismatched" pairs of additions and deletions. +# +# The result of this operation is similar to that of +# Diff::LCS::SDiffCallbacks. They may be compared as: +# +# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } +# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) +# +# s == c # -> true +# +# === Use +# +# This callback object must be initialised and can be used by the +# Diff::LCS#diff or Diff::LCS#sdiff methods. +# +# cbo = Diff::LCS::ContextDiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# cbo.finish +# +# Note that the call to #finish is absolutely necessary, or the last set of +# changes will not be visible. Alternatively, can be used as: +# +# cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# The necessary #finish call will be made. +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.map { |f| f.to_a } } +class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks + def discard_a(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end + + def discard_b(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end + + def change(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end +end + +# This will produce a simple array of diff change objects. Each element in +# the #diffs array is a single ContextChange. In the set of #diffs provided +# by SDiffCallbacks, both old and new objects will be presented for both +# changed and unchanged objects. +nil+ will be substituted +# for a discarded object. +# +# The diffset produced by this callback, when provided to Diff::LCS#sdiff, +# will compute and display the necessary components to show two sequences +# and their minimized differences side by side, just like the Unix utility +# +sdiff+. +# +# same same +# before | after +# old < - +# - > new +# +# seq1 = %w(a b c e h j l m n p) +# seq2 = %w(b c d e f j k l m r s t) +# +# diffs = Diff::LCS.sdiff(seq1, seq2) +# # This example shows a simplified array format. +# # [ [ "-", [ 0, "a"], [ 0, nil ] ], +# # [ "=", [ 1, "b"], [ 0, "b" ] ], +# # [ "=", [ 2, "c"], [ 1, "c" ] ], +# # [ "+", [ 3, nil], [ 2, "d" ] ], +# # [ "=", [ 3, "e"], [ 3, "e" ] ], +# # [ "!", [ 4, "h"], [ 4, "f" ] ], +# # [ "=", [ 5, "j"], [ 5, "j" ] ], +# # [ "+", [ 6, nil], [ 6, "k" ] ], +# # [ "=", [ 6, "l"], [ 7, "l" ] ], +# # [ "=", [ 7, "m"], [ 8, "m" ] ], +# # [ "!", [ 8, "n"], [ 9, "r" ] ], +# # [ "!", [ 9, "p"], [ 10, "s" ] ], +# # [ "+", [ 10, nil], [ 11, "t" ] ] ] +# +# The result of this operation is similar to that of +# Diff::LCS::ContextDiffCallbacks. They may be compared as: +# +# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } +# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) +# +# s == c # -> true +# +# === Use +# +# This callback object must be initialised and is used by the Diff::LCS#sdiff +# method. +# +# cbo = Diff::LCS::SDiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# +# As with the other initialisable callback objects, +# Diff::LCS::SDiffCallbacks can be initialised with a block. As there is no +# "fininishing" to be done, this has no effect on the state of the object. +# +# cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.to_a } +class Diff::LCS::SDiffCallbacks + # Returns the difference set collected during the diff process. + attr_reader :diffs + + def initialize # :yields: self + @diffs = [] + yield self if block_given? + end + + def match(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def discard_a(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def discard_b(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def change(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb new file mode 100644 index 0000000..714d78c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb @@ -0,0 +1,174 @@ +# frozen_string_literal: true + +# Represents a simplistic (non-contextual) change. Represents the removal or +# addition of an element from either the old or the new sequenced +# enumerable. +class Diff::LCS::Change + IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName + + # The only actions valid for changes are '+' (add), '-' (delete), '=' + # (no change), '!' (changed), '<' (tail changes from first sequence), or + # '>' (tail changes from second sequence). The last two ('<>') are only + # found with Diff::LCS::diff and Diff::LCS::sdiff. + VALID_ACTIONS = %w[+ - = ! > <].freeze + + def self.valid_action?(action) + VALID_ACTIONS.include? action + end + + # Returns the action this Change represents. + attr_reader :action + + # Returns the position of the Change. + attr_reader :position + # Returns the sequence element of the Change. + attr_reader :element + + def initialize(*args) + @action, @position, @element = *args + + fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) + fail "Invalid Position Type" unless @position.is_a? IntClass + end + + def inspect(*_args) + "#<#{self.class}: #{to_a.inspect}>" + end + + def to_a + [@action, @position, @element] + end + + alias_method :to_ary, :to_a + + def self.from_a(arr) + arr = arr.flatten(1) + case arr.size + when 5 + Diff::LCS::ContextChange.new(*arr[0...5]) + when 3 + Diff::LCS::Change.new(*arr[0...3]) + else + fail "Invalid change array format provided." + end + end + + include Comparable + + def ==(other) + (self.class == other.class) and + (action == other.action) and + (position == other.position) and + (element == other.element) + end + + def <=>(other) + r = action <=> other.action + r = position <=> other.position if r.zero? + r = element <=> other.element if r.zero? + r + end + + def adding? + @action == "+" + end + + def deleting? + @action == "-" + end + + def unchanged? + @action == "=" + end + + def changed? + @action == "!" + end + + def finished_a? + @action == ">" + end + + def finished_b? + @action == "<" + end +end + +# Represents a contextual change. Contains the position and values of the +# elements in the old and the new sequenced enumerables as well as the action +# taken. +class Diff::LCS::ContextChange < Diff::LCS::Change + # We don't need these two values. + undef :position + undef :element + + # Returns the old position being changed. + attr_reader :old_position + # Returns the new position being changed. + attr_reader :new_position + # Returns the old element being changed. + attr_reader :old_element + # Returns the new element being changed. + attr_reader :new_element + + def initialize(*args) + @action, @old_position, @old_element, @new_position, @new_element = *args + + fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) + fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass) + fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass) + end + + def to_a + [ + @action, + [@old_position, @old_element], + [@new_position, @new_element] + ] + end + + alias_method :to_ary, :to_a + + def self.from_a(arr) + Diff::LCS::Change.from_a(arr) + end + + # Simplifies a context change for use in some diff callbacks. '<' actions + # are converted to '-' and '>' actions are converted to '+'. + def self.simplify(event) + ea = event.to_a + + case ea[0] + when "-" + ea[2][1] = nil + when "<" + ea[0] = "-" + ea[2][1] = nil + when "+" + ea[1][1] = nil + when ">" + ea[0] = "+" + ea[1][1] = nil + end + + Diff::LCS::ContextChange.from_a(ea) + end + + def ==(other) + (self.class == other.class) and + (@action == other.action) and + (@old_position == other.old_position) and + (@new_position == other.new_position) and + (@old_element == other.old_element) and + (@new_element == other.new_element) + end + + def <=>(other) + r = @action <=> other.action + r = @old_position <=> other.old_position if r.zero? + r = @new_position <=> other.new_position if r.zero? + r = @old_element <=> other.old_element if r.zero? + r = @new_element <=> other.new_element if r.zero? + r + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb new file mode 100644 index 0000000..9073243 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require "erb" + +# Produce a simple HTML diff view. +class Diff::LCS::HTMLDiff + class << self + # standard:disable ThreadSafety/ClassAndModuleAttributes + attr_accessor :can_expand_tabs # :nodoc: + # standard:enable ThreadSafety/ClassAndModuleAttributes + end + self.can_expand_tabs = true + + class Callbacks # :nodoc: + attr_accessor :output + attr_accessor :match_class + attr_accessor :only_a_class + attr_accessor :only_b_class + + def initialize(output, options = {}) + @output = output + options ||= {} + + @match_class = options[:match_class] || "match" + @only_a_class = options[:only_a_class] || "only_a" + @only_b_class = options[:only_b_class] || "only_b" + end + + def htmlize(element, css_class) + element = " " if element.empty? + %(

#{element}
\n) + end + private :htmlize + + # This will be called with both lines are the same + def match(event) + @output << htmlize(event.old_element, :match_class) + end + + # This will be called when there is a line in A that isn't in B + def discard_a(event) + @output << htmlize(event.old_element, :only_a_class) + end + + # This will be called when there is a line in B that isn't in A + def discard_b(event) + @output << htmlize(event.new_element, :only_b_class) + end + end + + # standard:disable Style/HashSyntax + DEFAULT_OPTIONS = { + :expand_tabs => nil, + :output => nil, + :css => nil, + :title => nil + }.freeze + # standard:enable Style/HashSyntax + + # standard:disable Layout/HeredocIndentation + DEFAULT_CSS = <<-CSS +body { margin: 0; } +.diff +{ + border: 1px solid black; + margin: 1em 2em; +} +p +{ + margin-left: 2em; +} +pre +{ + padding-left: 1em; + margin: 0; + font-family: Inconsolata, Consolas, Lucida, Courier, monospaced; + white-space: pre; +} +.match { } +.only_a +{ + background-color: #fdd; + color: red; + text-decoration: line-through; +} +.only_b +{ + background-color: #ddf; + color: blue; + border-left: 3px solid blue +} +h1 { margin-left: 2em; } + CSS + # standard:enable Layout/HeredocIndentation + + def initialize(left, right, options = nil) + @left = left + @right = right + @options = options + + @options = DEFAULT_OPTIONS.dup if @options.nil? + end + + def verify_options + @options[:expand_tabs] ||= 4 + @options[:expand_tabs] = 4 if @options[:expand_tabs].negative? + + @options[:output] ||= $stdout + + @options[:css] ||= DEFAULT_CSS.dup + + @options[:title] ||= "diff" + end + private :verify_options + + attr_reader :options + + def run + verify_options + + if @options[:expand_tabs].positive? && self.class.can_expand_tabs + formatter = Text::Format.new + formatter.tabstop = @options[:expand_tabs] + + @left.map! { |line| formatter.expand(line.chomp) } + @right.map! { |line| formatter.expand(line.chomp) } + end + + @left.map! { |line| ERB::Util.html_escape(line.chomp) } + @right.map! { |line| ERB::Util.html_escape(line.chomp) } + + # standard:disable Layout/HeredocIndentation + @options[:output] << <<-OUTPUT + + + #{@options[:title]} + + + +

#{@options[:title]}

+

Legend: Only in Old  + Only in New

+
+ OUTPUT + # standard:enable Layout/HeredocIndentation + + callbacks = Callbacks.new(@options[:output]) + Diff::LCS.traverse_sequences(@left, @right, callbacks) + + # standard:disable Layout/HeredocIndentation + @options[:output] << <<-OUTPUT +
+ + + OUTPUT + # standard:enable Layout/HeredocIndentation + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb new file mode 100644 index 0000000..24b33bc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb @@ -0,0 +1,379 @@ +# frozen_string_literal: true + +require "diff/lcs/block" + +# A Hunk is a group of Blocks which overlap because of the context surrounding +# each block. (So if we're not using context, every hunk will contain one +# block.) Used in the diff program (bin/ldiff). +class Diff::LCS::Hunk + OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: + ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: + + private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant) + + # Create a hunk using references to both the old and new data, as well as the + # piece of data. + def initialize(data_old, data_new, piece, flag_context, file_length_difference) + # At first, a hunk will have just one Block in it + @blocks = [Diff::LCS::Block.new(piece)] + + if @blocks[0].remove.empty? && @blocks[0].insert.empty? + fail "Cannot build a hunk from #{piece.inspect}; has no add or remove actions" + end + + if String.method_defined?(:encoding) + @preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding + end + + @data_old = data_old + @data_new = data_new + @old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?) + @new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?) + + before = after = file_length_difference + after += @blocks[0].diff_size + @file_length_difference = after # The caller must get this manually + @max_diff_size = @blocks.map { |e| e.diff_size.abs }.max + + # Save the start & end of each array. If the array doesn't exist (e.g., + # we're only adding items in this block), then figure out the line number + # based on the line number of the other file and the current difference in + # file lengths. + if @blocks[0].remove.empty? + a1 = a2 = nil + else + a1 = @blocks[0].remove[0].position + a2 = @blocks[0].remove[-1].position + end + + if @blocks[0].insert.empty? + b1 = b2 = nil + else + b1 = @blocks[0].insert[0].position + b2 = @blocks[0].insert[-1].position + end + + @start_old = a1 || (b1 - before) + @start_new = b1 || (a1 + before) + @end_old = a2 || (b2 - after) + @end_new = b2 || (a2 + after) + + self.flag_context = flag_context + end + + attr_reader :blocks + attr_reader :start_old, :start_new + attr_reader :end_old, :end_new + attr_reader :file_length_difference + + # Change the "start" and "end" fields to note that context should be added + # to this hunk. + attr_accessor :flag_context + undef :flag_context= + def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods + return if context.nil? || context.zero? + + add_start = (context > @start_old) ? @start_old : context + + @start_old -= add_start + @start_new -= add_start + + old_size = @data_old.size + + add_end = + if (@end_old + context) >= old_size + old_size - @end_old - 1 + else + context + end + + @end_old += add_end + @end_new += add_end + end + + # Merges this hunk and the provided hunk together if they overlap. Returns + # a truthy value so that if there is no overlap, you can know the merge + # was skipped. + def merge(hunk) + return unless overlaps?(hunk) + + @start_old = hunk.start_old + @start_new = hunk.start_new + blocks.unshift(*hunk.blocks) + end + alias_method :unshift, :merge + + # Determines whether there is an overlap between this hunk and the + # provided hunk. This will be true if the difference between the two hunks + # start or end positions is within one position of each other. + def overlaps?(hunk) + hunk and (((@start_old - hunk.end_old) <= 1) or + ((@start_new - hunk.end_new) <= 1)) + end + + # Returns a diff string based on a format. + def diff(format, last = false) + case format + when :old + old_diff(last) + when :unified + unified_diff(last) + when :context + context_diff(last) + when :ed + self + when :reverse_ed, :ed_finish + ed_diff(format, last) + else + fail "Unknown diff format #{format}." + end + end + + # Note that an old diff can't have any context. Therefore, we know that + # there's only one block in the hunk. + def old_diff(last = false) + warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 + + block = @blocks[0] + + if last + old_missing_newline = !@old_empty && missing_last_newline?(@data_old) + new_missing_newline = !@new_empty && missing_last_newline?(@data_new) + end + + # Calculate item number range. Old diff range is just like a context + # diff range, except the ranges are on one line with the action between + # them. + s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n") + # If removing anything, just print out all the remove lines in the hunk + # which is just all the remove lines in the block. + unless block.remove.empty? + @data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") } + end + + s << encode("\\ No newline at end of file\n") if old_missing_newline && !new_missing_newline + s << encode("---\n") if block.op == "!" + + unless block.insert.empty? + @data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") } + end + + s << encode("\\ No newline at end of file\n") if new_missing_newline && !old_missing_newline + + s + end + private :old_diff + + def unified_diff(last = false) + # Calculate item number range. + s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n") + + # Outlist starts containing the hunk of the old file. Removing an item + # just means putting a '-' in front of it. Inserting an item requires + # getting it from the new file and splicing it in. We splice in + # +num_added+ items. Remove blocks use +num_added+ because splicing + # changed the length of outlist. + # + # We remove +num_removed+ items. Insert blocks use +num_removed+ + # because their item numbers -- corresponding to positions in the NEW + # file -- don't take removed items into account. + lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0 + + # standard:disable Performance/UnfreezeString + outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = blocks[-1] + + if last + old_missing_newline = !@old_empty && missing_last_newline?(@data_old) + new_missing_newline = !@new_empty && missing_last_newline?(@data_new) + end + + @blocks.each do |block| + block.remove.each do |item| + op = item.action.to_s # - + offset = item.position - lo + num_added + outlist[offset][0, 1] = encode(op) + num_removed += 1 + end + + if last && block == last_block && old_missing_newline && !new_missing_newline + outlist << encode('\\ No newline at end of file') + num_removed += 1 + end + + block.insert.each do |item| + op = item.action.to_s # + + offset = item.position - @start_new + num_removed + outlist[offset, 0] = encode(op) + @data_new[item.position].chomp + num_added += 1 + end + end + + outlist << encode('\\ No newline at end of file') if last && new_missing_newline + + s << outlist.join(encode("\n")) + + s + end + private :unified_diff + + def context_diff(last = false) + s = encode("***************\n") + s << encode("*** #{context_range(:old, ",")} ****\n") + r = context_range(:new, ",") + + if last + old_missing_newline = missing_last_newline?(@data_old) + new_missing_newline = missing_last_newline?(@data_new) + end + + # Print out file 1 part for each block in context diff format if there + # are any blocks that remove items + lo, hi = @start_old, @end_old + removes = @blocks.reject { |e| e.remove.empty? } + + unless removes.empty? + # standard:disable Performance/UnfreezeString + outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = removes[-1] + + removes.each do |block| + block.remove.each do |item| + outlist[item.position - lo][0, 1] = encode(block.op) # - or ! + end + + if last && block == last_block && old_missing_newline + outlist << encode('\\ No newline at end of file') + end + end + + s << outlist.join(encode("\n")) << encode("\n") + end + + s << encode("--- #{r} ----\n") + lo, hi = @start_new, @end_new + inserts = @blocks.reject { |e| e.insert.empty? } + + unless inserts.empty? + # standard:disable Performance/UnfreezeString + outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = inserts[-1] + + inserts.each do |block| + block.insert.each do |item| + outlist[item.position - lo][0, 1] = encode(block.op) # + or ! + end + + if last && block == last_block && new_missing_newline + outlist << encode('\\ No newline at end of file') + end + end + s << outlist.join(encode("\n")) + end + + s + end + private :context_diff + + def ed_diff(format, last) + warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 + if last + # ed script doesn't support well incomplete lines + warn ": No newline at end of file\n" if !@old_empty && missing_last_newline?(@data_old) + warn ": No newline at end of file\n" if !@new_empty && missing_last_newline?(@data_new) + + if @blocks[0].op == "!" + return +"" if @blocks[0].changes[0].element == @blocks[0].changes[1].element + "\n" + return +"" if @blocks[0].changes[0].element + "\n" == @blocks[0].changes[1].element + end + end + + s = + if format == :reverse_ed + encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n") + else + encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n") + end + + unless @blocks[0].insert.empty? + @data_new[@start_new..@end_new].each do |e| + s << e.chomp + encode("\n") + end + s << encode(".\n") + end + s + end + private :ed_diff + + # Generate a range of item numbers to print. Only print 1 number if the + # range has only one item in it. Otherwise, it's 'start,end' + def context_range(mode, op) + case mode + when :old + s, e = (@start_old + 1), (@end_old + 1) + when :new + s, e = (@start_new + 1), (@end_new + 1) + end + + (s < e) ? "#{s}#{op}#{e}" : e.to_s + end + private :context_range + + # Generate a range of item numbers to print for unified diff. Print number + # where block starts, followed by number of lines in the block + # (don't print number of lines if it's 1) + def unified_range(mode) + case mode + when :old + return "0,0" if @old_empty + s, e = (@start_old + 1), (@end_old + 1) + when :new + return "0,0" if @new_empty + s, e = (@start_new + 1), (@end_new + 1) + end + + length = e - s + 1 + + (length <= 1) ? e.to_s : "#{s},#{length}" + end + private :unified_range + + def missing_last_newline?(data) + newline = encode("\n") + + if data[-2] + data[-2].end_with?(newline) && !data[-1].end_with?(newline) + elsif data[-1] + !data[-1].end_with?(newline) + else + true + end + end + + if String.method_defined?(:encoding) + def encode(literal, target_encoding = @preferred_data_encoding) + literal.encode target_encoding + end + + def encode_as(string, *args) + args.map { |arg| arg.encode(string.encoding) } + end + else + def encode(literal, _target_encoding = nil) + literal + end + + def encode_as(_string, *args) + args + end + end + + private :encode + private :encode_as +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb new file mode 100644 index 0000000..8a9160a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb @@ -0,0 +1,308 @@ +# frozen_string_literal: true + +class << Diff::LCS + def diff_traversal(method, seq1, seq2, callbacks, &block) + callbacks = callbacks_for(callbacks) + case method + when :diff + traverse_sequences(seq1, seq2, callbacks) + when :sdiff + traverse_balanced(seq1, seq2, callbacks) + end + callbacks.finish if callbacks.respond_to? :finish + + if block + callbacks.diffs.map do |hunk| + if hunk.is_a? Array + hunk.map { |hunk_block| block[hunk_block] } + else + block[hunk] + end + end + else + callbacks.diffs + end + end + private :diff_traversal +end + +module Diff::LCS::Internals # :nodoc: +end + +class << Diff::LCS::Internals + # Compute the longest common subsequence between the sequenced + # Enumerables +a+ and +b+. The result is an array whose contents is such + # that + # + # result = Diff::LCS::Internals.lcs(a, b) + # result.each_with_index do |e, i| + # assert_equal(a[i], b[e]) unless e.nil? + # end + def lcs(a, b) + a_start = b_start = 0 + a_finish = a.size - 1 + b_finish = b.size - 1 + vector = [] + + # Collect any common elements at the beginning... + while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_start] == b[b_start]) + vector[a_start] = b_start + a_start += 1 + b_start += 1 + end + + # Now the end... + while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_finish] == b[b_finish]) + vector[a_finish] = b_finish + a_finish -= 1 + b_finish -= 1 + end + + # Now, compute the equivalence classes of positions of elements. + # An explanation for how this works: https://codeforces.com/topic/92191 + b_matches = position_hash(b, b_start..b_finish) + + thresh = [] + links = [] + string = a.is_a?(String) + + (a_start..a_finish).each do |i| + ai = string ? a[i, 1] : a[i] + bm = b_matches[ai] + k = nil + bm.reverse_each do |j| + # Although the threshold check is not mandatory for this to work, + # it may have an optimization purpose + # An attempt to remove it: https://github.com/halostatue/diff-lcs/pull/72 + # Why it is reintroduced: https://github.com/halostatue/diff-lcs/issues/78 + if k && (thresh[k] > j) && (thresh[k - 1] < j) + thresh[k] = j + else + k = replace_next_larger(thresh, j, k) + end + links[k] = [k.positive? ? links[k - 1] : nil, i, j] unless k.nil? + end + end + + unless thresh.empty? + link = links[thresh.size - 1] + until link.nil? + vector[link[1]] = link[2] + link = link[0] + end + end + + vector + end + + # This method will analyze the provided patchset to provide a single-pass + # normalization (conversion of the array form of Diff::LCS::Change objects to + # the object form of same) and detection of whether the patchset represents + # changes to be made. + def analyze_patchset(patchset, depth = 0) + fail "Patchset too complex" if depth > 1 + + has_changes = false + new_patchset = [] + + # Format: + # [ # patchset + # # hunk (change) + # [ # hunk + # # change + # ] + # ] + + patchset.each do |hunk| + case hunk + when Diff::LCS::Change + has_changes ||= !hunk.unchanged? + new_patchset << hunk + when Array + # Detect if the 'hunk' is actually an array-format change object. + if Diff::LCS::Change.valid_action? hunk[0] + hunk = Diff::LCS::Change.from_a(hunk) + has_changes ||= !hunk.unchanged? + new_patchset << hunk + else + with_changes, hunk = analyze_patchset(hunk, depth + 1) + has_changes ||= with_changes + new_patchset.concat(hunk) + end + else + fail ArgumentError, "Cannot normalise a hunk of class #{hunk.class}." + end + end + + [has_changes, new_patchset] + end + + # Examine the patchset and the source to see in which direction the + # patch should be applied. + # + # WARNING: By default, this examines the whole patch, so this could take + # some time. This also works better with Diff::LCS::ContextChange or + # Diff::LCS::Change as its source, as an array will cause the creation + # of one of the above. + def intuit_diff_direction(src, patchset, limit = nil) + string = src.is_a?(String) + count = left_match = left_miss = right_match = right_miss = 0 + + patchset.each do |change| + count += 1 + + case change + when Diff::LCS::ContextChange + le = string ? src[change.old_position, 1] : src[change.old_position] + re = string ? src[change.new_position, 1] : src[change.new_position] + + case change.action + when "-" # Remove details from the old string + if le == change.old_element + left_match += 1 + else + left_miss += 1 + end + when "+" + if re == change.new_element + right_match += 1 + else + right_miss += 1 + end + when "=" + left_miss += 1 if le != change.old_element + right_miss += 1 if re != change.new_element + when "!" + if le == change.old_element + left_match += 1 + elsif re == change.new_element + right_match += 1 + else + left_miss += 1 + right_miss += 1 + end + end + when Diff::LCS::Change + # With a simplistic change, we can't tell the difference between + # the left and right on '!' actions, so we ignore those. On '=' + # actions, if there's a miss, we miss both left and right. + element = string ? src[change.position, 1] : src[change.position] + + case change.action + when "-" + if element == change.element + left_match += 1 + else + left_miss += 1 + end + when "+" + if element == change.element + right_match += 1 + else + right_miss += 1 + end + when "=" + if element != change.element + left_miss += 1 + right_miss += 1 + end + end + end + + break if !limit.nil? && (count > limit) + end + + no_left = left_match.zero? && left_miss.positive? + no_right = right_match.zero? && right_miss.positive? + + case [no_left, no_right] + when [false, true] + :patch + when [true, false] + :unpatch + else + case left_match <=> right_match + when 1 + if left_miss.zero? + :patch + else + :unpatch + end + when -1 + if right_miss.zero? + :unpatch + else + :patch + end + else + fail "The provided patchset does not appear to apply to the provided \ +enumerable as either source or destination value." + end + end + end + + # Find the place at which +value+ would normally be inserted into the + # Enumerable. If that place is already occupied by +value+, do nothing + # and return +nil+. If the place does not exist (i.e., it is off the end + # of the Enumerable), add it to the end. Otherwise, replace the element + # at that point with +value+. It is assumed that the Enumerable's values + # are numeric. + # + # This operation preserves the sort order. + def replace_next_larger(enum, value, last_index = nil) + # Off the end? + if enum.empty? || (value > enum[-1]) + enum << value + return enum.size - 1 + end + + # Binary search for the insertion point + last_index ||= enum.size - 1 + first_index = 0 + while first_index <= last_index + i = (first_index + last_index) >> 1 + + found = enum[i] + + return nil if value == found + + if value > found + first_index = i + 1 + else + last_index = i - 1 + end + end + + # The insertion point is in first_index; overwrite the next larger + # value. + enum[first_index] = value + first_index + end + private :replace_next_larger + + # If +vector+ maps the matching elements of another collection onto this + # Enumerable, compute the inverse of +vector+ that maps this Enumerable + # onto the collection. (Currently unused.) + def inverse_vector(a, vector) + inverse = a.dup + (0...vector.size).each do |i| + inverse[vector[i]] = i unless vector[i].nil? + end + inverse + end + private :inverse_vector + + # Returns a hash mapping each element of an Enumerable to the set of + # positions it occupies in the Enumerable, optionally restricted to the + # elements specified in the range of indexes specified by +interval+. + def position_hash(enum, interval) + string = enum.is_a?(String) + hash = Hash.new { |h, k| h[k] = [] } + interval.each do |i| + k = string ? enum[i, 1] : enum[i] + hash[k] << i + end + hash + end + private :position_hash +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb new file mode 100644 index 0000000..6442c9b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb @@ -0,0 +1,189 @@ +# frozen_string_literal: true + +require "optparse" +require "diff/lcs/hunk" + +class Diff::LCS::Ldiff # :nodoc: + # standard:disable Layout/HeredocIndentation + BANNER = <<-COPYRIGHT +ldiff #{Diff::LCS::VERSION} + Copyright 2004-2025 Austin Ziegler + + Part of Diff::LCS. + https://github.com/halostatue/diff-lcs + + This program is free software. It may be redistributed and/or modified under + the terms of the GPL version 2 (or later), the Perl Artistic licence, or the + MIT licence. + COPYRIGHT + # standard:enable Layout/HeredocIndentation + + InputInfo = Struct.new(:filename, :data, :stat) do + def initialize(filename) + super(filename, ::File.read(filename), ::File.stat(filename)) + end + end + + attr_reader :format, :lines # :nodoc: + attr_reader :file_old, :file_new # :nodoc: + attr_reader :data_old, :data_new # :nodoc: + + def self.run(args, input = $stdin, output = $stdout, error = $stderr) # :nodoc: + new.run(args, input, output, error) + end + + def initialize + @binary = nil + @format = :old + @lines = 0 + end + + def run(args, _input = $stdin, output = $stdout, error = $stderr) # :nodoc: + args.options do |o| + o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile" + o.separator "" + o.on( + "-c", "-C", "--context [LINES]", Integer, + "Displays a context diff with LINES lines", "of context. Default 3 lines." + ) do |ctx| + @format = :context + @lines = ctx || 3 + end + o.on( + "-u", "-U", "--unified [LINES]", Integer, + "Displays a unified diff with LINES lines", "of context. Default 3 lines." + ) do |ctx| + @format = :unified + @lines = ctx || 3 + end + o.on("-e", "Creates an 'ed' script to change", "oldfile to newfile.") do |_ctx| + @format = :ed + end + o.on("-f", "Creates an 'ed' script to change", "oldfile to newfile in reverse order.") do |_ctx| + @format = :reverse_ed + end + o.on( + "-a", "--text", + "Treat the files as text and compare them", "line-by-line, even if they do not seem", "to be text." + ) do |_txt| + @binary = false + end + o.on("--binary", "Treats the files as binary.") do |_bin| + @binary = true + end + o.on("-q", "--brief", "Report only whether or not the files", "differ, not the details.") do |_ctx| + @format = :report + end + o.on_tail("--help", "Shows this text.") do + error << o + return 0 + end + o.on_tail("--version", "Shows the version of Diff::LCS.") do + error << Diff::LCS::Ldiff::BANNER + return 0 + end + o.on_tail "" + o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.' + o.parse! + end + + unless args.size == 2 + error << args.options + return 127 + end + + # Defaults are for old-style diff + @format ||= :old + @lines ||= 0 + + file_old, file_new = *ARGV + diff?( + InputInfo.new(file_old), + InputInfo.new(file_new), + @format, + output, + binary: @binary, + lines: @lines + ) ? 1 : 0 + end + + def diff?(info_old, info_new, format, output, binary: nil, lines: 0) + case format + when :context + char_old = "*" * 3 + char_new = "-" * 3 + when :unified + char_old = "-" * 3 + char_new = "+" * 3 + end + + # After we've read up to a certain point in each file, the number of + # items we've read from each file will differ by FLD (could be 0). + file_length_difference = 0 + + # Test binary status + if binary.nil? + old_bin = info_old.data[0, 4096].include?("\0") + new_bin = info_new.data[0, 4096].include?("\0") + binary = old_bin || new_bin + end + + # diff yields lots of pieces, each of which is basically a Block object + if binary + has_diffs = (info_old.data != info_new.data) + if format != :report + if has_diffs + output << "Binary files #{info_old.filename} and #{info_new.filename} differ\n" + return true + end + return false + end + else + data_old = info_old.data.lines.to_a + data_new = info_new.data.lines.to_a + diffs = Diff::LCS.diff(data_old, data_new) + return false if diffs.empty? + end + + case format + when :report + output << "Files #{info_old.filename} and #{info_new.filename} differ\n" + return true + when :unified, :context + ft = info_old.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") + output << "#{char_old} #{info_old.filename}\t#{ft}\n" + ft = info_new.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") + output << "#{char_new} #{info_new.filename}\t#{ft}\n" + when :ed + real_output = output + output = [] + end + + # Loop over hunks. If a hunk overlaps with the last hunk, join them. + # Otherwise, print out the old one. + oldhunk = hunk = nil + diffs.each do |piece| + begin + hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, lines, file_length_difference) + file_length_difference = hunk.file_length_difference + + next unless oldhunk + next if lines.positive? && hunk.merge(oldhunk) + + output << oldhunk.diff(format) + output << "\n" if format == :unified + ensure + oldhunk = hunk + end + end + + last = oldhunk.diff(format, true) + last << "\n" unless last.is_a?(Diff::LCS::Hunk) || last.empty? || last.end_with?("\n") + + output << last + + output.reverse_each { |e| real_output << e.diff(:ed_finish, e == output[0]) } if format == :ed + + true + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb new file mode 100644 index 0000000..9ab32e9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class String + include Diff::LCS +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb new file mode 100644 index 0000000..82830e3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Diff + module LCS + VERSION = "1.6.2" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml new file mode 100644 index 0000000..22418cf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml @@ -0,0 +1,5 @@ +[tools] +ruby = "3.4" + +[env] +MAINTENANCE = "true" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb new file mode 100644 index 0000000..42533ae --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS::Change do + describe "an add" do + subject { described_class.new("+", 0, "element") } + it { should_not be_deleting } + it { should be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a delete" do + subject { described_class.new("-", 0, "element") } + it { should be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "an unchanged" do + subject { described_class.new("=", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a changed" do + subject { described_class.new("!", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a finished_a" do + subject { described_class.new(">", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should be_finished_a } + it { should_not be_finished_b } + end + + describe "a finished_b" do + subject { described_class.new("<", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should be_finished_b } + end + + describe "as array" do + it "should be converted" do + action, position, element = described_class.new("!", 0, "element") + expect(action).to eq "!" + expect(position).to eq 0 + expect(element).to eq "element" + end + end +end + +describe Diff::LCS::ContextChange do + describe "as array" do + it "should be converted" do + action, (old_position, old_element), (new_position, new_element) = + described_class.new("!", 1, "old_element", 2, "new_element") + + expect(action).to eq "!" + expect(old_position).to eq 1 + expect(old_element).to eq "old_element" + expect(new_position).to eq 2 + expect(new_element).to eq "new_element" + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb new file mode 100644 index 0000000..869f098 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS, ".diff" do + include Diff::LCS::SpecHelper::Matchers + + it "correctly diffs seq1 to seq2" do + diff_s1_s2 = Diff::LCS.diff(seq1, seq2) + expect(change_diff(correct_forward_diff)).to eq(diff_s1_s2) + end + + it "correctly diffs seq2 to seq1" do + diff_s2_s1 = Diff::LCS.diff(seq2, seq1) + expect(change_diff(correct_backward_diff)).to eq(diff_s2_s1) + end + + it "correctly diffs against an empty sequence" do + diff = Diff::LCS.diff(word_sequence, []) + correct_diff = [ + [ + ["-", 0, "abcd"], + ["-", 1, "efgh"], + ["-", 2, "ijkl"], + ["-", 3, "mnopqrstuvwxyz"] + ] + ] + + expect(change_diff(correct_diff)).to eq(diff) + + diff = Diff::LCS.diff([], word_sequence) + correct_diff.each do |hunk| + hunk.each { |change| change[0] = "+" } + end + expect(change_diff(correct_diff)).to eq(diff) + end + + it "correctly diffs 'xx' and 'xaxb'" do + left = "xx" + right = "xaxb" + expect(Diff::LCS.patch(left, Diff::LCS.diff(left, right))).to eq(right) + end + + it "returns an empty diff with (hello, hello)" do + expect(Diff::LCS.diff(hello, hello)).to be_empty + end + + it "returns an empty diff with (hello_ary, hello_ary)" do + expect(Diff::LCS.diff(hello_ary, hello_ary)).to be_empty + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x new file mode 100644 index 0000000..cd34c23 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x @@ -0,0 +1,2 @@ +123 +x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x new file mode 100644 index 0000000..9a823ac --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x @@ -0,0 +1,2 @@ +456 +x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX new file mode 100644 index 0000000..5765d6a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX @@ -0,0 +1 @@ +aX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX new file mode 100644 index 0000000..a1c813d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX @@ -0,0 +1 @@ +bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv new file mode 100644 index 0000000..9ac8428 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv @@ -0,0 +1,50 @@ +1,3 +2,7 +3,13 +4,21 +5,31 +6,43 +7,57 +8,73 +9,91 +10,111 +11,133 +12,157 +13,183 +14,211 +15,241 +16,273 +17,307 +18,343 +19,381 +20,421 +21,463 +22,507 +23,553 +24,601 +25,651 +26,703 +27,757 +28,813 +29,871 +30,931 +31,993 +32,1057 +33,1123 +34,1191 +35,1261 +36,1333 +37,1407 +38,1483 +39,1561 +40,1641 +41,1723 +42,1807 +43,1893 +44,1981 +45,2071 +46,2163 +47,2257 +48,2353 +49,2451 +50,2500 \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv new file mode 100644 index 0000000..797de76 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv @@ -0,0 +1,51 @@ + 1,3 +2,7 +3,13 +4,21 +5,31 +6,42 +7,57 +8,73 +9,91 +10,111 +11,133 +12,157 +13,183 +14,211 +15,241 +16,273 +17,307 +18,343 +19,200 +20,421 +21,463 +22,507 +23,553 +24,601 +25,651 +26,703 +27,757 +28,813 +29,871 +30,931 +31,123 +32,1057 +33,1123 +34,1000 +35,1261 +36,1333 +37,1407 +38,1483 +39,1561 +40,1641 +41,1723 +42,1807 +43,1893 +44,1981 +45,2071 +46,2163 +47,1524 +48,2353 +49,2451 +50,2500 +51,2520 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin new file mode 100644 index 0000000000000000000000000000000000000000..ba18e3dcc474e720bdd955f81c8848324c862840 GIT binary patch literal 6 Ncmc~u&B@7U000O<0u=xN literal 0 HcmV?d00001 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines new file mode 100644 index 0000000..f384549 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines @@ -0,0 +1,4 @@ +one +two +three +four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line new file mode 100644 index 0000000..c40a3bd --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line @@ -0,0 +1,4 @@ +one +two +three +four \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e new file mode 100644 index 0000000..8ed0319 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e @@ -0,0 +1,2 @@ +: No newline at end of file +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f new file mode 100644 index 0000000..8ed0319 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f @@ -0,0 +1,2 @@ +: No newline at end of file +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e new file mode 100644 index 0000000..397dd5b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f new file mode 100644 index 0000000..397dd5b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e new file mode 100644 index 0000000..f9493ef --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f new file mode 100644 index 0000000..f9493ef --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff new file mode 100644 index 0000000..fa1a347 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff @@ -0,0 +1,4 @@ +1c1 +< aX +--- +> bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c new file mode 100644 index 0000000..0e1ad99 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c @@ -0,0 +1,7 @@ +*** spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 +--- spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 +*************** +*** 1 **** +! aX +--- 1 ---- +! bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e new file mode 100644 index 0000000..13e0f7f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e @@ -0,0 +1,3 @@ +1c +bXaX +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f new file mode 100644 index 0000000..77710c7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f @@ -0,0 +1,3 @@ +c1 +bXaX +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u new file mode 100644 index 0000000..b84f718 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u @@ -0,0 +1,5 @@ +--- spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 ++++ spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 +@@ -1 +1 @@ +-aX ++bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef new file mode 100644 index 0000000..8b98efb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef @@ -0,0 +1,4 @@ +3c3 +< "description": "hi" +--- +> "description": "lo" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c new file mode 100644 index 0000000..efbfa19 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c @@ -0,0 +1,15 @@ +*** spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 +--- spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 +*************** +*** 1,4 **** + { + "name": "x", +! "description": "hi" + } +\ No newline at end of file +--- 1,4 ---- + { + "name": "x", +! "description": "lo" + } +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e new file mode 100644 index 0000000..775d881 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e @@ -0,0 +1,3 @@ +3c + "description": "lo" +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f new file mode 100644 index 0000000..9bf1e67 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f @@ -0,0 +1,3 @@ +c3 + "description": "lo" +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u new file mode 100644 index 0000000..dbacd88 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u @@ -0,0 +1,9 @@ +--- spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 ++++ spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 +@@ -1,4 +1,4 @@ + { + "name": "x", +- "description": "hi" ++ "description": "lo" + } +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 new file mode 100644 index 0000000..496b3dc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 @@ -0,0 +1,7 @@ +2d1 +< recipe[b::default] +14a14,17 +> recipe[o::new] +> recipe[p::new] +> recipe[q::new] +> recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c new file mode 100644 index 0000000..8349a7a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c @@ -0,0 +1,20 @@ +*** spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 +--- spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 +*************** +*** 1,5 **** + recipe[a::default] +- recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +--- 1,4 ---- +*************** +*** 12,14 **** +--- 11,17 ---- + recipe[l::default] + recipe[m::default] + recipe[n::default] ++ recipe[o::new] ++ recipe[p::new] ++ recipe[q::new] ++ recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d new file mode 100644 index 0000000..ca32a49 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d @@ -0,0 +1,7 @@ +d2 +a14 +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e new file mode 100644 index 0000000..89f3fa0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e @@ -0,0 +1,7 @@ +14a +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. +2d diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f new file mode 100644 index 0000000..ca32a49 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f @@ -0,0 +1,7 @@ +d2 +a14 +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u new file mode 100644 index 0000000..ef025c7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u @@ -0,0 +1,16 @@ +--- spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 ++++ spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 +@@ -1,5 +1,4 @@ + recipe[a::default] +-recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +@@ -12,3 +11,7 @@ + recipe[l::default] + recipe[m::default] + recipe[n::default] ++recipe[o::new] ++recipe[p::new] ++recipe[q::new] ++recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines new file mode 100644 index 0000000..e2afc31 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines @@ -0,0 +1,5 @@ +0a1,4 +> one +> two +> three +> four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c new file mode 100644 index 0000000..be0e827 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c @@ -0,0 +1,9 @@ +*** spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +--- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +*************** +*** 0 **** +--- 1,4 ---- ++ one ++ two ++ three ++ four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e new file mode 100644 index 0000000..f8f92fe --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e @@ -0,0 +1,6 @@ +0a +one +two +three +four +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f new file mode 100644 index 0000000..f02e5a0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f @@ -0,0 +1,6 @@ +a0 +one +two +three +four +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u new file mode 100644 index 0000000..60bd55c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u @@ -0,0 +1,7 @@ +--- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 ++++ spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +@@ -0,0 +1,4 @@ ++one ++two ++three ++four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty new file mode 100644 index 0000000..67d0a58 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty @@ -0,0 +1,5 @@ +1,4d0 +< one +< two +< three +< four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c new file mode 100644 index 0000000..b216344 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c @@ -0,0 +1,9 @@ +*** spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +--- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +*************** +*** 1,4 **** +- one +- two +- three +- four +--- 0 ---- diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e new file mode 100644 index 0000000..c821d7c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e @@ -0,0 +1 @@ +1,4d diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f new file mode 100644 index 0000000..442bd5a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f @@ -0,0 +1 @@ +d1 4 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u new file mode 100644 index 0000000..79e6d75 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u @@ -0,0 +1,7 @@ +--- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 ++++ spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +@@ -1,4 +0,0 @@ +-one +-two +-three +-four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context new file mode 100644 index 0000000..4335560 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context @@ -0,0 +1,4 @@ +1c1 +< 123 +--- +> 456 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c new file mode 100644 index 0000000..4b759fa --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c @@ -0,0 +1,9 @@ +*** spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 +--- spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 +*************** +*** 1,2 **** +! 123 + x +--- 1,2 ---- +! 456 + x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e new file mode 100644 index 0000000..7a8334b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e @@ -0,0 +1,3 @@ +1c +456 +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f new file mode 100644 index 0000000..97223a8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f @@ -0,0 +1,3 @@ +c1 +456 +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u new file mode 100644 index 0000000..7fbf0e2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u @@ -0,0 +1,6 @@ +--- spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 ++++ spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 +@@ -1,2 +1,2 @@ +-123 ++456 + x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 new file mode 100644 index 0000000..c5cb113 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 @@ -0,0 +1,5 @@ +4c4 +< four +--- +> four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c new file mode 100644 index 0000000..55d1ade --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c @@ -0,0 +1,14 @@ +*** spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +--- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +*************** +*** 1,4 **** + one + two + three +! four +--- 1,4 ---- + one + two + three +! four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u new file mode 100644 index 0000000..010518b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u @@ -0,0 +1,9 @@ +--- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 ++++ spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +@@ -1,4 +1,4 @@ + one + two + three +-four ++four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 new file mode 100644 index 0000000..10e4326 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 @@ -0,0 +1,5 @@ +4c4 +< four +\ No newline at end of file +--- +> four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c new file mode 100644 index 0000000..b431030 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c @@ -0,0 +1,14 @@ +*** spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +--- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +*************** +*** 1,4 **** + one + two + three +! four +\ No newline at end of file +--- 1,4 ---- + one + two + three +! four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u new file mode 100644 index 0000000..2481a9e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u @@ -0,0 +1,9 @@ +--- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 ++++ spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +@@ -1,4 +1,4 @@ + one + two + three +-four +\ No newline at end of file ++four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef new file mode 100644 index 0000000..d7babfe --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef @@ -0,0 +1,4 @@ +{ + "name": "x", + "description": "lo" +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 new file mode 100644 index 0000000..8213c73 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 @@ -0,0 +1,17 @@ +recipe[a::default] +recipe[c::default] +recipe[d::default] +recipe[e::default] +recipe[f::default] +recipe[g::default] +recipe[h::default] +recipe[i::default] +recipe[j::default] +recipe[k::default] +recipe[l::default] +recipe[m::default] +recipe[n::default] +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef new file mode 100644 index 0000000..5f9e38b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef @@ -0,0 +1,4 @@ +{ + "name": "x", + "description": "hi" +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 new file mode 100644 index 0000000..4a23407 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 @@ -0,0 +1,14 @@ +recipe[a::default] +recipe[b::default] +recipe[c::default] +recipe[d::default] +recipe[e::default] +recipe[f::default] +recipe[g::default] +recipe[h::default] +recipe[i::default] +recipe[j::default] +recipe[k::default] +recipe[l::default] +recipe[m::default] +recipe[n::default] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb new file mode 100644 index 0000000..7d91039 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require "spec_helper" + +if String.method_defined?(:encoding) + require "diff/lcs/hunk" + + describe Diff::LCS::Hunk do + let(:old_data) { ["Tu a un carté avec {count} itéms".encode("UTF-16LE")] } + let(:new_data) { ["Tu a un carte avec {count} items".encode("UTF-16LE")] } + let(:pieces) { Diff::LCS.diff old_data, new_data } + let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) } + + it "produces a unified diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -1 +1 @@ + -Tu a un carté avec {count} itéms + +Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:unified)).to eq(expected) + end + + it "produces a unified diff from the two pieces (last entry)" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -1 +1 @@ + -Tu a un carté avec {count} itéms + +Tu a un carte avec {count} items + \\ No newline at end of file + EXPECTED + + expect(hunk.diff(:unified, true)).to eq(expected) + end + + it "produces a context diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + *************** + *** 1 **** + ! Tu a un carté avec {count} itéms + --- 1 ---- + ! Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:context)).to eq(expected) + end + + it "produces an old diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp + 1c1 + < Tu a un carté avec {count} itéms + --- + > Tu a un carte avec {count} items + + EXPECTED + + expect(hunk.diff(:old)).to eq(expected) + end + + it "produces a reverse ed diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp + c1 + Tu a un carte avec {count} items + . + + EXPECTED + + expect(hunk.diff(:reverse_ed)).to eq(expected) + end + + context "with empty first data set" do + let(:old_data) { [] } + + it "produces a unified diff" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -0,0 +1 @@ + +Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:unified)).to eq(expected) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb new file mode 100644 index 0000000..5b0fb2a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require "spec_helper" +require "diff/lcs/hunk" + +describe "Diff::LCS Issues" do + include Diff::LCS::SpecHelper::Matchers + + describe "issue #1" do + shared_examples "handles simple diffs" do |s1, s2, forward_diff| + before do + @diff_s1_s2 = Diff::LCS.diff(s1, s2) + end + + it "creates the correct diff" do + expect(change_diff(forward_diff)).to eq(@diff_s1_s2) + end + + it "creates the correct patch s1->s2" do + expect(Diff::LCS.patch(s1, @diff_s1_s2)).to eq(s2) + end + + it "creates the correct patch s2->s1" do + expect(Diff::LCS.patch(s2, @diff_s1_s2)).to eq(s1) + end + end + + describe "string" do + it_has_behavior "handles simple diffs", "aX", "bXaX", [ + [ + ["+", 0, "b"], + ["+", 1, "X"] + ] + ] + it_has_behavior "handles simple diffs", "bXaX", "aX", [ + [ + ["-", 0, "b"], + ["-", 1, "X"] + ] + ] + end + + describe "array" do + it_has_behavior "handles simple diffs", %w[a X], %w[b X a X], [ + [ + ["+", 0, "b"], + ["+", 1, "X"] + ] + ] + it_has_behavior "handles simple diffs", %w[b X a X], %w[a X], [ + [ + ["-", 0, "b"], + ["-", 1, "X"] + ] + ] + end + end + + describe "issue #57" do + it "should fail with a correct error" do + # standard:disable Style/HashSyntax + expect { + actual = {:category => "app.rack.request"} + expected = {:category => "rack.middleware", :title => "Anonymous Middleware"} + expect(actual).to eq(expected) + }.to raise_error(RSpec::Expectations::ExpectationNotMetError) + # standard:enable Style/HashSyntax + end + end + + describe "issue #65" do + def diff_lines(old_lines, new_lines) + file_length_difference = 0 + previous_hunk = nil + output = [] + + Diff::LCS.diff(old_lines, new_lines).each do |piece| + hunk = Diff::LCS::Hunk.new(old_lines, new_lines, piece, 3, file_length_difference) + file_length_difference = hunk.file_length_difference + maybe_contiguous_hunks = previous_hunk.nil? || hunk.merge(previous_hunk) + + output << "#{previous_hunk.diff(:unified)}\n" unless maybe_contiguous_hunks + + previous_hunk = hunk + end + output << "#{previous_hunk.diff(:unified, true)}\n" unless previous_hunk.nil? + output.join + end + + it "should not misplace the new chunk" do + old_data = [ + "recipe[a::default]", "recipe[b::default]", "recipe[c::default]", + "recipe[d::default]", "recipe[e::default]", "recipe[f::default]", + "recipe[g::default]", "recipe[h::default]", "recipe[i::default]", + "recipe[j::default]", "recipe[k::default]", "recipe[l::default]", + "recipe[m::default]", "recipe[n::default]" + ] + + new_data = [ + "recipe[a::default]", "recipe[c::default]", "recipe[d::default]", + "recipe[e::default]", "recipe[f::default]", "recipe[g::default]", + "recipe[h::default]", "recipe[i::default]", "recipe[j::default]", + "recipe[k::default]", "recipe[l::default]", "recipe[m::default]", + "recipe[n::default]", "recipe[o::new]", "recipe[p::new]", + "recipe[q::new]", "recipe[r::new]" + ] + + # standard:disable Layout/HeredocIndentation + expect(diff_lines(old_data, new_data)).to eq(<<-EODIFF) +@@ -1,5 +1,4 @@ + recipe[a::default] +-recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +@@ -12,3 +11,7 @@ + recipe[l::default] + recipe[m::default] + recipe[n::default] ++recipe[o::new] ++recipe[p::new] ++recipe[q::new] ++recipe[r::new] + EODIFF + # standard:enable Layout/HeredocIndentation + end + end + + describe "issue #107 (replaces issue #60)" do + it "should produce unified output with correct context" do + # standard:disable Layout/HeredocIndentation + old_data = <<-DATA_OLD.strip.split("\n").map(&:chomp) +{ + "name": "x", + "description": "hi" +} + DATA_OLD + + new_data = <<-DATA_NEW.strip.split("\n").map(&:chomp) +{ + "name": "x", + "description": "lo" +} + DATA_NEW + + diff = ::Diff::LCS.diff(old_data, new_data) + hunk = ::Diff::LCS::Hunk.new(old_data, new_data, diff.first, 3, 0) + + expect(hunk.diff(:unified)).to eq(<<-EXPECTED.chomp) +@@ -1,4 +1,4 @@ + { + "name": "x", +- "description": "hi" ++ "description": "lo" + } + EXPECTED + # standard:enable Layout/HeredocIndentation + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb new file mode 100644 index 0000000..c17f22f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS::Internals, ".lcs" do + include Diff::LCS::SpecHelper::Matchers + + it "returns a meaningful LCS array with (seq1, seq2)" do + res = Diff::LCS::Internals.lcs(seq1, seq2) + # The result of the LCS (less the +nil+ values) must be as long as the + # correct result. + expect(res.compact.size).to eq(correct_lcs.size) + expect(res).to correctly_map_sequence(seq1).to_other_sequence(seq2) + + # Compact these transformations and they should be the correct LCS. + x_seq1 = (0...res.size).map { |ix| res[ix] ? seq1[ix] : nil }.compact + x_seq2 = (0...res.size).map { |ix| res[ix] ? seq2[res[ix]] : nil }.compact + + expect(x_seq1).to eq(correct_lcs) + expect(x_seq2).to eq(correct_lcs) + end + + it "returns all indexes with (hello, hello)" do + expect(Diff::LCS::Internals.lcs(hello, hello)).to \ + eq((0...hello.size).to_a) + end + + it "returns all indexes with (hello_ary, hello_ary)" do + expect(Diff::LCS::Internals.lcs(hello_ary, hello_ary)).to \ + eq((0...hello_ary.size).to_a) + end +end + +describe Diff::LCS, ".LCS" do + include Diff::LCS::SpecHelper::Matchers + + it "returns the correct compacted values from Diff::LCS.LCS" do + res = Diff::LCS.LCS(seq1, seq2) + expect(res).to eq(correct_lcs) + expect(res.compact).to eq(res) + end + + it "is transitive" do + res = Diff::LCS.LCS(seq2, seq1) + expect(res).to eq(correct_lcs) + expect(res.compact).to eq(res) + end + + it "returns %W(h e l l o) with (hello, hello)" do + expect(Diff::LCS.LCS(hello, hello)).to eq(hello.chars) + end + + it "returns hello_ary with (hello_ary, hello_ary)" do + expect(Diff::LCS.LCS(hello_ary, hello_ary)).to eq(hello_ary) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb new file mode 100644 index 0000000..e13b561 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "bin/ldiff" do + include CaptureSubprocessIO + + # standard:disable Style/HashSyntax + fixtures = [ + {:name => "diff", :left => "aX", :right => "bXaX", :diff => 1}, + {:name => "diff.missing_new_line1", :left => "four_lines", :right => "four_lines_with_missing_new_line", :diff => 1}, + {:name => "diff.missing_new_line2", :left => "four_lines_with_missing_new_line", :right => "four_lines", :diff => 1}, + {:name => "diff.issue95_trailing_context", :left => "123_x", :right => "456_x", :diff => 1}, + {:name => "diff.four_lines.vs.empty", :left => "four_lines", :right => "empty", :diff => 1}, + {:name => "diff.empty.vs.four_lines", :left => "empty", :right => "four_lines", :diff => 1}, + {:name => "diff.bin1", :left => "file1.bin", :right => "file1.bin", :diff => 0}, + {:name => "diff.bin2", :left => "file1.bin", :right => "file2.bin", :diff => 1}, + {:name => "diff.chef", :left => "old-chef", :right => "new-chef", :diff => 1}, + {:name => "diff.chef2", :left => "old-chef2", :right => "new-chef2", :diff => 1} + ].product([nil, "-e", "-f", "-c", "-u"]).map { |(fixture, flag)| + fixture = fixture.dup + fixture[:flag] = flag + fixture + } + # standard:enable Style/HashSyntax + + def self.test_ldiff(fixture) + desc = [ + fixture[:flag], + "spec/fixtures/#{fixture[:left]}", + "spec/fixtures/#{fixture[:right]}", + "#", + "=>", + "spec/fixtures/ldiff/output.#{fixture[:name]}#{fixture[:flag]}" + ].join(" ") + + it desc do + stdout, stderr, status = run_ldiff(fixture) + expect(status).to eq(fixture[:diff]) + expect(stderr).to eq(read_fixture(fixture, mode: "error", allow_missing: true)) + expect(stdout).to eq(read_fixture(fixture, mode: "output", allow_missing: false)) + end + end + + fixtures.each do |fixture| + test_ldiff(fixture) + end + + def read_fixture(options, mode: "output", allow_missing: false) + fixture = options.fetch(:name) + flag = options.fetch(:flag) + name = "spec/fixtures/ldiff/#{mode}.#{fixture}#{flag}" + + return "" if !::File.exist?(name) && allow_missing + + data = IO.__send__(IO.respond_to?(:binread) ? :binread : :read, name) + clean_data(data, flag) + end + + def clean_data(data, flag) + data = + case flag + when "-c", "-u" + clean_output_timestamp(data) + else + data + end + data.gsub(/\r\n?/, "\n") + end + + def clean_output_timestamp(data) + data.gsub( + %r{ + ^ + [-+*]{3} + \s* + spec/fixtures/(\S+) + \s* + \d{4}-\d\d-\d\d + \s* + \d\d:\d\d:\d\d(?:\.\d+) + \s* + (?:[-+]\d{4}|Z) + }x, + '*** spec/fixtures/\1 0000-00-00 :00 =>:00 =>00.000000000 -0000' + ) + end + + def run_ldiff(options) + flag = options.fetch(:flag) + left = options.fetch(:left) + right = options.fetch(:right) + + stdout, stderr = capture_subprocess_io do + system("ruby -Ilib bin/ldiff #{flag} spec/fixtures/#{left} spec/fixtures/#{right}") + end + + [clean_data(stdout, flag), stderr, $?.exitstatus] + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb new file mode 100644 index 0000000..8fc3ee2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb @@ -0,0 +1,416 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.patch" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "patch sequences correctly" do + it "correctly patches left-to-right (patch autodiscovery)" do + expect(Diff::LCS.patch(s1, patch_set)).to eq(s2) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(s1, patch_set, :patch)).to eq(s2) + expect(Diff::LCS.patch!(s1, patch_set)).to eq(s2) + end + + it "correctly patches right-to-left (unpatch autodiscovery)" do + expect(Diff::LCS.patch(s2, patch_set)).to eq(s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(s2, patch_set, :unpatch)).to eq(s1) + expect(Diff::LCS.unpatch!(s2, patch_set)).to eq(s1) + end + end + + describe "using a Diff::LCS.diff patchset" do + describe "an empty patchset returns the source" do + it "works on a string (hello)" do + diff = Diff::LCS.diff(hello, hello) + expect(Diff::LCS.patch(hello, diff)).to eq(hello) + end + + it "works on an array %W(h e l l o)" do + diff = Diff::LCS.diff(hello_ary, hello_ary) + expect(Diff::LCS.patch(hello_ary, diff)).to eq(hello_ary) + end + end + + describe "with default diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { Diff::LCS.diff(seq1, seq2) } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { Diff::LCS.diff(seq2, seq1) } + end + end + end + + describe "with context diff callbacks (ContextDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.diff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) + } + end + end + end + + describe "with sdiff callbacks (SDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.diff(seq1, seq2, Diff::LCS::SDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.diff(seq2, seq1, Diff::LCS::SDiffCallbacks) + } + end + end + end + end + + describe "using a Diff::LCS.sdiff patchset" do + describe "an empty patchset returns the source" do + it "works on a string (hello)" do + expect(Diff::LCS.patch(hello, Diff::LCS.sdiff(hello, hello))).to eq(hello) + end + + it "works on an array %W(h e l l o)" do + expect(Diff::LCS.patch(hello_ary, Diff::LCS.sdiff(hello_ary, hello_ary))).to eq(hello_ary) + end + end + + describe "with default diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.sdiff(seq1, seq2, Diff::LCS::DiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.sdiff(seq2, seq1, Diff::LCS::DiffCallbacks) + } + end + end + end + + describe "with context diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.sdiff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) + } + end + end + end + + describe "with sdiff callbacks (SDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { Diff::LCS.sdiff(seq1, seq2) } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { Diff::LCS.sdiff(seq2, seq1) } + end + end + end + end + + # Note: because of the error in autodiscovery ("does not autodiscover s1 + # to s2 patches"), this cannot use the "patch sequences correctly" shared + # set. Once the bug in autodiscovery is fixed, this can be converted as + # above. + describe "fix bug 891: patchsets do not contain the last equal part" do + before :each do + @s1 = %w[a b c d e f g h i j k] # standard:disable Layout/SpaceInsideArrayPercentLiteral + @s2 = %w[a b c d D e f g h i j k] + end + + describe "using Diff::LCS.diff with default diff callbacks" do + before :each do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.diff with context diff callbacks" do + before :each do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.diff with sdiff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::SDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::SDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with default sdiff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with context diff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with default diff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::DiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::DiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb new file mode 100644 index 0000000..aded301 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.sdiff" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "compare sequences correctly" do + it "compares s1 -> s2 correctly" do + expect(Diff::LCS.sdiff(s1, s2)).to eq(context_diff(result)) + end + + it "compares s2 -> s1 correctly" do + expect(Diff::LCS.sdiff(s2, s1)).to eq(context_diff(reverse_sdiff(result))) + end + end + + describe "using seq1 & seq2" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:result) { correct_forward_sdiff } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(abc def yyy xxx ghi jkl) & %w(abc dxf xxx ghi jkl)" do + let(:s1) { %w[abc def yyy xxx ghi jkl] } + let(:s2) { %w[abc dxf xxx ghi jkl] } + let(:result) { + # standard:disable Layout/ExtraSpacing + [ + ["=", [0, "abc"], [0, "abc"]], + ["!", [1, "def"], [1, "dxf"]], + ["-", [2, "yyy"], [2, nil]], + ["=", [3, "xxx"], [2, "xxx"]], + ["=", [4, "ghi"], [3, "ghi"]], + ["=", [5, "jkl"], [4, "jkl"]] + ] + # standard:enable Layout/ExtraSpacing + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c d e) & %w(a e)" do + let(:s1) { %w[a b c d e] } + let(:s2) { %w[a e] } + let(:result) { + [ + ["=", [0, "a"], [0, "a"]], + ["-", [1, "b"], [1, nil]], + ["-", [2, "c"], [1, nil]], + ["-", [3, "d"], [1, nil]], + ["=", [4, "e"], [1, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e) & %w(a b c d e)" do + let(:s1) { %w[a e] } + let(:s2) { %w[a b c d e] } + let(:result) { + [ + ["=", [0, "a"], [0, "a"]], + ["+", [1, nil], [1, "b"]], + ["+", [1, nil], [2, "c"]], + ["+", [1, nil], [3, "d"]], + ["=", [1, "e"], [4, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(v x a e) & %w(w y a b c d e)" do + let(:s1) { %w[v x a e] } + let(:s2) { %w[w y a b c d e] } + let(:result) { + [ + ["!", [0, "v"], [0, "w"]], + ["!", [1, "x"], [1, "y"]], + ["=", [2, "a"], [2, "a"]], + ["+", [3, nil], [3, "b"]], + ["+", [3, nil], [4, "c"]], + ["+", [3, nil], [5, "d"]], + ["=", [3, "e"], [6, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(x a e) & %w(a b c d e)" do + let(:s1) { %w[x a e] } + let(:s2) { %w[a b c d e] } + let(:result) { + [ + ["-", [0, "x"], [0, nil]], + ["=", [1, "a"], [0, "a"]], + ["+", [2, nil], [1, "b"]], + ["+", [2, nil], [2, "c"]], + ["+", [2, nil], [3, "d"]], + ["=", [2, "e"], [4, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e) & %w(x a b c d e)" do + let(:s1) { %w[a e] } + let(:s2) { %w[x a b c d e] } + let(:result) { + [ + ["+", [0, nil], [0, "x"]], + ["=", [0, "a"], [1, "a"]], + ["+", [1, nil], [2, "b"]], + ["+", [1, nil], [3, "c"]], + ["+", [1, nil], [4, "d"]], + ["=", [1, "e"], [5, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e v) & %w(x a b c d e w x)" do + let(:s1) { %w[a e v] } + let(:s2) { %w[x a b c d e w x] } + let(:result) { + [ + ["+", [0, nil], [0, "x"]], + ["=", [0, "a"], [1, "a"]], + ["+", [1, nil], [2, "b"]], + ["+", [1, nil], [3, "c"]], + ["+", [1, nil], [4, "d"]], + ["=", [1, "e"], [5, "e"]], + ["!", [2, "v"], [6, "w"]], + ["+", [3, nil], [7, "x"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w() & %w(a b c)" do + let(:s1) { %w[] } + let(:s2) { %w[a b c] } + let(:result) { + [ + ["+", [0, nil], [0, "a"]], + ["+", [0, nil], [1, "b"]], + ["+", [0, nil], [2, "c"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c) & %w(1)" do + let(:s1) { %w[a b c] } + let(:s2) { %w[1] } + let(:result) { + [ + ["!", [0, "a"], [0, "1"]], + ["-", [1, "b"], [1, nil]], + ["-", [2, "c"], [1, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c) & %w(c)" do + let(:s1) { %w[a b c] } + let(:s2) { %w[c] } + let(:result) { + [ + ["-", [0, "a"], [0, nil]], + ["-", [1, "b"], [0, nil]], + ["=", [2, "c"], [0, "c"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(abcd efgh ijkl mnop) & []" do + let(:s1) { %w[abcd efgh ijkl mnop] } + let(:s2) { [] } + let(:result) { + [ + ["-", [0, "abcd"], [0, nil]], + ["-", [1, "efgh"], [0, nil]], + ["-", [2, "ijkl"], [0, nil]], + ["-", [3, "mnop"], [0, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using [[1,2]] & []" do + let(:s1) { [[1, 2]] } + let(:s2) { [] } + let(:result) { + [ + ["-", [0, [1, 2]], [0, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb new file mode 100644 index 0000000..baaa3d0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb @@ -0,0 +1,376 @@ +# frozen_string_literal: true + +require "rubygems" +require "pathname" + +require "psych" if RUBY_VERSION >= "1.9" + +if ENV["COVERAGE"] + require "simplecov" + require "simplecov-lcov" + + SimpleCov::Formatter::LcovFormatter.config do |config| + config.report_with_single_file = true + config.lcov_file_name = "lcov.info" + end + + SimpleCov.start "test_frameworks" do + enable_coverage :branch + primary_coverage :branch + formatter SimpleCov::Formatter::MultiFormatter.new([ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::LcovFormatter, + SimpleCov::Formatter::SimpleFormatter + ]) + end +end + +file = Pathname.new(__FILE__).expand_path +path = file.parent +parent = path.parent + +$:.unshift parent.join("lib") + +module CaptureSubprocessIO + def _synchronize + yield + end + + def capture_subprocess_io + _synchronize { _capture_subprocess_io { yield } } + end + + def _capture_subprocess_io + require "tempfile" + + captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err") + + orig_stdout, orig_stderr = $stdout.dup, $stderr.dup + $stdout.reopen captured_stdout + $stderr.reopen captured_stderr + + yield + + $stdout.rewind + $stderr.rewind + + [captured_stdout.read, captured_stderr.read] + ensure + captured_stdout.unlink + captured_stderr.unlink + $stdout.reopen orig_stdout + $stderr.reopen orig_stderr + end + private :_capture_subprocess_io +end + +require "diff-lcs" + +module Diff::LCS::SpecHelper + def hello + "hello" + end + + def hello_ary + %w[h e l l o] + end + + def seq1 + %w[a b c e h j l m n p] + end + + def skipped_seq1 + %w[a h n p] + end + + def seq2 + %w[b c d e f j k l m r s t] + end + + def skipped_seq2 + %w[d f k r s t] + end + + def word_sequence + %w[abcd efgh ijkl mnopqrstuvwxyz] + end + + def correct_lcs + %w[b c e j l m] + end + + # standard:disable Layout/ExtraSpacing + def correct_forward_diff + [ + [ + ["-", 0, "a"] + ], + [ + ["+", 2, "d"] + ], + [ + ["-", 4, "h"], + ["+", 4, "f"] + ], + [ + ["+", 6, "k"] + ], + [ + ["-", 8, "n"], + ["+", 9, "r"], + ["-", 9, "p"], + ["+", 10, "s"], + ["+", 11, "t"] + ] + ] + end + + def correct_backward_diff + [ + [ + ["+", 0, "a"] + ], + [ + ["-", 2, "d"] + ], + [ + ["-", 4, "f"], + ["+", 4, "h"] + ], + [ + ["-", 6, "k"] + ], + [ + ["-", 9, "r"], + ["+", 8, "n"], + ["-", 10, "s"], + ["+", 9, "p"], + ["-", 11, "t"] + ] + ] + end + + def correct_forward_sdiff + [ + ["-", [0, "a"], [0, nil]], + ["=", [1, "b"], [0, "b"]], + ["=", [2, "c"], [1, "c"]], + ["+", [3, nil], [2, "d"]], + ["=", [3, "e"], [3, "e"]], + ["!", [4, "h"], [4, "f"]], + ["=", [5, "j"], [5, "j"]], + ["+", [6, nil], [6, "k"]], + ["=", [6, "l"], [7, "l"]], + ["=", [7, "m"], [8, "m"]], + ["!", [8, "n"], [9, "r"]], + ["!", [9, "p"], [10, "s"]], + ["+", [10, nil], [11, "t"]] + ] + end + # standard:enable Layout/ExtraSpacing + + def reverse_sdiff(forward_sdiff) + forward_sdiff.map { |line| + line[1], line[2] = line[2], line[1] + case line[0] + when "-" then line[0] = "+" + when "+" then line[0] = "-" + end + line + } + end + + def change_diff(diff) + map_diffs(diff, Diff::LCS::Change) + end + + def context_diff(diff) + map_diffs(diff, Diff::LCS::ContextChange) + end + + def format_diffs(diffs) + diffs.map { |e| + if e.is_a?(Array) + e.map { |f| f.to_a.join }.join(", ") + else + e.to_a.join + end + }.join("\n") + end + + def map_diffs(diffs, klass = Diff::LCS::ContextChange) + diffs.map do |chunks| + if klass == Diff::LCS::ContextChange + klass.from_a(chunks) + else + chunks.map { |changes| klass.from_a(changes) } + end + end + end + + def balanced_traversal(s1, s2, callback_type) + callback = __send__(callback_type) + Diff::LCS.traverse_balanced(s1, s2, callback) + callback + end + + def balanced_reverse(change_result) + new_result = [] + change_result.each do |line| + line = [line[0], line[2], line[1]] + case line[0] + when "<" + line[0] = ">" + when ">" + line[0] = "<" + end + new_result << line + end + new_result.sort_by { |line| [line[1], line[2]] } + end + + def map_to_no_change(change_result) + new_result = [] + change_result.each do |line| + case line[0] + when "!" + new_result << ["<", line[1], line[2]] + new_result << [">", line[1] + 1, line[2]] + else + new_result << line + end + end + new_result + end + + class SimpleCallback + def initialize + reset + end + + attr_reader :matched_a + attr_reader :matched_b + attr_reader :discards_a + attr_reader :discards_b + attr_reader :done_a + attr_reader :done_b + + def reset + @matched_a = [] + @matched_b = [] + @discards_a = [] + @discards_b = [] + @done_a = [] + @done_b = [] + self + end + + def match(event) + @matched_a << event.old_element + @matched_b << event.new_element + end + + def discard_b(event) + @discards_b << event.new_element + end + + def discard_a(event) + @discards_a << event.old_element + end + + def finished_a(event) + @done_a << [ + event.old_element, event.old_position, + event.new_element, event.new_position + ] + end + + def finished_b(event) + @done_b << [ + event.old_element, event.old_position, + event.new_element, event.new_position + ] + end + end + + def simple_callback + SimpleCallback.new + end + + class SimpleCallbackNoFinishers < SimpleCallback + undef :finished_a + undef :finished_b + end + + def simple_callback_no_finishers + SimpleCallbackNoFinishers.new + end + + class BalancedCallback + def initialize + reset + end + + attr_reader :result + + def reset + @result = [] + end + + def match(event) + @result << ["=", event.old_position, event.new_position] + end + + def discard_a(event) + @result << ["<", event.old_position, event.new_position] + end + + def discard_b(event) + @result << [">", event.old_position, event.new_position] + end + + def change(event) + @result << ["!", event.old_position, event.new_position] + end + end + + def balanced_callback + BalancedCallback.new + end + + class BalancedCallbackNoChange < BalancedCallback + undef :change + end + + def balanced_callback_no_change + BalancedCallbackNoChange.new + end + + module Matchers + extend RSpec::Matchers::DSL + + matcher :be_nil_or_match_values do |ii, s1, s2| + match do |ee| + expect(ee).to(satisfy { |vee| vee.nil? || s1[ii] == s2[ee] }) + end + end + + matcher :correctly_map_sequence do |s1| + match do |actual| + actual.each_index { |ii| expect(actual[ii]).to be_nil_or_match_values(ii, s1, @s2) } + end + + chain :to_other_sequence do |s2| + @s2 = s2 + end + end + end +end + +RSpec.configure do |conf| + conf.include Diff::LCS::SpecHelper + conf.alias_it_should_behave_like_to :it_has_behavior, "has behavior:" + # standard:disable Style/HashSyntax + conf.filter_run_excluding :broken => true + # standard:enable Style/HashSyntax +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb new file mode 100644 index 0000000..3a3f677 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb @@ -0,0 +1,312 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.traverse_balanced" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "with a #change callback" do |s1, s2, result| + it "traverses s1 -> s2 correctly" do + traversal = balanced_traversal(s1, s2, :balanced_callback) + expect(traversal.result).to eq(result) + end + + it "traverses s2 -> s1 correctly" do + traversal = balanced_traversal(s2, s1, :balanced_callback) + expect(traversal.result).to eq(balanced_reverse(result)) + end + end + + shared_examples "without a #change callback" do |s1, s2, result| + it "traverses s1 -> s2 correctly" do + traversal = balanced_traversal(s1, s2, :balanced_callback_no_change) + expect(traversal.result).to eq(map_to_no_change(result)) + end + + it "traverses s2 -> s1 correctly" do + traversal = balanced_traversal(s2, s1, :balanced_callback_no_change) + expect(traversal.result).to eq(map_to_no_change(balanced_reverse(result))) + end + end + + describe "identical string sequences ('abc')" do + s1 = s2 = "abc" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "identical array sequences %w(a b c)" do + s1 = s2 = %w[a b c] + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a b c) & %w(a x c)" do + s1 = %w[a b c] + s2 = %w[a x c] + + result = [ + ["=", 0, 0], + ["!", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a x y c) & %w(a v w c)" do + s1 = %w[a x y c] + s2 = %w[a v w c] + + result = [ + ["=", 0, 0], + ["!", 1, 1], + ["!", 2, 2], + ["=", 3, 3] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(x y c) & %w(v w c)" do + s1 = %w[x y c] + s2 = %w[v w c] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a x y z) & %w(b v w)" do + s1 = %w[a x y z] + s2 = %w[b v w] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["!", 2, 2], + ["<", 3, 3] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a z) & %w(a)" do + s1 = %w[a z] + s2 = %w[a] + result = [ + ["=", 0, 0], + ["<", 1, 1] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(z a) & %w(a)" do + s1 = %w[z a] + s2 = %w[a] + result = [ + ["<", 0, 0], + ["=", 1, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a b c) & %w(x y z)" do + s1 = %w[a b c] + s2 = %w[x y z] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["!", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(abcd efgh ijkl mnoopqrstuvwxyz) & []" do + s1 = %w[abcd efgh ijkl mnopqrstuvwxyz] + s2 = [] + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["<", 2, 0], + ["<", 3, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a b c) & %q(a x c)" do + s1 = "a b c" + s2 = "a x c" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["=", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a x y c) & %q(a v w c)" do + s1 = "a x y c" + s2 = "a v w c" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4], + ["=", 5, 5], + ["=", 6, 6] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(x y c) & %q(v w c)" do + s1 = "x y c" + s2 = "v w c" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["=", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a x y z) & %q(b v w)" do + s1 = "a x y z" + s2 = "b v w" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4], + ["<", 5, 5], + ["<", 6, 5] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a z) & %q(a)" do + s1 = "a z" + s2 = "a" + result = [ + ["=", 0, 0], + ["<", 1, 1], + ["<", 2, 1] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(z a) & %q(a)" do + s1 = "z a" + s2 = "a" + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["=", 2, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a b c) & %q(x y z)" do + s1 = "a b c" + s2 = "x y z" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(abcd efgh ijkl mnopqrstuvwxyz) & %q()" do + s1 = "abcd efgh ijkl mnopqrstuvwxyz" + s2 = "" + # standard:disable Layout/ExtraSpacing + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["<", 2, 0], + ["<", 3, 0], + ["<", 4, 0], + ["<", 5, 0], + ["<", 6, 0], + ["<", 7, 0], + ["<", 8, 0], + ["<", 9, 0], + ["<", 10, 0], + ["<", 11, 0], + ["<", 12, 0], + ["<", 13, 0], + ["<", 14, 0], + ["<", 15, 0], + ["<", 16, 0], + ["<", 17, 0], + ["<", 18, 0], + ["<", 19, 0], + ["<", 20, 0], + ["<", 21, 0], + ["<", 22, 0], + ["<", 23, 0], + ["<", 24, 0], + ["<", 25, 0], + ["<", 26, 0], + ["<", 27, 0], + ["<", 28, 0] + ] + # standard:enable Layout/ExtraSpacing + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb new file mode 100644 index 0000000..8e9928f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.traverse_sequences" do + describe "callback with no finishers" do + describe "over (seq1, seq2)" do + before(:each) do + @callback_s1_s2 = simple_callback_no_finishers + Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) + + @callback_s2_s1 = simple_callback_no_finishers + Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) + end + + it "has the correct LCS result on left-matches" do + expect(@callback_s1_s2.matched_a).to eq(correct_lcs) + expect(@callback_s2_s1.matched_a).to eq(correct_lcs) + end + + it "has the correct LCS result on right-matches" do + expect(@callback_s1_s2.matched_b).to eq(correct_lcs) + expect(@callback_s2_s1.matched_b).to eq(correct_lcs) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) + expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) + expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback_s1_s2.done_a).to be_empty + expect(@callback_s1_s2.done_b).to be_empty + expect(@callback_s2_s1.done_a).to be_empty + expect(@callback_s2_s1.done_b).to be_empty + end + end + + describe "over (hello, hello)" do + before(:each) do + @callback = simple_callback_no_finishers + Diff::LCS.traverse_sequences(hello, hello, @callback) + end + + it "has the correct LCS result on left-matches" do + expect(@callback.matched_a).to eq(hello.chars) + end + + it "has the correct LCS result on right-matches" do + expect(@callback.matched_b).to eq(hello.chars) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback.discards_a).to be_empty + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback.discards_b).to be_empty + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback.done_a).to be_empty + expect(@callback.done_b).to be_empty + end + end + + describe "over (hello_ary, hello_ary)" do + before(:each) do + @callback = simple_callback_no_finishers + Diff::LCS.traverse_sequences(hello_ary, hello_ary, @callback) + end + + it "has the correct LCS result on left-matches" do + expect(@callback.matched_a).to eq(hello_ary) + end + + it "has the correct LCS result on right-matches" do + expect(@callback.matched_b).to eq(hello_ary) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback.discards_a).to be_empty + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback.discards_b).to be_empty + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback.done_a).to be_empty + expect(@callback.done_b).to be_empty + end + end + end + + describe "callback with finisher" do + before(:each) do + @callback_s1_s2 = simple_callback + Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) + @callback_s2_s1 = simple_callback + Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) + end + + it "has the correct LCS result on left-matches" do + expect(@callback_s1_s2.matched_a).to eq(correct_lcs) + expect(@callback_s2_s1.matched_a).to eq(correct_lcs) + end + + it "has the correct LCS result on right-matches" do + expect(@callback_s1_s2.matched_b).to eq(correct_lcs) + expect(@callback_s2_s1.matched_b).to eq(correct_lcs) + end + + it "has the correct skipped sequences for the left sequence" do + expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) + expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) + end + + it "has the correct skipped sequences for the right sequence" do + expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) + expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) + end + + it "has done markers differently-sized sequences" do + expect(@callback_s1_s2.done_a).to eq([["p", 9, "t", 11]]) + expect(@callback_s1_s2.done_b).to be_empty + + expect(@callback_s2_s1.done_a).to be_empty + expect(@callback_s2_s1.done_b).to eq([["t", 11, "p", 9]]) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc new file mode 100644 index 0000000..51e9f71 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc @@ -0,0 +1,2454 @@ +=== 13.2.1 + +* Suppressed "internal:array:52:in 'Array#each'" from backtrace by @hsbt in #554 +* Bump actions/configure-pages from 4 to 5 by @dependabot in #553 + +=== 13.2.0 + +* Fix rule example to be correct by @zenspider in #525 +* Switch to use test-unit by @hsbt in #536 +* Removed redundant block by @hsbt in #537 +* Use Struct instead of OpenStruct. by @hsbt in #545 +* Accept FileList object as directory task's target by @gemmaro in #530 +* Fix exception when exception has nil backtrace by @janbiedermann in #451 +* Add TruffleRuby on CI by @andrykonchin in #551 + +=== 13.1.0 + +* Added dependabot.yml for actions by @hsbt in #416 +* Add Ruby 3.1 to the CI matrix by @petergoldstein in #415 +* (Performance) Remove unnecessary I/O syscalls for FileTasks by @da2x in #393 +* Skip test failure with JRuby by @hsbt in #418 +* Remove bin/rdoc by @tnir in #421 +* Remove bin/rake by @tnir in #422 +* Remove bin/bundle by @tnir in #425 +* Apply RuboCop linting for Ruby 2.3 by @tnir in #423 +* Update rubocop to work with Ruby 2.4 compatible by @tnir in #424 +* chore: fix typo in comments by @tnir in #429 +* Use 'test' as workflow name on Actions by @tnir in #427 +* docs: update CONTRIBUTING.rdoc by @tnir in #428 +* Add RuboCop job to Actions by @tnir in #426 +* Lock minitest-5.15.0 for Ruby 2.2 by @hsbt in #442 +* Eagerly require set in thread_pool.rb by @jeremyevans in #440 +* Avoid creating an unnecessary thread pool by @jeremyevans in #441 +* Add credit for maintenance in Rake 12/13 by @tnir in #443 +* Sh fully echoes commands which error exit by @MarkDBlackwell in #147 +* Correct RuboCop offenses by @deivid-rodriguez in #444 +* [StepSecurity] ci: Harden GitHub Actions by @step-security-bot in #450 +* Add ruby 3.2 to test matrix by @hanneskaeufler in #458 +* Missing 'do' on example by @zzak in #467 +* Try to use dependabot automerge by @hsbt in #470 +* Rewrite auto-merge feature for dependabot by @hsbt in #471 +* Update bundler in Dependabot by @ono-max in #472 +* Fix grammar in help text by @mebezac in #381 +* Try to use ruby/ruby/.github/workflows/ruby_versions.yml@master by @hsbt in #475 +* Use GitHub Pages Action for generating rdoc page by @hsbt in #477 +* Support #detailed_message when task failed by @ksss in #486 +* Debug at stop when task fail by @ksss in #489 +* Drop to support Ruby 2.2 by @hsbt in #492 +* Bump up setup-ruby by @hsbt in #497 +* Update development dependencies by @hsbt in #505 + +=== 13.0.6 + +* Additional fix for #389 + Pull request #390 by hsbt + +=== 13.0.5 + +* Fixed the regression of #388 + Pull request #389 by hsbt + +=== 13.0.4 + +* Fix rake test loader swallowing useful error information. + Pull request #367 by deivid-rodriguez +* Add -C/--directory option the same as GNU make. + Pull request #376 by nobu + +=== 13.0.3 + +* Fix breaking change of execution order on TestTask. + Pull request #368 by ysakasin + +=== 13.0.2 + +==== Enhancements + +* Fix tests to work with current FileUtils + Pull Request #358 by jeremyevans +* Simplify default rake test loader + Pull Request #357 by deivid-rodriguez +* Update rdoc + Pull Request #366 by bahasalien +* Update broken links to rake articles from Avdi in README + Pull Request #360 by svl7 + +=== 13.0.1 + +==== Bug fixes + +* Fixed bug: Reenabled task raises previous exception on second invokation + Pull Request #271 by thorsteneckel +* Fix an incorrectly resolved arg pattern + Pull Request #327 by mjbellantoni + +=== 13.0.0 + +==== Enhancements + +* Follows recent changes on keyword arguments in ruby 2.7. + Pull Request #326 by nobu +* Make `PackageTask` be able to omit parent directory while packing files + Pull Request #310 by tonytonyjan +* Add order only dependency + Pull Request #269 by take-cheeze + +==== Compatibility changes + +* Drop old ruby versions(< 2.2) + +=== 12.3.3 + +==== Bug fixes + +* Use the application's name in error message if a task is not found. + Pull Request #303 by tmatilai + +==== Enhancements: + +* Use File.open explicitly. + +=== 12.3.2 + +==== Bug fixes + +* Fixed test fails caused by 2.6 warnings. + Pull Request #297 by hsbt + +==== Enhancements: + +* Rdoc improvements. + Pull Request #293 by colby-swandale +* Improve multitask performance. + Pull Request #273 by jsm +* Add alias `prereqs`. + Pull Request #268 by take-cheeze + +=== 12.3.1 + +==== Bug fixes + +* Support did_you_mean >= v1.2.0 which has a breaking change on formatters. + Pull request #262 by FUJI Goro. + +==== Enhancements: + +* Don't run task if it depends on already invoked but failed task. + Pull request #252 by Gonzalo Rodriguez. +* Make space trimming consistent for all task arguments. + Pull request #259 by Gonzalo Rodriguez. +* Removes duplicated inclusion of Rake::DSL in tests. + Pull request #254 by Gonzalo Rodriguez. +* Re-raise a LoadError that didn't come from require in the test loader. + Pull request #250 by Dylan Thacker-Smith. + +=== 12.3.0 + +==== Compatibility Changes + +* Bump `required_ruby_version` to Ruby 2.0.0. Rake has already + removed support for Ruby 1.9.x. + +==== Enhancements: + +* Support `test-bundled-gems` task on ruby core. + +=== 12.2.1 + +==== Bug fixes + +* Fixed to break Capistrano::Application on capistrano3. + +=== 12.2.0 + +==== Enhancements: + +* Make rake easier to use as a library + Pull request #211 by @drbrain +* Fix quadratic performance in FileTask#out_of_date? + Pull request #224 by @doudou +* Clarify output when printing nested exception traces + Pull request #232 by @urbanautomaton + +==== Bug fixes + +* Account for a file that match 2 or more patterns. + Pull request #231 by @styd + +=== 12.1.0 + +==== Enhancements: + +* Added did_you_mean feature for invalid rake task. + Pull request #221 by @xtina-starr +* Enabled to dependency chained by extensions. Pull request #39 by Petr Skocik. +* Make all of string literals to frozen objects on Ruby 2.4 or later. + +==== Bug fixes + +* Typo fixes in rakefile.rdoc. Pull request #180 by Yuta Kurotaki. +* Fix unexpected behavior of file task with dryrun option. + Pull request #183 by @aycabta. +* Make LoadError from running tests more obvious. Pull request #195 + by Eric Hodel. +* Fix unexpected TypeError with hash style option. Pull request #202 + by Kuniaki IGARASHI. + +=== 12.0.0 + +==== Compatibility Changes + +* Removed arguments on clear #157 by Jesse Bowes +* Removed `rake/contrib` packages. These are extracted to `rake-contrib` gem. +* Removed deprecated method named `last\_comment`. + +==== Enhancements: + +* Re-use trace option on `cleanup` task. #164 by Brian Henderson +* Actions adore keyword arguments #174 by Josh Cheek +* Rake::TaskArguments#key? alias of #has_key? #175 by Paul Annesley + +=== 11.3.0 / 2016-09-20 + +==== Enhancements: + +* Remove to reference `Fixnum` constant. Pull request #160 by nobu + +=== 11.2.2 / 2016-06-12 + +==== Bug fixes + +* Fix unexpected behavior with multiple dependencies on Rake::TestTask + +=== 11.2.1 / 2016-06-12 + +==== Bug fixes + +* Fix regression of dependencies handling on Rake::TestTask. Report #139 + +=== 11.2.0 / 2016-06-11 + +==== Bug fixes + +* Fix unexpected cut-out behavior on task description using triple dots + and exclamation. Report #106 from Stephan Kämper and Pull request #134 by Lee +* Fix empty argument assignment with `with_defaults` option. Pull request #135 + by bakunyo +* Ignore to use `hwprefs` on Darwin platform. Use sysctl now. Report #128 + +==== Enhancements + +* Spawn options for sh Pull equest #138 by Eric Hodel. +* Allow to specify dependencies(prerequisites) for Rake::TestTask + Pull request #117 by Tim Maslyuchenko +* Use Bundler task instead of hoe for gem release. +* Remove explicitly load to rubygems for Ruby 1.8. +* Unify to declare `Rake::VERSION`. +* Support xz format for PackageTask. + +=== 11.1.2 / 2016-03-28 + +==== Bug fixes + +* Remove `-W` option when Rake::TestTask#verbose enabled. It's misunderstanding + specification change with Rake 11. Partly revert #67 + +=== 11.1.1 / 2016-03-14 + +==== Bug fixes + +* Use `-W` instead of `--verbose` when Rake::TestTask#verbose enabled. + JRuby doesn't have `--verbose` option. + +=== 11.1.0 / 2016-03-11 + +==== Compatibility Changes + +* Revert to remove `last\_comment`. It will remove Rake 12. + +=== 11.0.1 / 2016-03-09 + +==== Bug fixes + +* Fixed packaging manifest. + +=== 11.0.0 / 2016-03-09 + +==== Bug fixes + +* Correctly handle bad encoding in exception messages. Pull request #113 + by Tomer Brisker +* Fix verbose option at TestTask. Pull request #67 by Mike Blumtritt + +==== Enhancements + +* Make FileList#exclude more analogous to FileList#include. +* Use IO.open instead of Open3.popen3 for CPU counter. +* Make Rake::Task#already_invoked publicly accessible. + Pull request #93 by Joe Rafaniello +* Lookup prerequisites with same name outside of scope instead of + matching self. Pull request #96 by Sandy Vanderbleek +* Make FileList#pathmap behave like String#pathmap. + Pull request #61 by Daniel Tamai +* Add fetch method to task arguments. + Pull request #12 by Chris Keathley +* Use ruby warnings by default. Pull request #97 by Harold Giménez + +==== Compatibility Changes + +* Removed to support Ruby 1.8.x +* Removed constant named `RAKEVERSION` +* Removed Rake::AltSystem +* Removed Rake::RubyForgePublisher +* Removed Rake::TaskManager#last\_comment. Use last\_description. +* Removed Rake::TaskLib#paste +* Removed Top-level SshDirPublisher, SshFreshDirPublisher, SshFilePublisher + and CompositePublisher from lib/rake/contrib/publisher.rb +* Removed "rake/runtest.rb" + +=== 10.5.0 / 2016-01-13 + +==== Enhancements + +* Removed monkey patching for Ruby 1.8. Pull request #46 by Pablo Herrero. +* Inheritance class of Rake::FileList returns always self class. + Pull request #74 by Thomas Scholz + +=== 10.4.2 / 2014-12-02 + +==== Bug fixes + +* Rake no longer edits ARGV. This allows you to re-exec rake from a rake + task. Pull requset #9 by Matt Palmer. +* Documented how Rake::DSL#desc handles sentences in task descriptions. + Issue #7 by Raza Sayed. +* Fixed test error on 1.9.3 with legacy RubyGems. Issue #8 by Matt Palmer. +* Deleted duplicated History entry. Pull request #10 by Yuji Yamamoto. + +=== 10.4.1 / 2014-12-01 + +==== Bug fixes + +* Reverted fix for #277 as it caused numerous issues for rake users. + rails/spring issue #366 by Gustavo Dutra. + +=== 10.4.0 / 2014-11-22 + +==== Enhancements + +* Upgraded to minitest 5. Pull request #292 by Teo Ljungberg. +* Added support for Pathname in rake tasks. Pull request #271 by Randy + Coulman. +* Rake now ignores falsy dependencies which allows for easier programmatic + creation of tasks. Pull request #273 by Manav. +* Rake no longer edits ARGV. This allows you to re-exec rake from a rake + task. Issue #277 by Matt Palmer. +* Etc.nprocessors is used for counting the number of CPUs. + +==== Bug fixes + +* Updated rake manpage. Issue #283 by Nathan Long, pull request #291 by + skittleys. +* Add Rake::LATE to allow rebuilding of files that depend on deleted files. + Bug #286, pull request #287 by David Grayson. +* Fix relinking of files when repackaging. Bug #276 by Muenze. +* Fixed some typos. Pull request #280 by Jed Northridge. +* Try counting CPUs via cpuinfo if host_os was not matched. Pull request + #282 by Edouard B. + +=== 10.3.2 / 2014-05-15 + +==== Bug fixes + +* Rake no longer infinitely loops when showing exception causes that refer to + each other. Bug #272 by Chris Bandy. +* Fixed documentation typos. Bug #275 by Jake Worth. + +=== 10.3.1 / 2014-04-17 + +==== Bug fixes + +* Really stop reporting an error when cleaning already-deleted files. Pull + request #269 by Randy Coulman +* Fixed infinite loop when cleaning already-deleted files on windows. + +=== 10.3 / 2014-04-15 + +==== Enhancements + +* Added --build-all option to rake which treats all file prerequisites as + out-of-date. Pull request #254 by Andrew Gilbert. +* Added Rake::NameSpace#scope. Issue #263 by Jon San Miguel. + +==== Bug fixes + +* Suppress org.jruby package files in rake error messages for JRuby users. + Issue #213 by Charles Nutter. +* Fixed typo, removed extra "h". Pull request #267 by Hsing-Hui Hsu. +* Rake no longer reports an error when cleaning already-deleted files. Pull + request #266 by Randy Coulman. +* Consume stderr while determining CPU count to avoid hang. Issue #268 by + Albert Sun. + +=== 10.2.2 / 2014-03-27 + +==== Bug fixes + +* Restored Ruby 1.8.7 compatibility + +=== 10.2.1 / 2014-03-25 + +==== Bug fixes + +* File tasks including a ':' are now top-level tasks again. Issue #262 by + Josh Holtrop. +* Use sysctl for CPU count for all BSDs. Pull request #261 by Joshua Stein. +* Fixed CPU detection for unknown platforms. + +=== 10.2.0 / 2014-03-24 + +==== Enhancements + +* Rake now requires Ruby 1.9 or newer. For me, this is a breaking change, but + it seems that Jim planned to release it with Rake 10.2. See also pull + request #247 by Philip Arndt. +* Rake now allows you to declare tasks under a namespace like: + + task 'a:b' do ... end + + Pull request #232 by Judson Lester. +* Task#source defaults to the first prerequisite in non-rule tasks. Pull + request #215 by Avdi Grimm. +* Rake now automatically rebuilds and reloads imported files. Pull request + #209 by Randy Coulman. +* The rake task arguments can contain escaped commas. Pull request #214 by + Filip Hrbek. +* Rake now prints the exception class on errors. Patch #251 by David Cornu. + +==== Bug fixes + +* Fixed typos. Pull request #256 by Valera Rozuvan, #250 via Jake Worth, #260 + by Zachary Scott. +* Fixed documentation for calling tasks with arguments. Pull request #235 by + John Varghese. +* Clarified `rake -f` usage message. Pull request #252 by Marco Pfatschbacher. +* Fixed a test failure on windows. Pull request #231 by Hiroshi Shirosaki. +* Fixed corrupted rake.1.gz. Pull request #225 by Michel Boaventura. +* Fixed bug in can\_detect\_signals? in test. Patch from #243 by Alexey + Borzenkov. + +=== 10.1.1 + +* Use http://github.com/jimweirich/rake instead of http://rake.rubyforge.org for + canonical project url. + +=== 10.1.0 + +==== Changes + +===== New Features + +* Add support for variable length task argument lists. If more actual + arguments are supplied than named arguments, then the extra + arguments values will be in args.extras. + +* Application name is not displayed in the help banner. (Previously + "rake" was hardcoded, now rake-based applications can display their + own names). + +===== Bug Fixes + +Bug fixes include: + +* Fix backtrace suppression issues. + +* Rules now explicit get task arguments passed to them. + +* Rename FileList#exclude? to FileList#exclude\_from\_list? to avoid + conflict with new Rails method. + +* Clean / Clobber tasks now report failure to remove files. + +* Plus heaps of internal code cleanup. + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. +The following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Michael Nikitochkin (general code cleanup) +* Vipul A M (general code cleanup) +* Dennis Bell (variable length task argument lists) +* Jacob Swanner (rules arguments) +* Rafael Rosa Fu (documentation typo) +* Stuart Nelson (install.rb fixes) +* Lee Hambley (application name in help banner) + +-- Jim Weirich + +=== 10.0.3 + + "Jim, when will Rake reach version 1.0?" + +Over the past several years I've been asked that question at +conferences, panels and over twitter. Due to historical reasons (or +maybe just plain laziness) Rake has (incorrectly) been treating the +second digit of the version as the major release number. So in my head +Rake was already at version 9. + +Well, it's time to fix things. This next version of Rake drops old, +crufty, backwards compatibility hacks such as top level constants, DSL +methods defined in Object and numerous other features that are just no +longer desired. It's also time to drop the leading zero from the +version number as well and call this new version of rake what it +really is: Version 10. + +So, welcome to Rake 10.0! + +Rake 10 is actually feature identical to the latest version of Rake 9 +(that would be the version spelled 0.9.3), *except* that Rake 10 drops +all the sundry deprecated features that have accumulated over the years. + +If your Rakefile is up to date and current with all the new features +of Rake 10, you are ready to go. If your Rakefile still uses a few +deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same +feature set. Just be aware that future features will be in Rake 10 +family line. + +==== Changes + +As mentioned above, there are no new features in Rake 10. However, +there are a number of features missing: + +* Classic namespaces are now gone. Rake is no longer able to reflect + the options settings in the global variables ($rakefile, $show\_tasks, + $show\_prereqs, $trace, $dryrun and $silent). The + --classic-namespace option is no longer supported. + +* Global constants are no longer supported. This includes + Task, FileTask, FileCreationTask and + RakeApp). The constant missing hook to warn about using + global rake constants has been removed. + +* The Rake DSL methods (task, file, directory, etc) are in their own + module (Rake::DSL). The stub versions of these methods (that printed + warnings) in Object have been removed. However, the DSL methods are + added to the top-level main object. Since main is + not in the inheritance tree, the presence of the DSL methods in main + should be low impact on other libraries. + + If you want to use the Rake DSL commands from your own code, just + include Rake::DSL into your own classes and modules. + +* The deprecated syntax for task arguments (the one using + :needs) has been removed. + +* The --reduce-compat flag has been removed (it's not needed + anymore). + +* The deprecated rake/sys.rb library has been removed. + +* The deprecated rake/rdoctask.rb library has been removed. + RDoc supplies its own rake task now. + +* The deprecated rake/gempackagetask.rb library has been + removed. Gem supplies its own package task now. + +There is one small behavioral change: + +* Non-file tasks now always report the current time as their time + stamp. This is different from the previous behavior where non-file + tasks reported current time only if there were no prerequisites, and + the max prerequisite timestamp otherwise. This lead to inconsistent + and surprising behavior when adding prerequisites to tasks that in + turn were prequisites to file tasks. The new behavior is more + consistent and predictable. + +==== Changes (from 0.9.3, 0.9.4, 0.9.5) + +Since Rake 10 includes the changes from the last version of Rake 9, +we'll repeat the changes for versions 0.9.3 through 0.9.5 here. + +===== New Features (in 0.9.3) + +* Multitask tasks now use a thread pool. Use -j to limit the number of + available threads. + +* Use -m to turn regular tasks into multitasks (use at your own risk). + +* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to + programatically add rake task libraries. + +* You can specific backtrace suppression patterns (see + --suppress-backtrace) + +* Directory tasks can now take prerequisites and actions + +* Use --backtrace to request a full backtrace without the task trace. + +* You can say "--backtrace=stdout" and "--trace=stdout" to route trace + output to standard output rather than standard error. + +* Optional 'phony' target (enable with 'require 'rake/phony'") for + special purpose builds. + +* Task#clear now clears task comments as well as actions and + prerequisites. Task#clear_comment will specifically target comments. + +* The --all option will force -T and -D to consider all the tasks, + with and without descriptions. + +===== Bug Fixes (in 0.9.3) + +* Semi-colons in windows rakefile paths now work. + +* Improved Control-C support when invoking multiple test suites. + +* egrep method now reads files in text mode (better support for + Windows) + +* Better deprecation line number reporting. + +* The -W option now works with all tasks, whether they have a + description or not. + +* File globs in rake should not be sorted alphabetically, independent + of file system and platform. + +* Numerous internal improvements. + +* Documentation typos and fixes. + +===== Bug Fixes (in 0.9.4) + +* Exit status with failing tests is not correctly set to non-zero. + +* Simplified syntax for phony task (for older versions of RDoc). + +* Stand alone FileList usage gets glob function (without loading in + extra dependencies) + +===== Bug Fixes (in 0.9.5) + +* --trace and --backtrace no longer swallow following task names. + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 10.0.2 + +==== Changes + +===== Bug Fixes + +* --trace and --backtrace no longer swallow following task names. + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 10.0.1 + +==== Changes + +===== Bug Fixes + +* Exit status with failing tests is not correctly set to non-zero. + +* Simplified syntax for phony task (for older versions of RDoc). + +* Stand alone FileList usage gets glob function (without loading in + extra dependencies) + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 10.0.0 + + "Jim, when will Rake reach version 1.0?" + +Over the past several years I've been asked that question at +conferences, panels and over twitter. Due to historical reasons (or +maybe just plain laziness) Rake has (incorrectly) been treating the +second digit of the version as the major release number. So in my head +Rake was already at version 9. + +Well, it's time to fix things. This next version of Rake drops old, +crufty, backwards compatibility hacks such as top level constants, DSL +methods defined in Object and numerous other features that are just no +longer desired. It's also time to drop the leading zero from the +version number as well and call this new version of rake what it +really is: Version 10. + +So, welcome to Rake 10.0! + +Rake 10 is actually feature identical to the latest version of Rake 9 +(that would be the version spelled 0.9.3), *except* that Rake 10 drops +all the sundry deprecated features that have accumulated over the years. + +If your Rakefile is up to date and current with all the new features +of Rake 10, you are ready to go. If your Rakefile still uses a few +deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same +feature set. Just be aware that future features will be in Rake 10 +family line. + +==== Changes in 10.0 + +As mentioned above, there are no new features in Rake 10. However, +there are a number of features missing: + +* Classic namespaces are now gone. Rake is no longer able to reflect + the options settings in the global variables ($rakefile, $show\_tasks, + $show\_prereqs, $trace, $dryrun and $silent). The + --classic-namespace option is no longer supported. + +* Global constants are no longer supported. This includes + Task, FileTask, FileCreationTask and + RakeApp). The constant missing hook to warn about using + global rake constants has been removed. + +* The Rake DSL methods (task, file, directory, etc) are in their own + module (Rake::DSL). The stub versions of these methods (that printed + warnings) in Object have been removed. However, the DSL methods are + added to the top-level main object. Since main is + not in the inheritance tree, the presence of the DSL methods in main + should be low impact on other libraries. + + If you want to use the Rake DSL commands from your own code, just + include Rake::DSL into your own classes and modules. + +* The deprecated syntax for task arguments (the one using + :needs) has been removed. + +* The --reduce-compat flag has been removed (it's not needed + anymore). + +* The deprecated rake/sys.rb library has been removed. + +* The deprecated rake/rdoctask.rb library has been removed. + RDoc supplies its own rake task now. + +* The deprecated rake/gempackagetask.rb library has been + removed. Gem supplies its own package task now. + +There is one small behavioral change: + +* Non-file tasks now always report the current time as their time + stamp. This is different from the previous behavior where non-file + tasks reported current time only if there were no prerequisites, and + the max prerequisite timestamp otherwise. This lead to inconsistent + and surprising behavior when adding prerequisites to tasks that in + turn were prequisites to file tasks. The new behavior is more + consistent and predictable. + +==== Changes (from 0.9.3) + +Since Rake 10 includes the changes from the last version of Rake 9, +we'll repeat the changes for version 0.9.3 here. + +===== New Features + +* Multitask tasks now use a thread pool. Use -j to limit the number of + available threads. + +* Use -m to turn regular tasks into multitasks (use at your own risk). + +* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to + programatically add rake task libraries. + +* You can specific backtrace suppression patterns (see + --suppress-backtrace) + +* Directory tasks can now take prerequisites and actions + +* Use --backtrace to request a full backtrace without the task trace. + +* You can say "--backtrace=stdout" and "--trace=stdout" to route trace + output to standard output rather than standard error. + +* Optional 'phony' target (enable with 'require 'rake/phony'") for + special purpose builds. + +* Task#clear now clears task comments as well as actions and + prerequisites. Task#clear_comment will specifically target comments. + +* The --all option will force -T and -D to consider all the tasks, + with and without descriptions. + +===== Bug Fixes + +* Semi-colons in windows rakefile paths now work. + +* Improved Control-C support when invoking multiple test suites. + +* egrep method now reads files in text mode (better support for + Windows) + +* Better deprecation line number reporting. + +* The -W option now works with all tasks, whether they have a + description or not. + +* File globs in rake should not be sorted alphabetically, independent + of file system and platform. + +* Numerous internal improvements. + +* Documentation typos and fixes. + + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.6 + +Rake version 0.9.6 contains a number of fixes mainly for merging +Rake into the Ruby source tree and fixing tests. + +==== Changes + +===== Bug Fixes (0.9.6) + +* Better trace output when using a multi-threaded Rakefile. +* Arg parsing is now consistent for tasks and multitasks. +* Skip exit code test in versions of Ruby that don't support it well. + +Changes for better integration with the Ruby source tree: + +* Fix version literal for Ruby source tree build. +* Better loading of libraries for testing in Ruby build. +* Use the ruby version provided by Ruby's tests. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.5 + +Rake version 0.9.5 contains a number of bug fixes. + +==== Changes + +===== Bug Fixes (0.9.5) + +* --trace and --backtrace no longer swallow following task names. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.4 + +Rake version 0.9.4 contains a number of bug fixes. + +==== Changes + +===== Bug Fixes (0.9.4) + +* Exit status with failing tests is not correctly set to non-zero. + +* Simplified syntax for phony task (for older versions of RDoc). + +* Stand alone FileList usage gets glob function (without loading in + extra dependencies) + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.3 + +Rake version 0.9.3 contains some new, backwards compatible features and +a number of bug fixes. + +==== Changes + +===== New Features + +* Multitask tasks now use a thread pool. Use -j to limit the number of + available threads. + +* Use -m to turn regular tasks into multitasks (use at your own risk). + +* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to + programatically add rake task libraries. + +* You can specific backtrace suppression patterns (see + --suppress-backtrace) + +* Directory tasks can now take prerequisites and actions + +* Use --backtrace to request a full backtrace without the task trace. + +* You can say "--backtrace=stdout" and "--trace=stdout" to route trace + output to standard output rather than standard error. + +* Optional 'phony' target (enable with 'require 'rake/phony'") for + special purpose builds. + +* Task#clear now clears task comments as well as actions and + prerequisites. Task#clear_comment will specifically target comments. + +* The --all option will force -T and -D to consider all the tasks, + with and without descriptions. + +===== Bug Fixes + +* Semi-colons in windows rakefile paths now work. + +* Improved Control-C support when invoking multiple test suites. + +* egrep method now reads files in text mode (better support for + Windows) + +* Better deprecation line number reporting. + +* The -W option now works with all tasks, whether they have a + description or not. + +* File globs in rake should not be sorted alphabetically, independent + of file system and platform. + +* Numerous internal improvements. + +* Documentation typos and fixes. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== Rake 0.9.2.2 + +Rake version 0.9.2.2 is mainly bug fixes. + +==== Changes + +* The rake test loader now removes arguments it has processed. Issue #51 +* Rake::TaskArguments now responds to #values\_at +* RakeFileUtils.verbose_flag = nil silences output the same as 0.8.7 +* Rake tests are now directory-independent +* Rake tests are no longer require flexmock +* Commands constant is no longer polluting top level namespace. +* Show only the interesting portion of the backtrace by default (James M. Lawrence). +* Added --reduce-compat option to remove backward compatible DSL hacks (James M. Lawrence). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + +=== 0.9.2 + +Rake version 0.9.2 has a few small fixes. See below for details. + +==== Changes + +* Support for Ruby 1.8.6 was fixed. +* Global DSL warnings now honor --no-deprecate + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + +=== 0.9.1 + +Rake version 0.9.1 has a number of bug fixes and enhancments (see +below for more details). Additionally, the internals have be slightly +restructured and improved. + +==== Changes + +Rake 0.9.1 adds back the global DSL methods, but with deprecation +messages. This allows Rake 0.9.1 to be used with older rakefiles with +warning messages. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + +=== 0.9.0 + +Rake version 0.9.0 has a number of bug fixes and enhancments (see +below for more details). Additionally, the internals have be slightly +restructured and improved. + +==== Changes + +===== New Features / Enhancements / Bug Fixes in Version 0.9.0 + +* Rake now warns when the deprecated :needs syntax used (and suggests + the proper syntax in the warning). + +* Moved Rake DSL commands to top level ruby object 'main'. Rake DSL + commands are no longer private methods in Object. (Suggested by + James M. Lawrence/quix) + +* Rake now uses case-insensitive comparisons to find the Rakefile on Windows. + Based on patch by Roger Pack. + +* Rake now requires (instead of loads) files in the test task. Patch by Cezary + Baginski. + +* Fixed typos. Patches by Sean Scot August Moon and R.T. Lechow. + +* Rake now prints the Rakefile directory only when it's different from the + current directory. Patch by Alex Chaffee. + +* Improved rakefile_location discovery on Windows. Patch by James Tucker. + +* Rake now recognizes "Windows Server" as a windows system. Patch by Matthias + Lüdtke + +* Rake::RDocTask is deprecated. Use RDoc::Task from RDoc 2.4.2+ (require + 'rdoc/task') + +* Rake::GemPackageTask is deprecated. Use Gem::PackageTask (require + 'rubygems/package\_task') + +* Rake now outputs various messages to $stderr instead of $stdout. + +* Rake no longer emits warnings for Config. Patch by Santiago Pastorino. + +* Removed Rake's DSL methods from the top level scope. If you need to + call 'task :xzy' in your code, include Rake::DSL into your class, or + put the code in a Rake::DSL.environment do ... end block. + +* Split rake.rb into individual files. + +* Support for the --where (-W) flag for showing where a task is defined. + +* Fixed quoting in test task. + (http://onestepback.org/redmine/issues/show/44, + http://www.pivotaltracker.com/story/show/1223138) + +* Fixed the silent option parsing problem. + (http://onestepback.org/redmine/issues/show/47) + +* Fixed :verbose=>false flag on sh and ruby commands. + +* Rake command line options may be given by default in a RAKEOPT + environment variable. + +* Errors in Rake will now display the task invocation chain in effect + at the time of the error. + +* Accepted change by warnickr to not expand test patterns in shell + (allowing more files in the test suite). + +* Fixed that file tasks did not perform prereq lookups in scope + (Redmine #57). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + + +=== 0.8.7 + +Rake version 0.8.5 introduced greatly improved support for executing +commands on Windows. The "sh" command now has the same semantics on +Windows that it has on Unix based platforms. + +Rake version 0.8.6 includes minor fixes the the RDoc generation. +Rake version 0.8.7 includes a minor fix for JRuby running on windows. + +==== Changes + +===== New Features / Enhancements in Version 0.8.5 + +* Improved implementation of the Rake system command for Windows. + (patch from James M. Lawrence/quix) + +* Support for Ruby 1.9's improved system command. (patch from James + M. Lawrence/quix) + +* Rake now includes the configured extension when invoking an + executable (Config::CONFIG['EXEEXT]) + +===== Bug Fixes in Version 0.8.5 + +* Environment variable keys are now correctly cased (it matters in + some implementations). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Charles Nutter + +-- Jim Weirich + +=== 0.8.6 + +Rake version 0.8.5 introduced greatly improved support for executing +commands on Windows. The "sh" command now has the same semantics on +Windows that it has on Unix based platforms. + +Rake version 0.8.5 includes minor fixes the the RDoc generation. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence/quix +* Luis Lavena + +-- Jim Weirich + +=== 0.8.5 + +Rake version 0.8.5 is a new release of Rake with greatly improved +support for executing commands on Windows. The "sh" command now has +the same semantics on Windows that it has on Unix based platforms. + +==== Changes + +===== New Features / Enhancements in Version 0.8.5 + +* Improved implementation of the Rake system command for Windows. + (patch from James M. Lawrence/quix) + +* Support for Ruby 1.9's improved system command. (patch from James + M. Lawrence/quix) + +* Rake now includes the configured extension when invoking an + executable (Config::CONFIG['EXEEXT]) + +===== Bug Fixes in Version 0.8.5 + +* Environment variable keys are now correctly cased (it matters in + some implementations). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence/quix +* Luis Lavena + +-- Jim Weirich + +=== 0.8.4 + +Rake version 0.8.4 is a bug-fix release of rake. + +NOTE: The version of Rake that comes with Ruby 1.9 has diverged + slightly from the core Rake code base. Rake 0.8.4 will work + with Ruby 1.9, but is not a strict upgrade for the Rake that + comes with Ruby 1.9. A (near) future release of Rake will unify + those two codebases. + +==== Letter Writing Campaign + +Thanks to Aaron Patterson (@tenderlove) and Eric Hodel (@drbrain) for +their encouraging support in organizing a letter writing campaign to +lobby for the "Warning Free" release of rake 0.8.4. A special callout +goes to Jonathan D. Lord, Sr (Dr. Wingnut) whose postcard was the +first to actually reach me. (see +http://tenderlovemaking.com/2009/02/26/we-need-a-new-version-of-rake/ +for details) + +==== Changes + +===== New Features / Enhancements in Version 0.8.4 + +* Case is preserved on rakefile names. (patch from James + M. Lawrence/quix) + +* Improved Rakefile case insensitivity testing (patch from Luis + Lavena). + +* Windows system dir search order is now: HOME, HOMEDRIVE + HOMEPATH, + APPDATA, USERPROFILE (patch from Luis Lavena) + +* MingGW is now recognized as a windows platform. (patch from Luis + Lavena) + +===== Bug Fixes in Version 0.8.4 + +* Removed reference to manage_gem to fix the warning produced by the + gem package task. + +* Fixed stray ARGV option problem that was interfering with + Test::Unit::Runner. (patch from Pivotal Labs) + +===== Infrastructure Improvements in Version 0.8.4 + +* Numerous fixes to the windows test suite (patch from Luis Lavena). + +* Improved Rakefile case insensitivity testing (patch from Luis + Lavena). + +* Better support for windows paths in the test task (patch from Simon + Chiang/bahuvrihi) + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence/quix +* Luis Lavena +* Pivotal Labs +* Simon Chiang/bahuvrihi + +-- Jim Weirich + +=== 0.8.3 + +Rake version 0.8.3 is a bug-fix release of rake. + +==== Changes + +===== Bug Fixes in Version 0.8.3 + +* Enhanced the system directory detection in windows. We now check + HOMEDRIVE/HOMEPATH and USERPROFILE if APPDATA isn't found. (Patch + supplied by James Tucker). Rake no long aborts if it can't find the + directory. + +* Added fix to handle ruby installations in directories with spaces in + their name. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Edwin Pratomo +* Gavin Stark +* Adam Q. Salter +* Adam Majer +* Emanuel Indermühle +* Ittay Dror +* Bheeshmar Redheendran (for spending an afternoon with me debugging + windows issues) + +-- Jim Weirich + + +=== 0.8.2 + +Rake version 0.8.2 is a new release of rake that includes a number of +new features and numerous bug fixes. + +==== Changes + +===== New Features in Version 0.8.2 + +* Switched from getoptlong to optparse (patches supplied by Edwin + Pratomo). + +* The -T option will now attempt to dynamically sense the size of the + terminal. The -T output will only self-truncate if the output is a + tty. However, if RAKE_COLUMNS is explicitly set, it will be honored + in any case. (Patch provided by Gavin Stark). + +* The following public methods have been added to rake task objects: + + * task.clear -- Clear both the prerequisites and actions of the + target rake task. + * task.clear_prerequisites -- Clear all the existing prerequisites + from the target rake task. + * task.clear_actions -- Clear all the existing actions from the + target rake task. + * task.reenable -- Re-enable a task, allowing its actions to be + executed again if the task is invoked. + +* Changed RDoc test task to have no default template. This makes it + easier for the tempate to pick up the template from the environment. + +* Default values for task arguments can easily be specified with the + :with_defaults method. (Idea for default argument merging supplied + by (Adam Q. Salter) + +===== Bug Fixes in Version 0.8.2 + +* Fixed bug in package task so that it will include the subdir + directory in the package for testing. (Bug found by Adam Majer) + +* Fixed filename dependency order bug in test\_inspect\_pending and + test\_to\_s\_pending. (Bug found by Adam Majer) + +* Fixed check for file utils options to make them immune to the + symbol/string differences. (Patch supplied by Edwin Pratomo) + +* Fixed bug with rules involving multiple source, where only the first + dependency of a rule has any effect (Patch supplied by Emanuel + Indermühle) + +* FileList#clone and FileList#dup have better sematics w.r.t. taint + and freeze. + +* Changed from using Mutex to Monitor. Evidently Mutex causes thread + join errors when Ruby is compiled with -disable-pthreads. (Patch + supplied by Ittay Dror) + +* Fixed bug in makefile parser that had problems with extra spaces in + file task names. (Patch supplied by Ittay Dror) + +==== Other changes in Version 0.8.2 + +* Added ENV var to rake's own Rakefile to prevent OS X from including + extended attribute junk in the rake package tar file. (Bug found by + Adam Majer) + +* Added a performance patch for reading large makefile dependency + files. (Patch supplied by Ittay Dror) + +==== Task Argument Examples + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.2] + +And the string "0.8.2" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +===== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, :first_name, :last_name + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name (:first_name and :last_name in the example). + +To access the values of the parameters, the block defining the task +behaviour can now accept a second parameter: + + task :name, :first_name, :last_name do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Edwin Pratomo +* Gavin Stark +* Adam Q. Salter +* Adam Majer +* Emanuel Indermühle +* Ittay Dror +* Bheeshmar Redheendran (for spending an afternoon with me debugging + windows issues) + +-- Jim Weirich + +=== 0.8.0/0.8.1 + +Rake version 0.8.0 is a new release of rake that includes serveral new +features. + +==== Changes + +===== New Features in Version 0.8.0 + +* Tasks can now receive command line parameters. See the examples + below for more details. + +* Comments are limited to 80 columns on output, but full comments can + be seen by using the -D parameter. (feature suggested by Jamis + Buck). + +* Explicit exit(n) calls will now set the exit status to n. (patch + provided by Stephen Touset). + +* Rake is now compatible with Ruby 1.9. + +Version 0.8.1 is a minor update that includes additional Ruby 1.9 +compatibility fixes. + +==== Task Argument Examples + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.0] + +And the string "0.8.0" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +===== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, :first_name, :last_name + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name (:first_name and :last_name in the example). + +To access the values of the parameters, the block defining the task +behaviour can now accept a second parameter: + + task :name, :first_name, :last_name do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Jamis Buck (for comment formatting suggestions) +* Stephen Touset (for exit status patch). + +-- Jim Weirich + + +=== 0.7.3 + +Rake version 0.7.3 is a minor release that includes some refactoring to better +support custom Rake applications. + +==== Changes + +===== New Features in Version 0.7.3 + +* Added the +init+ and +top_level+ methods to make the creation of custom Rake applications a bit easier. E.g. + + gem 'rake', ">= 0.7.3" + require 'rake' + + Rake.application.init('myrake') + + task :default do + something_interesting + end + + Rake.application.top_level + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +-- Jim Weirich + + +=== 0.7.2 + + +Version 0.7.2 supplies a bug fix and a few minor enhancements. In +particular, the new version fixes an incompatibility with the soon to +be released Ruby 1.8.6. We strongly recommend upgrading to Rake 0.7.2 +in order to be compatible with the new version of Ruby. + +==== Changes + +===== Bug Fixes in 0.7.2 + +There are quite a number of bug fixes in the new 0.7.2 version of +Rake: + +* Removed dependency on internal fu_xxx functions from FileUtils. + +* Error messages are now send to stderr rather than stdout (from + Payton Quackenbush). + +* Better error handling on invalid command line arguments (from Payton + Quackenbush). + +* Fixed some bugs where the application object was going to the global + appliation instead of using its own data. + +* Fixed the method name leak from FileUtils (bug found by Glenn + Vanderburg). + +* Added test for noop, bad_option and verbose flags to sh command. + +* Added a description to the gem task in GemPackageTask. + +* Fixed a bug when rules have multiple prerequisites (patch by Joel + VanderWerf) + +* Added the handful of RakeFileUtils to the private method as well. + +===== New Features in 0.7.2 + +The following new features are available in Rake version 0.7.2: + +* Added square and curly bracket patterns to FileList#include (Tilman + Sauerbeck). + +* FileLists can now pass a block to FileList#exclude to exclude files + based on calculated values. + +* Added plain filename support to rule dependents (suggested by Nobu + Nakada). + +* Added pathmap support to rule dependents. In other words, if a + pathmap format (beginning with a '%') is given as a Rake rule + dependent, then the name of the depend will be the name of the + target with the pathmap format applied. + +* Added a 'tasks' method to a namespace to get a list of tasks + associated with the namespace. + +* Added tar_command and zip_command options to the Package task. + +* The clean task will no longer delete 'core' if it is a directory. + +===== Internal Rake Improvements + +The following changes will are mainly internal improvements and +refactorings and have little effect on the end user. But they may be +of interest to the general public. + +* Added rcov task and updated unit testing for better code coverage. + +* Added a 'shame' task to the Rakefile. + +* Added rake_extension to handle detection of extension collisions. + +* Added a protected 'require "rubygems"' to test/test_application to + unbreak cruisecontrol.rb. + +* Removed rake\_dup. Now we just simply rescue a bad dup. + +* Refactored the FileList reject logic to remove duplication. + +* Removed if \_\_FILE\_\_ at the end of the rake.rb file. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Payton Quackenbush -- For several error handling improvements. + +* Glenn Vanderburg -- For finding and fixing the method name leak from + FileUtils. + +* Joel VanderWerf -- for finding and fixing a bug in the handling of + multiple prerequisites. + +* Tilman Sauerbeck -- For some enhancing FileList to support more + advanced file globbing. + +* Nobu Nakada -- For suggesting plain file name support to rule dependents. + +-- Jim Weirich + +=== 0.7.1 + +Version 0.7.1 supplies a bug fix and a few minor enhancements. + +==== Changes + +===== Bug Fixes in 0.7.1 + +* Changes in the exception reported for the FileUtils.ln caused + safe_ln to fail with a NotImplementedError. Rake 0.7.1 will now + catch that error or any StandardError and properly fall back to + using +cp+. + +===== New Features in 0.7.1 + +* You can filter the results of the --task option by supplying an + optional regular expression. This allows the user to easily find a + particular task name in a long list of possible names. + +* Transforming procs in a rule may now return a list of prerequisites. + This allows more flexible rule formation. + +* FileList and String now support a +pathmap+ melthod that makes the + transforming paths a bit easier. See the API docs for +pathmap+ for + details. + +* The -f option without a value will disable the search for a + Rakefile. This allows the Rakefile to be defined entirely in a + library (and loaded with the -r option). The current working + directory is not changed when this is done. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* James Britt and Assaph Mehr for reporting and helping to debug the + safe_ln issue. + +-- Jim Weirich + + +=== 0.7.0 + +These changes for Rake have been brewing for a long time. Here they +are, I hope you enjoy them. + +==== Changes + +===== New Features + +* Name space support for task names (see below). +* Prerequisites can be executed in parallel (see below). +* Added safe_ln support for openAFS (via Ludvig Omholt). +* RDoc defaults to internal (in-process) invocation. The old behavior + is still available by setting the +external+ flag to true. +* Rakefiles are now loaded with the expanded path to prevent + accidental pollution from the Ruby load path. +* Task objects my now be used in prerequisite lists directly. +* Task objects (in addition to task names) may now be included in the + prerequisite list of a task. +* Internals cleanup and refactoring. + +===== Bug Fixes + +* Compatibility fixes for Ruby 1.8.4 FileUtils changes. + +===== Namespaces + +Tasks can now be nested inside their own namespaces. Tasks within one +namespace will not accidentally interfer with tasks named in a different +namespace. + +For example: + + namespace "main" do + task :build do + # Build the main program + end + end + + namespace "samples" do + task :build do + # Build the sample programs + end + end + + task :build_all => ["main:build", "samples:build"] + +Even though both tasks are named :build, they are separate tasks in +their own namespaces. The :build_all task (defined in the toplevel +namespace) references both build tasks in its prerequisites. + +You may invoke each of the individual build tasks with the following +commands: + + rake main:build + rake samples:build + +Or invoke both via the :build_all command: + + rake build_all + +Namespaces may be nested arbitrarily. Since the name of file tasks +correspond to the name of a file in the external file system, +FileTasks are not affected by the namespaces. + +See the Rakefile format documentation (in the Rake API documents) for +more information. + +===== Parallel Tasks + +Sometimes you have several tasks that can be executed in parallel. By +specifying these tasks as prerequisites to a +multitask+ task. + +In the following example the tasks copy\_src, copy\_doc and copy\_bin +will all execute in parallel in their own thread. + + multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do + puts "All Copies Complete" + end + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Doug Young (inspiration for the parallel task) +* David Heinemeier Hansson (for --trace message enhancement and for + pushing for namespace support). +* Ludvig Omholt (for the openAFS fix) + +-- Jim Weirich + +=== 0.6.1 + +* Rebuilt 0.6.0 gem without signing. + +=== 0.6.0 + +Its time for some long requested enhancements and lots of bug fixes +... And a whole new web page. + +==== New Web Page + +The primary documentation for rake has moved from the RubyForge based +wiki to its own Hieraki based web site. Constant spam on the wiki +made it a difficult to keep clean. The new site will be easier to +update and organize. + +Check out the new documentation at: http://docs.rubyrake.org + +We will be adding new documentation to the site as time goes on. + +In addition to the new docs page, make sure you check out Martin +Fowlers article on rake at http://martinfowler.com/articles/rake.html + +==== Changes + +===== New Features + +* Multiple prerequisites on Rake rules now allowed. However, keep the + following in mind: + + 1. All the prerequisites of a rule must be available before a rule + is triggered, where "enabled" means (a) an existing file, (b) a + defined rule, or (c) another rule which also must be + trigger-able. + 2. Rules are checked in order of definition, so it is important to + order your rules properly. If a file can be created by two + different rules, put the more specific rule first (otherwise the + more general rule will trigger first and the specific one will + never be triggered). + 3. The source method now returns the name of the first + prerequisite listed in the rule. sources returns the + names of all the rule prerequisites, ordered as they are defined + in the rule. If the task has other prerequisites not defined in + the rule (but defined in an explicit task definition), then they + will _not_ be included in the sources list. + +* FileLists may now use the egrep command. This popular enhancement + is now a core part of the FileList object. If you want to get a + list of all your to-dos, fixmes and TBD comments, add the following + to your Rakefile. + + desc "Look for TODO and FIXME tags in the code" + task :todo do + FileList['**/*.rb'].egrep /#.*(FIXME|TODO|TBD)/ + end + +* The investigation method was added to task object to dump + out some important values. This makes it a bit easier to debug Rake + tasks. + + For example, if you are having problems with a particular task, just + print it out: + + task :huh do + puts Rake::Task['huh'].investigation + end + +* The Rake::TestTask class now supports a "ruby\_opts" option to pass + arbitrary ruby options to a test subprocess. + +===== Some Incompatibilities + +* When using the ruby command to start a Ruby subprocess, the + Ruby interpreter that is currently running rake is used by default. + This makes it easier to use rake in an environment with multiple + ruby installation. (Previously, the first ruby command found in the + PATH was used). + + If you wish to chose a different Ruby interpreter, you can + explicitly choose the interpreter via the sh command. + +* The major rake classes (Task, FileTask, FileCreationTask, RakeApp) + have been moved out of the toplevel scope and are now accessible as + Rake::Task, Rake::FileTask, Rake::FileCreationTask and + Rake::Application. If your Rakefile + directly references any one of these tasks, you may: + + 1. Update your Rakefile to use the new classnames + 2. Use the --classic-namespace option on the rake command to get the + old behavior, + 3. Add require 'rake/classic_namespace' to the + Rakefile to get the old behavior. + + rake will print a rather annoying warning whenever a + deprecated class name is referenced without enabling classic + namespace. + +===== Bug Fixes + +* Several unit tests and functional tests were fixed to run better + under windows. + +* Directory tasks are now a specialized version of a File task. A + directory task will only be triggered if it doesn't exist. It will + not be triggered if it is out of date w.r.t. any of its + prerequisites. + +* Fixed a bug in the Rake::GemPackageTask class so that the gem now + properly contains the platform name. + +* Fixed a bug where a prerequisite on a file task would cause + an exception if the prerequisite did not exist. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Greg Fast (better ruby_opt test options) +* Kelly Felkins (requested by better namespace support) +* Martin Fowler (suggested Task.investigation) +* Stuart Jansen (send initial patch for multiple prerequisites). +* Masao Mutch (better support for non-ruby Gem platforms) +* Philipp Neubeck (patch for file task exception fix) + +-- Jim Weirich + +=== 0.5.4 + +Time for some minor bug fixes and small enhancements + +==== Changes + +Here are the changes for version 0.5.4 ... + +* Added double quotes to the test runner. This allows the location of + the tests (and runner) to be in a directory path that contains + spaces (e.g. "C:/Program Files/ruby/bin"). +* Added .svn to default ignore list. Now subversion project metadata + is automatically ignored by Rake's FileList. +* Updated FileList#include to support nested arrays and filelists. + FileLists are flat lists of file names. Using a FileList in an + include will flatten out the nested file names. + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +Thanks to ... + +* Tilman Sauerbeck for the nested FileList suggestion. +* Josh Knowles for pointing out the spaces in directory name problem. + +-- Jim Weirich + +=== 0.5.3 + +Although it has only been two weeks since the last release, we have +enough updates to the Rake program to make it time for another +release. + +==== Changes + +Here are the changes for version 0.5.3 ... + +* FileLists have been extensively changed so that they mimic the + behavior of real arrays even more closely. In particular, + operations on FileLists that return a new collection (e.g. collect, + reject) will now return a FileList rather than an array. In + addition, several places where FileLists were not properly expanded + before use have been fixed. +* A method (+ext+) to simplify the handling of file extensions was + added to String and to Array. +* The 'testrb' script in test/unit tends to silently swallow syntax + errors in test suites. Because of that, the default test loader is + now a rake-provided script. You can still use 'testrb' by setting + the loader flag in the test task to :testrb. (See the API documents + for TestTask for all the loader flag values). +* FileUtil methods (e.g. cp, mv, install) are now declared to be + private. This will cut down on the interference with user defined + methods of the same name. +* Fixed the verbose flag in the TestTask so that the test code is + controlled by the flag. Also shortened up some failure messages. + (Thanks to Tobias Luetke for the suggestion). +* Rules will now properly detect a task that can generate a source + file. Previously rules would only consider source files that were + already present. +* Added an +import+ command that allows Rake to dynamically import + dependendencies into a running Rake session. The +import+ command + can run tasks to update the dependency file before loading them. + Dependency files can be in rake or make format, allowing rake to + work with tools designed to generate dependencies for make. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +Thanks to ... + +* Brian Gernhardt for the rules fix (especially for the patience to + explain the problem to me until I got what he was talking about). +* Stefan Lang for pointing out problems in the dark corners of the + FileList implementation. +* Alexey Verkhovsky pointing out the silently swallows syntax errors + in tests. +* Tobias Luetke for beautifying the test task output. +* Sam Roberts for some of the ideas behind dependency loading. + +-- Jim Weirich + + +=== 0.5.0 + +It has been a long time in coming, but we finally have a new version +of Rake available. + +==== Changes + +* Fixed documentation that was lacking the Rake module name (Tilman + Sauerbeck). +* Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck). +* Recursive rules are now supported (Tilman Sauerbeck). +* Added warning option for the Test Task (requested by Eric Hodel). +* The jamis rdoc template is only used if it exists. +* Added fix for Ruby 1.8.2 test/unit and rails problem. +* Added contributed rake man file (Jani Monoses). +* Added Brian Candler's fix for problems in --trace and --dry-run + mode. + +==== Thanks + +Lots of people provided input to this release. Thanks to Tilman +Sauerbeck for numerous patches, documentation fixes and suggestions. +And for also pushing me to get this release out. Also, thanks to +Brian Candler for the finding and fixing --trace/dry-run fix. That +was an obscure bug. Also to Eric Hodel for some good suggestions. + +-- Jim Weirich + +=== 0.4.15 + +==== Changes + +Version 0.4.15 is a bug fix update for the Ruby 1.8.2 compatibility +changes. This release includes: + +* Fixed a bug that prevented the TESTOPTS flag from working with the + revised for 1.8.2 test task. +* Updated the docs on --trace to indicate that it also enables a full + backtrace on errors. +* Several fixes for new warnings generated. + +==== Mini-Roadmap + +I will continue to issue Rake updates in the 0.4.xx series as new +Ruby-1.8.2 issues become manifest. Once the codebase stabilizes, I +will release a 0.5.0 version incorporating all the changes. If you +are not using Ruby-1.8.2 and wish to avoid version churn, I recommend +staying with a release prior to Rake-0.4.14. + +=== 0.4.14 + +Version 0.4.14 is a compatibility fix to allow Rake's test task to +work under Ruby 1.8.2. A change in the Test::Unit autorun feature +prevented Rake from running any tests. This release fixes the +problem. + +Rake 0.4.14 is the recommended release for anyone using Ruby 1.8.2. + +=== 0.4.13 + +* Fixed the dry-run flag so it is operating again. +* Multiple arguments to sh and ruby commands will not be interpreted + by the shell (patch provided by Jonathan Paisley). + +=== 0.4.12 + +* Added --silent (-s) to suppress the (in directory) rake message. + +=== 0.4.11 + +* Changed the "don't know how to rake" message (finally) +* Changes references to a literal "Rakefile" to reference the global + variable $rakefile (which contains the actual name of the rakefile). + +=== 0.4.10 + +* Added block support to the "sh" command, allowing users to take + special actions on the result of the system call. E.g. + + sh "shell_command" do |ok, res| + puts "Program returned #{res.exitstatus}" if ! ok + end + +=== 0.4.9 + +* Switched to Jamis Buck's RDoc template. +* Removed autorequire from Rake's gem spec. This prevents the Rake + libraries from loading while using rails. + +=== 0.4.8 + +* Added support for .rb versions of Rakefile. +* Removed \\\n's from test task. +* Fixed Ruby 1.9 compatibility issue with FileList. + +=== 0.4.7 + +* Fixed problem in FileList that caused Ruby 1.9 to go into infinite + recursion. Since to_a was removed from Object, it does not need to + added back into the list of methods to rewrite in FileList. (Thanks + to Kent Sibilev for pointing this out). + +=== 0.4.6 +* Removed test version of ln in FileUtils that prevented safe_ln from + using ln. + +=== 0.4.5 +* Upgraded comments in TestTask. +* FileList to_s and inspect now automatically resolve pending changes. +* FileList#exclude properly returns the FileList. + +=== 0.4.4 +* Fixed initialization problem with @comment. +* Now using multi -r technique in TestTask. Switch Rakefile back to + using the built-in test task macros because the rake runtime is no + longer needed. +* Added 'TEST=filename' and 'TESTOPTS=options' to the Test Task + macros. +* Allow a +test_files+ attribute in test tasks. This allows more + flexibility in specifying test files. + +=== 0.4.3 +* Fixed Comment leakage. + +=== 0.4.2 +* Added safe_ln that falls back to a copy if a file link is not supported. +* Package builder now uses safe\_ln. + +=== 0.4.1 +* Task comments are now additive, combined with "/". +* Works with (soon to be released) rubygems 0.6.2 (or 0.7.0) + +=== 0.4.0 +* FileList now uses deferred loading. The file system is not searched + until the first call that needs the file names. +* VAR=VALUE options are now accepted on the command line and are + treated like environment variables. The values may be tested in a + Rakefile by referencing ENV['VAR']. +* File.mtime is now used (instead of File.new().mtime). + +=== 0.3.2.x + +* Removed some hidden dependencies on rubygems. Tests now will test + gems only if they are installed. +* Removed Sys from some example files. I believe that is that last + reference to Sys outside of the contrib area. +* Updated all copyright notices to include 2004. + +=== 0.3.2 + +* GEM Installation now works with the application stub. + +=== 0.3.1 + +* FileLists now automatically ignore CVS, .bak, ! +* GEM Installation now works. + +=== 0.3.0 + +Promoted 0.2.10. + +=== 0.2.10 +General + +* Added title to Rake's rdocs +* Contrib packages are no longer included in the documentation. + +RDoc Issues + +* Removed default for the '--main' option +* Fixed rendering of the rdoc options +* Fixed clean/clobber confusion with rerdoc +* 'title' attribute added + +Package Task Library Issues + +* Version (or explicit :noversion) is required. +* +package_file+ attribute is now writable + +FileList Issues + +* Dropped bang version of exclude. Now using ant-like include/exclude semantics. +* Enabled the "yield self" idiom in FileList#initialize. + +=== 0.2.9 + +This version contains numerous changes as the RubyConf.new(2003) +presentation was being prepared. The changes include: + +* The monolithic rubyapp task library is in the process of being + dropped in favor of lighter weight task libraries. + +=== 0.2.7 + +* Added "desc" for task descriptions. +* -T will now display tasks with descriptions. +* -P will display tasks and prerequisites. +* Dropped the Sys module in favor of the 1.8.x FileUtils module. Sys + is still supported in the contrib area. + +=== 0.2.6 + +* Moved to RubyForge + +=== 0.2.5 + +* Switched to standard ruby app builder. +* Added no_match option to file matcher. + +=== 0.2.4 + +* Fixed indir, which neglected to actually change directories. + +=== 0.2.3 + +* Added rake module for a help target +* Added 'for\_files' to Sys +* Added a $rakefile constant +* Added test for selecting proper rule with multiple targets. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE new file mode 100644 index 0000000..4292f3b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) Jim Weirich + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc new file mode 100644 index 0000000..b31fe37 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc @@ -0,0 +1,155 @@ += RAKE -- Ruby Make + +home :: https://github.com/ruby/rake +bugs :: https://github.com/ruby/rake/issues +docs :: https://ruby.github.io/rake + +== Description + +Rake is a Make-like program implemented in Ruby. Tasks and dependencies are +specified in standard Ruby syntax. + +Rake has the following features: + +* Rakefiles (rake's version of Makefiles) are completely defined in + standard Ruby syntax. No XML files to edit. No quirky Makefile + syntax to worry about (is that a tab or a space?) + +* Users can specify tasks with prerequisites. + +* Rake supports rule patterns to synthesize implicit tasks. + +* Flexible FileLists that act like arrays but know about manipulating + file names and paths. + +* A library of prepackaged tasks to make building rakefiles easier. For example, + tasks for building tarballs. (Formerly + tasks for building RDoc, Gems, and publishing to FTP were included in rake but they're now + available in RDoc, RubyGems, and rake-contrib respectively.) + +* Supports parallel execution of tasks. + +== Installation + +=== Gem Installation + +Download and install rake with the following. + + gem install rake + +== Usage + +=== Simple Example + +First, you must write a "Rakefile" file which contains the build rules. Here's +a simple example: + + task default: %w[test] + + task :test do + ruby "test/unittest.rb" + end + +This Rakefile has two tasks: + +* A task named "test", which -- upon invocation -- will run a unit test file + in Ruby. +* A task named "default". This task does nothing by itself, but it has exactly + one dependency, namely the "test" task. Invoking the "default" task will + cause Rake to invoke the "test" task as well. + +Running the "rake" command without any options will cause it to run the +"default" task in the Rakefile: + + % ls + Rakefile test/ + % rake + (in /home/some_user/Projects/rake) + ruby test/unittest.rb + ....unit test output here... + +Type "rake --help" for all available options. + +== Resources + +=== Rake Information + +* {Rake command-line}[rdoc-ref:doc/command_line_usage.rdoc] +* {Writing Rakefiles}[rdoc-ref:doc/rakefile.rdoc] +* The original {Rake announcement}[rdoc-ref:doc/rational.rdoc] +* Rake {glossary}[rdoc-ref:doc/glossary.rdoc] + +=== Presentations and Articles about Rake + +* Avdi Grimm's rake series: + 1. {Rake Basics}[https://avdi.codes/rake-part-1-basics/] + 2. {Rake File Lists}[https://avdi.codes/rake-part-2-file-lists-2/] + 3. {Rake Rules}[https://avdi.codes/rake-part-3-rules/] + 4. {Rake Pathmap}[https://avdi.codes/rake-part-4-pathmap/] + 5. {File Operations}[https://avdi.codes/rake-part-5-file-operations/] + 6. {Clean and Clobber}[https://avdi.codes/rake-part-6-clean-and-clobber/] + 7. {MultiTask}[https://avdi.codes/rake-part-7-multitask/] +* {Jim Weirich's 2003 RubyConf presentation}[https://web.archive.org/web/20140221123354/http://onestepback.org/articles/buildingwithrake/] +* Martin Fowler's article on Rake: https://martinfowler.com/articles/rake.html + +== Other Make Re-envisionings ... + +Rake is a late entry in the make replacement field. Here are links to +other projects with similar (and not so similar) goals. + +* https://directory.fsf.org/wiki/Bras -- Bras, one of earliest + implementations of "make in a scripting language". +* http://www.a-a-p.org -- Make in Python +* https://ant.apache.org -- The Ant project +* https://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System +* https://www.rubydoc.info/gems/rant/0.5.7/frames -- Rant, another Ruby make tool. + +== Credits + +[Jim Weirich] Who originally created Rake. + +[Ryan Dlugosz] For the initial conversation that sparked Rake. + +[Nobuyoshi Nakada ] For the initial patch for rule support. + +[Tilman Sauerbeck ] For the recursive rule patch. + +[Eric Hodel] For aid in maintaining rake. + +[Hiroshi SHIBATA] Maintainer of Rake 10 and later + +== License + +Rake is available under an MIT-style license. + +:include: MIT-LICENSE + +--- + += Other stuff + +Author:: Jim Weirich +Requires:: Ruby 2.0.0 or later +License:: Copyright Jim Weirich. + Released under an MIT-style license. See the MIT-LICENSE + file included in the distribution. + +== Warranty + +This software is provided "as is" and without any express or implied +warranties, including, without limitation, the implied warranties of +merchantability and fitness for a particular purpose. + +== Historical + +Rake was originally created by Jim Weirich, who unfortunately passed away in +February 2014. This repository was originally hosted at +{github.com/jimweirich/rake}[https://github.com/jimweirich/rake/], however +with his passing, has been moved to {ruby/rake}[https://github.com/ruby/rake]. + +You can view Jim's last commit here: +https://github.com/jimweirich/rake/commit/336559f28f55bce418e2ebcc0a57548dcbac4025 + +You can {read more about Jim}[https://en.wikipedia.org/wiki/Jim_Weirich] at Wikipedia. + +Thank you for this great tool, Jim. We'll remember you. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc new file mode 100644 index 0000000..c1ff39d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc @@ -0,0 +1,171 @@ += Rake Command Line Usage + +Rake is invoked from the command line using: + + % rake [options ...] [VAR=VALUE ...] [targets ...] + +Options are: + +[name=value] + Set the environment variable name to value + during the execution of the rake command. You can access + the value by using ENV['name']. + +[--all (-A)] + Used in combination with the -T and -D options, will force + those options to show all the tasks, even the ones without comments. + +[--backtrace{=_output_} (-n)] + Enable a full backtrace (i.e. like --trace, but without the task + tracing details). The _output_ parameter is optional, but if + specified it controls where the backtrace output is sent. If + _output_ is stdout, then backtrace output is directed to + standard output. If _output_ is stderr, or if it is + missing, then the backtrace output is sent to standard error. + +[--comments] + Used in combination with the -W options to force the output to + contain commented options only. This is the reverse of + --all. + +[--describe _pattern_ (-D)] + Describe the tasks (matching optional PATTERN), then exit. + +[--dry-run (-n)] + Do a dry run. Print the tasks invoked and executed, but do not + actually execute any of the actions. + +[--execute _code_ (-e)] + Execute some Ruby code and exit. + +[--execute-print _code_ (-p)] + Execute some Ruby code, print the result, and exit. + +[--execute-continue _code_ (-E)] + Execute some Ruby code, then continue with normal task processing. + +[--help (-H)] + Display some help text and exit. + +[--jobs _number_ (-j)] + + Specifies the maximum number of concurrent threads allowed. Rake + will allocate threads as needed up to this maximum number. + + If omitted, Rake will attempt to estimate the number of CPUs on + the system and add 4 to that number. + + The concurrent threads are used to execute the multitask + prerequisites. Also see the -m option which turns all + tasks into multitasks. + + Sample values: + (no -j) : Allow up to (# of CPUs + 4) number of threads + --jobs : Allow unlimited number of threads + --jobs=1 : Allow only one thread (the main thread) + --jobs=16 : Allow up to 16 concurrent threads + +[--job-stats _level_] + + Display job statistics at the completion of the run. By default, + this will display the requested number of active threads (from the + -j options) and the maximum number of threads in play at any given + time. + + If the optional _level_ is history, then a complete trace + of task history will be displayed on standard output. + +[--libdir _directory_ (-I)] + Add _directory_ to the list of directories searched for require. + +[--multitask (-m)] + Treat all tasks as multitasks. ('make/drake' semantics) + +[--nosearch (-N)] + Do not search for a Rakefile in parent directories. + +[--prereqs (-P)] + Display a list of all tasks and their immediate prerequisites. + +[--quiet (-q)] + Do not echo commands from FileUtils. + +[--rakefile _filename_ (-f)] + Use _filename_ as the name of the rakefile. The default rakefile + names are +rakefile+ and +Rakefile+ (with +rakefile+ taking + precedence). If the rakefile is not found in the current + directory, +rake+ will search parent directories for a match. The + directory where the Rakefile is found will become the current + directory for the actions executed in the Rakefile. + +[--rakelibdir _rakelibdir_ (-R)] + Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') + +[--require _name_ (-r)] + Require _name_ before executing the Rakefile. + +[--rules] + Trace the rules resolution. + +[--silent (-s)] + Like --quiet, but also suppresses the 'in directory' announcement. + +[--suppress-backtrace _pattern_ ] + Line matching the regular expression _pattern_ will be removed + from the backtrace output. Note that the --backtrace option is the + full backtrace without these lines suppressed. + +[--system (-g)] + Use the system wide (global) rakefiles. The project Rakefile is + ignored. By default, the system wide rakefiles are used only if no + project Rakefile is found. On Unix-like system, the system wide + rake files are located in $HOME/.rake. On a windows system they + are stored in $APPDATA/Rake. + +[--no-system (-G)] + Use the project level Rakefile, ignoring the system-wide (global) + rakefiles. + +[--tasks pattern (-T)] + Display a list of the major tasks and their comments. Comments + are defined using the "desc" command. If a pattern is given, then + only tasks matching the pattern are displayed. + +[--trace{=_output_} (-t)] + Turn on invoke/execute tracing. Also enable full backtrace on + errors. The _output_ parameter is optional, but if specified it + controls where the trace output is sent. If _output_ is + stdout, then trace output is directed to standard output. + If _output_ is stderr, or if it is missing, then trace + output is sent to standard error. + +[--verbose (-v)] + Echo the Sys commands to standard output. + +[--version (-V)] + Display the program version and exit. + +[--where pattern (-W)] + Display tasks that match pattern and the file and line + number where the task is defined. By default this option will + display all tasks, not just the tasks that have descriptions. + +[--no-deprecation-warnings (-X)] + Do not display the deprecation warnings. + +== Environment Variables + +[RAKEOPT] + Command line options can be specified in the RAKEOPT + environment variable. These options will be processed as if they + were given on the command line. This is useful for setting default + options that you want to use with every rake invocation. + + For example, setting: + export RAKEOPT="-s --trace" + + would cause rake to run silently with tracing enabled by default. + +In addition, any command line option of the form +VAR=VALUE will be added to the environment hash +ENV and may be tested in the Rakefile. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 new file mode 100644 index 0000000..39f8bcc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 @@ -0,0 +1,38 @@ +# Example Rakefile -*- ruby -*- + +task :default => [:main] + +file "a.o" => ["a.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +file "b.o" => ["b.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +file "main.o" => ["main.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +OBJFILES = ["a.o", "b.o", "main.o"] +task :obj => OBJFILES + +file "main" => OBJFILES do |t| + sh "gcc -o #{t.name} main.o a.o b.o" +end + +task :clean do + rm_f FileList['*.o'] + Dir['*~'].each { |fn| rm_f fn } +end + +task :clobber => [:clean] do + rm_f "main" +end + +task :run => ["main"] do + sh "./main" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 new file mode 100644 index 0000000..35310ec --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 @@ -0,0 +1,35 @@ +# Example Rakefile -*- ruby -*- +# Using the power of Ruby + +task :default => [:main] + +def ext(fn, newext) + fn.sub(/\.[^.]+$/, newext) +end + +SRCFILES = Dir['*.c'] +OBJFILES = SRCFILES.collect { |fn| ext(fn,".o") } + +OBJFILES.each do |objfile| + srcfile = ext(objfile, ".c") + file objfile => [srcfile] do |t| + sh "gcc #{srcfile} -c -o #{t.name}" + end +end + +file "main" => OBJFILES do |t| + sh "gcc -o #{t.name} main.o a.o b.o" +end + +task :clean do + rm_f FileList['*.o'] + Dir['*~'].each { |fn| rm_f fn } +end + +task :clobber => [:clean] do + rm_f "main" +end + +task :run => ["main"] do + sh "./main" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c new file mode 100644 index 0000000..620e6f8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c @@ -0,0 +1,6 @@ +#include + +void a() +{ + printf ("In function a\n"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c new file mode 100644 index 0000000..9b24aa1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c @@ -0,0 +1,6 @@ +#include + +void b() +{ + printf ("In function b\n"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c new file mode 100644 index 0000000..a04558a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c @@ -0,0 +1,11 @@ +#include + +extern void a(); +extern void b(); + +int main () +{ + a(); + b(); + return 0; +} diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc new file mode 100644 index 0000000..9d592b0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc @@ -0,0 +1,42 @@ += Glossary + +action :: + Code to be executed in order to perform a task. Actions in a Rakefile are + specified in a code block. (Usually delimited by +do+/+end+ pairs.) + +execute :: + When a task is executed, all of its actions are performed in the order they + were defined. Note that, unlike invoke, execute always + executes the actions (without invoking or executing the prerequisites). + +file task (Rake::FileTask) :: + A file task is a task whose purpose is to create a file (which has the same + name as the task). When invoked, a file task will only execute if one or + more of the following conditions are true. + + 1. The associated file does not exist. + 2. A prerequisite has a later time stamp than the existing file. + + Because normal Tasks always have the current time as timestamp, a FileTask + that has a normal Task prerequisite will always execute. + +invoke :: + When a task is invoked, first we check to see if it has been invoked before. + If it has been, then nothing else is done. If this is the first time it has + been invoked, then we invoke each of its prerequisites. Finally, we check + to see if we need to execute the actions of this task by calling + Rake::Task#needed?. If the task is needed, we execute its actions. + + NOTE: Prerequisites are still invoked even if the task is not needed. + +prerequisites :: + Every task has a (possibly empty) set of prerequisites. A prerequisite P to + Task T is itself a task that must be invoked before Task T. + +rule :: + A rule is a recipe for synthesizing a task when no task is explicitly + defined. Rules generally synthesize file tasks. + +task (Rake::Task) :: + The basic unit of work in a Rakefile. A task has a name, a set of + prerequisites, and a list of actions to be performed. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb new file mode 100644 index 0000000..531aa75 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb @@ -0,0 +1,592 @@ +# frozen_string_literal: true +module RDoc +module Page + +FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif" + +STYLE = < pre { + padding: 0.5em; + border: 1px dotted black; + background: #FFE; +} + +CSS + +XHTML_PREAMBLE = %{ + +} + +HEADER = XHTML_PREAMBLE + < + + %title% + + + + + + + +ENDHEADER + +FILE_PAGE = < + + + + +
File
%short_name%
+ + + + + + + + + +
Path:%full_path% +IF:cvsurl +  (CVS) +ENDIF:cvsurl +
Modified:%dtm_modified%
+
+ +
+HTML + +################################################################### + +CLASS_PAGE = < + %classmod%
%full_name% + + + + + + +IF:parent + + + + +ENDIF:parent +
In: +START:infiles +HREF:full_path_url:full_path: +IF:cvsurl + (CVS) +ENDIF:cvsurl +END:infiles +
Parent: +IF:par_url + +ENDIF:par_url +%parent% +IF:par_url + +ENDIF:par_url +
+ + + +HTML + +################################################################### + +METHOD_LIST = < +IF:diagram +
+ %diagram% +
+ENDIF:diagram + +IF:description +
%description%
+ENDIF:description + +IF:requires +
Required Files
+
    +START:requires +
  • HREF:aref:name:
  • +END:requires +
+ENDIF:requires + +IF:toc +
Contents
+ +ENDIF:toc + +IF:methods +
Methods
+
    +START:methods +
  • HREF:aref:name:
  • +END:methods +
+ENDIF:methods + +IF:includes +
Included Modules
+
    +START:includes +
  • HREF:aref:name:
  • +END:includes +
+ENDIF:includes + +START:sections +IF:sectitle + +IF:seccomment +
+%seccomment% +
+ENDIF:seccomment +ENDIF:sectitle + +IF:classlist +
Classes and Modules
+ %classlist% +ENDIF:classlist + +IF:constants +
Constants
+ +START:constants + + + + + +IF:desc + + + + +ENDIF:desc +END:constants +
%name%=%value%
 %desc%
+ENDIF:constants + +IF:attributes +
Attributes
+ +START:attributes + + + + + +END:attributes +
+IF:rw +[%rw%] +ENDIF:rw + %name%%a_desc%
+ENDIF:attributes + +IF:method_list +START:method_list +IF:methods +
%type% %category% methods
+START:methods +
+
+IF:callseq + %callseq% +ENDIF:callseq +IFNOT:callseq + %name%%params% +ENDIF:callseq +IF:codeurl +[ source ] +ENDIF:codeurl +
+IF:m_desc +
+ %m_desc% +
+ENDIF:m_desc +IF:aka +
+ This method is also aliased as +START:aka + %name% +END:aka +
+ENDIF:aka +IF:sourcecode +
+ +
+
+%sourcecode%
+
+
+
+ENDIF:sourcecode +
+END:methods +ENDIF:methods +END:method_list +ENDIF:method_list +END:sections + +HTML + +FOOTER = < + +ENDFOOTER + +BODY = HEADER + < + +
+ #{METHOD_LIST} +
+ + #{FOOTER} +ENDBODY + +########################## Source code ########################## + +SRC_PAGE = XHTML_PREAMBLE + < +%title% + + + + +
%code%
+ + +HTML + +########################## Index ################################ + +FR_INDEX_BODY = < + + + + + + + +
+START:entries +%name%
+END:entries +
+ +HTML + +CLASS_INDEX = FILE_INDEX +METHOD_INDEX = FILE_INDEX + +INDEX = XHTML_PREAMBLE + < + + %title% + + + + + + + + + +IF:inline_source + +ENDIF:inline_source +IFNOT:inline_source + + + + +ENDIF:inline_source + + <body bgcolor="white"> + Click <a href="html/index.html">here</a> for a non-frames + version of this page. + </body> + + + + +HTML + +end +end + + diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc new file mode 100644 index 0000000..a9e33d1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc @@ -0,0 +1,127 @@ += Original Prototype Rake + +This is the original 100 line prototype rake program. + +--- + #!/usr/bin/env ruby + + require 'ftools' + + class Task + TASKS = Hash.new + + attr_reader :prerequisites + + def initialize(task_name) + @name = task_name + @prerequisites = [] + @actions = [] + end + + def enhance(deps=nil, &block) + @prerequisites |= deps if deps + @actions << block if block_given? + self + end + + def name + @name.to_s + end + + def invoke + @prerequisites.each { |n| Task[n].invoke } + execute if needed? + end + + def execute + return if @triggered + @triggered = true + @actions.collect { |act| result = act.call(self) }.last + end + + def needed? + true + end + + def timestamp + Time.now + end + + class << self + def [](task_name) + TASKS[intern(task_name)] or fail "Don't know how to rake #{task_name}" + end + + def define_task(args, &block) + case args + when Hash + fail "Too Many Target Names: #{args.keys.join(' ')}" if args.size > 1 + fail "No Task Name Given" if args.size < 1 + task_name = args.keys[0] + deps = args[task_name] + else + task_name = args + deps = [] + end + deps = deps.collect {|d| intern(d) } + get(task_name).enhance(deps, &block) + end + + def get(task_name) + name = intern(task_name) + TASKS[name] ||= self.new(name) + end + + def intern(task_name) + (Symbol === task_name) ? task_name : task_name.intern + end + end + end + + class FileTask < Task + def needed? + return true unless File.exist?(name) + latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max + return false if latest_prereq.nil? + timestamp < latest_prereq + end + + def timestamp + File.new(name.to_s).mtime + end + end + + def task(args, &block) + Task.define_task(args, &block) + end + + def file(args, &block) + FileTask.define_task(args, &block) + end + + def sys(cmd) + puts cmd + system(cmd) or fail "Command Failed: [#{cmd}]" + end + + def rake + begin + here = Dir.pwd + while ! File.exist?("Rakefile") + Dir.chdir("..") + fail "No Rakefile found" if Dir.pwd == here + here = Dir.pwd + end + puts "(in #{Dir.pwd})" + load "./Rakefile" + ARGV.push("default") if ARGV.size == 0 + ARGV.each { |task_name| Task[task_name].invoke } + rescue Exception => ex + puts "rake aborted ... #{ex.message}" + puts ex.backtrace.find {|str| str =~ /Rakefile/ } || "" + end + end + + if __FILE__ == $0 then + rake + end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 new file mode 100644 index 0000000..c6bfa25 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 @@ -0,0 +1,156 @@ +.Dd June 12, 2016 +.Dt RAKE 1 +.Os rake 11.2.2 +.Sh NAME +.Nm rake +.Nd make-like build utility for Ruby +.Sh SYNOPSIS +.Nm +.Op Fl f Ar rakefile +.Op Ar options +.Ar targets ... +.Sh DESCRIPTION +.Nm +is a +.Xr make 1 Ns -like +build utility for Ruby. +Tasks and dependencies are specified in standard Ruby syntax. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl m , Fl -multitask +Treat all tasks as multitasks. +.It Fl B , Fl -build-all +Build all prerequisites, including those which are up\-to\-date. +.It Fl j , Fl -jobs Ar num_jobs +Specifies the maximum number of tasks to execute in parallel (default is number of CPU cores + 4). +.El +.Ss Modules +.Bl -tag -width Ds +.It Fl I , Fl -libdir Ar libdir +Include +.Ar libdir +in the search path for required modules. +.It Fl r , Fl -require Ar module +Require +.Ar module +before executing +.Pa rakefile . +.El +.Ss Rakefile location +.Bl -tag -width Ds +.It Fl f , Fl -rakefile Ar filename +Use +.Ar filename +as the rakefile to search for. +.It Fl N , Fl -no-search , Fl -nosearch +Do not search parent directories for the Rakefile. +.It Fl G , Fl -no-system , Fl -nosystem +Use standard project Rakefile search paths, ignore system wide rakefiles. +.It Fl R , Fl -rakelib Ar rakelibdir , Fl -rakelibdir Ar rakelibdir +Auto-import any .rake files in +.Ar rakelibdir +(default is +.Sq rakelib ) +.It Fl g , Fl -system +Use system-wide (global) rakefiles (usually +.Pa ~/.rake/*.rake ) . +.El +.Ss Debugging +.Bl -tag -width Ds +.It Fl -backtrace Ns = Ns Ar out +Enable full backtrace. +.Ar out +can be +.Dv stderr +(default) or +.Dv stdout . +.It Fl t , Fl -trace Ns = Ns Ar out +Turn on invoke/execute tracing, enable full backtrace. +.Ar out +can be +.Dv stderr +(default) or +.Dv stdout . +.It Fl -suppress-backtrace Ar pattern +Suppress backtrace lines matching regexp +.Ar pattern . +Ignored if +.Fl -trace +is on. +.It Fl -rules +Trace the rules resolution. +.It Fl n , Fl -dry-run +Do a dry run without executing actions. +.It Fl T , Fl -tasks Op Ar pattern +Display the tasks (matching optional +.Ar pattern ) +with descriptions, then exit. +.It Fl D , Fl -describe Op Ar pattern +Describe the tasks (matching optional +.Ar pattern ) , +then exit. +.It Fl W , Fl -where Op Ar pattern +Describe the tasks (matching optional +.Ar pattern ) , +then exit. +.It Fl P , Fl -prereqs +Display the tasks and dependencies, then exit. +.It Fl e , Fl -execute Ar code +Execute some Ruby code and exit. +.It Fl p , Fl -execute-print Ar code +Execute some Ruby code, print the result, then exit. +.It Fl E , Fl -execute-continue Ar code +Execute some Ruby code, then continue with normal task processing. +.El +.Ss Information +.Bl -tag -width Ds +.It Fl v , Fl -verbose +Log message to standard output. +.It Fl q , Fl -quiet +Do not log messages to standard output. +.It Fl s , Fl -silent +Like +.Fl -quiet , +but also suppresses the +.Sq in directory +announcement. +.It Fl X , Fl -no-deprecation-warnings +Disable the deprecation warnings. +.It Fl -comments +Show commented tasks only +.It Fl A , Fl -all +Show all tasks, even uncommented ones (in combination with +.Fl T +or +.Fl D ) +.It Fl -job-stats Op Ar level +Display job statistics. +If +.Ar level +is +.Sq history , +displays a complete job list. +.It Fl V , Fl -version +Display the program version. +.It Fl h , Fl H , Fl -help +Display a help message. +.El +.Sh SEE ALSO +The complete documentation for +.Nm rake +has been installed at +.Pa /usr/share/doc/rake-doc/html/index.html . +It is also available online at +.Lk https://ruby.github.io/rake . +.Sh AUTHORS +.An -nosplit +.Nm +was written by +.An Jim Weirich Aq Mt jim@weirichhouse.org . +.Pp +This manual was created by +.An Caitlin Matos Aq Mt caitlin.matos@zoho.com +for the Debian project (but may be used by others). +It was inspired by the manual by +.An Jani Monoses Aq Mt jani@iv.ro +for the Ubuntu project. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc new file mode 100644 index 0000000..4014306 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc @@ -0,0 +1,622 @@ += Rakefile Format + +First of all, there is no special format for a Rakefile. A Rakefile +contains executable Ruby code. Anything legal in a ruby script is +allowed in a Rakefile. + +Now that we understand there is no special syntax in a Rakefile, there +are some conventions that are used in a Rakefile that are a little +unusual in a typical Ruby program. Since a Rakefile is tailored to +specifying tasks and actions, the idioms used in a Rakefile are +designed to support that. + +So, what goes into a Rakefile? + +== Tasks + +Tasks are the main unit of work in a Rakefile. Tasks have a name +(usually given as a symbol or a string), a list of prerequisites (more +symbols or strings) and a list of actions (given as a block). + +=== Simple Tasks + +A task is declared by using the +task+ method. +task+ takes a single +parameter that is the name of the task. + + task :name + +=== Tasks with Prerequisites + +Any prerequisites are given as a list (enclosed in square brackets) +following the name and an arrow (=>). + + task name: [:prereq1, :prereq2] + +*NOTE:* Although this syntax looks a little funky, it is legal +Ruby. We are constructing a hash where the key is :name and the value +for that key is the list of prerequisites. It is equivalent to the +following ... + + hash = Hash.new + hash[:name] = [:prereq1, :prereq2] + task(hash) + +You can also use strings for task names and prerequisites, rake doesn't care. +This is the same task definition: + + task 'name' => %w[prereq1 prereq2] + +As is this: + + task name: %w[prereq1 prereq2] + +We'll prefer this style for regular tasks with prerequisites throughout the +rest of the document. Using an array of strings for the prerequisites means +you will need to make fewer changes if you need to move tasks into namespaces +or perform other refactorings. + +=== Tasks with Actions + +Actions are defined by passing a block to the +task+ method. Any Ruby +code can be placed in the block. The block may reference the task +object via the block parameter. + + task name: [:prereq1, :prereq2] do |t| + # actions (may reference t) + end + +=== Multiple Definitions + +A task may be specified more than once. Each specification adds its +prerequisites and actions to the existing definition. This allows one +part of a rakefile to specify the actions and a different rakefile +(perhaps separately generated) to specify the dependencies. + +For example, the following is equivalent to the single task +specification given above. + + task :name + task name: :prereq1 + task name: %w[prereq2] + task :name do |t| + # actions + end + +== File Tasks + +Some tasks are designed to create a file from one or more other files. +Tasks that generate these files may be skipped if the file already +exists. File tasks are used to specify file creation tasks. + +File tasks are declared using the +file+ method (instead of the +task+ +method). In addition, file tasks are usually named with a string +rather than a symbol. + +The following file task creates a executable program (named +prog+) +given two object files named +a.o+ and +b.o+. The tasks +for creating +a.o+ and +b.o+ are not shown. + + file "prog" => ["a.o", "b.o"] do |t| + sh "cc -o #{t.name} #{t.prerequisites.join(' ')}" + end + +== Directory Tasks + +It is common to need to create directories upon demand. The ++directory+ convenience method is a short-hand for creating a FileTask +that creates the directory. For example, the following declaration +... + + directory "testdata/examples/doc" + +is equivalent to ... + + file "testdata" do |t| mkdir t.name end + file "testdata/examples" => ["testdata"] do |t| mkdir t.name end + file "testdata/examples/doc" => ["testdata/examples"] do |t| mkdir t.name end + +The +directory+ method does not accept prerequisites or actions, but +both prerequisites and actions can be added later. For example ... + + directory "testdata" + file "testdata" => ["otherdata"] + file "testdata" do + cp Dir["standard_data/*.data"], "testdata" + end + +== Tasks with Parallel Prerequisites + +Rake allows parallel execution of prerequisites using the following syntax: + + multitask copy_files: %w[copy_src copy_doc copy_bin] do + puts "All Copies Complete" + end + +In this example, +copy_files+ is a normal rake task. Its actions are +executed whenever all of its prerequisites are done. The big +difference is that the prerequisites (+copy_src+, +copy_bin+ and ++copy_doc+) are executed in parallel. Each of the prerequisites are +run in their own Ruby thread, possibly allowing faster overall runtime. + +=== Secondary Prerequisites + +If any of the primary prerequisites of a multitask have common secondary +prerequisites, all of the primary/parallel prerequisites will wait +until the common prerequisites have been run. + +For example, if the copy_xxx tasks have the +following prerequisites: + + task copy_src: :prep_for_copy + task copy_bin: :prep_for_copy + task copy_doc: :prep_for_copy + +Then the +prep_for_copy+ task is run before starting all the copies in +parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+, +and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is +run only once, even though it is referenced in multiple threads. + +=== Thread Safety + +The Rake internal data structures are thread-safe with respect +to the multitask parallel execution, so there is no need for the user +to do extra synchronization for Rake's benefit. However, if there are +user data structures shared between the parallel prerequisites, the +user must do whatever is necessary to prevent race conditions. + +== Tasks with Arguments + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.2] + +And the string "0.8.2" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire name + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +=== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, [:first_name, :last_name] + +The first argument is still the name of the task (:name in this case). +The next two arguments are the names of the parameters expected by +:name in an array (:first_name and :last_name in the example). + +To access the values of the parameters, the block defining the task +behaviour can now accept a second parameter: + + task :name, [:first_name, :last_name] do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. + +If you wish to specify default values for the arguments, you can use +the with_defaults method in the task body. Here is the above example +where we specify default values for the first and last names: + + task :name, [:first_name, :last_name] do |t, args| + args.with_defaults(:first_name => "John", :last_name => "Dough") + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +=== Tasks that Expect Parameters and Have Prerequisites + +Tasks that use parameters have a slightly different format for +prerequisites. Use the arrow notation to indicate the prerequisites +for tasks with arguments. For example: + + task :name, [:first_name, :last_name] => [:pre_name] do |t, args| + args.with_defaults(:first_name => "John", :last_name => "Dough") + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +=== Tasks that take Variable-length Parameters + +Tasks that need to handle a list of values as a parameter can use the +extras method of the args variable. This allows for tasks that can +loop over a variable number of values, and its compatible with named +parameters as well: + + task :email, [:message] do |t, args| + mail = Mail.new(args.message) + recipients = args.extras + recipients.each do |target| + mail.send_to(target) + end + end + +There is also the convenience method to_a that returns all parameters +in the sequential order they were given, including those associated +with named parameters. + +=== Deprecated Task Parameters Format + +There is an older format for declaring task parameters that omitted +the task argument array and used the :needs keyword to introduce the +dependencies. That format is still supported for compatibility, but +is not recommended for use. The older format may be dropped in future +versions of rake. + +== Accessing Task Programmatically + +Sometimes it is useful to manipulate tasks programmatically in a +Rakefile. To find a task object use Rake::Task.[]. + +=== Programmatic Task Example + +For example, the following Rakefile defines two tasks. The :doit task +simply prints a simple "DONE" message. The :dont class will lookup +the doit class and remove (clear) all of its prerequisites and +actions. + + task :doit do + puts "DONE" + end + + task :dont do + Rake::Task[:doit].clear + end + +Running this example: + + $ rake doit + (in /Users/jim/working/git/rake/x) + DONE + $ rake dont doit + (in /Users/jim/working/git/rake/x) + $ + +The ability to programmatically manipulate tasks gives rake very +powerful meta-programming capabilities w.r.t. task execution, but +should be used with caution. + +== Rules + +When a file is named as a prerequisite, but does not have a file task +defined for it, Rake will attempt to synthesize a task by looking at a +list of rules supplied in the Rakefile. + +Suppose we were trying to invoke task "mycode.o", but no task is +defined for it. But the rakefile has a rule that look like this ... + + rule '.o' => ['.c'] do |t| + sh "cc #{t.source} -c -o #{t.name}" + end + +This rule will synthesize any task that ends in ".o". It has a +prerequisite a source file with an extension of ".c" must exist. If +Rake is able to find a file named "mycode.c", it will automatically +create a task that builds "mycode.o" from "mycode.c". + +If the file "mycode.c" does not exist, rake will attempt +to recursively synthesize a rule for it. + +When a task is synthesized from a rule, the +source+ attribute of the +task is set to the matching source file. This allows us to write +rules with actions that reference the source file. + +=== Advanced Rules + +Any regular expression may be used as the rule pattern. Additionally, +a proc may be used to calculate the name of the source file. This +allows for complex patterns and sources. + +The following rule is equivalent to the example above. + + rule( /\.o$/ => [ + proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') } + ]) do |t| + sh "cc #{t.source} -c -o #{t.name}" + end + +*NOTE:* Because of a _quirk_ in Ruby syntax, parenthesis are +required on *rule* when the first argument is a regular expression. + +The following rule might be used for Java files ... + + rule '.class' => [ + proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') } + ] do |t| + java_compile(t.source, t.name) + end + +*NOTE:* +java_compile+ is a hypothetical method that invokes the +java compiler. + +== Importing Dependencies + +Any ruby file (including other rakefiles) can be included with a +standard Ruby +require+ command. The rules and declarations in the +required file are just added to the definitions already accumulated. + +Because the files are loaded _before_ the rake targets are evaluated, +the loaded files must be "ready to go" when the rake command is +invoked. This makes generated dependency files difficult to use. By +the time rake gets around to updating the dependencies file, it is too +late to load it. + +The +import+ command addresses this by specifying a file to be loaded +_after_ the main rakefile is loaded, but _before_ any targets on the +command line are invoked. In addition, if the file name matches an +explicit task, that task is invoked before loading the file. This +allows dependency files to be generated and used in a single rake +command invocation. + +Example: + + require 'rake/loaders/makefile' + + file ".depends.mf" => [SRC_LIST] do |t| + sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" + end + + import ".depends.mf" + +If ".depends" does not exist, or is out of date w.r.t. the source +files, a new ".depends" file is generated using +makedepend+ before +loading. + +== Comments + +Standard Ruby comments (beginning with "#") can be used anywhere it is +legal in Ruby source code, including comments for tasks and rules. +However, if you wish a task to be described using the "-T" switch, +then you need to use the +desc+ command to describe the task. + +Example: + + desc "Create a distribution package" + task package: %w[ ... ] do ... end + +The "-T" switch (or "--tasks" if you like to spell things out) will +display a list of tasks that have a description. If you use +desc+ to +describe your major tasks, you have a semi-automatic way of generating +a summary of your Rake file. + + $ rake -T + (in /home/.../rake) + rake clean # Remove any temporary products. + rake clobber # Remove any generated file. + rake clobber_rdoc # Remove rdoc products + rake contrib_test # Run tests for contrib_test + rake default # Default Task + rake install # Install the application + rake lines # Count lines in the main rake file + rake rdoc # Build the rdoc HTML Files + rake rerdoc # Force a rebuild of the RDOC files + rake test # Run tests + rake testall # Run all test targets + +Only tasks with descriptions will be displayed with the "-T" switch. +Use "-P" (or "--prereqs") to get a list of all tasks and their +prerequisites. + +== Namespaces + +As projects grow (and along with it, the number of tasks), it is +common for task names to begin to clash. For example, if you might +have a main program and a set of sample programs built by a single +Rakefile. By placing the tasks related to the main program in one +namespace, and the tasks for building the sample programs in a +different namespace, the task names will not interfere with each other. + +For example: + + namespace "main" do + task :build do + # Build the main program + end + end + + namespace "samples" do + task :build do + # Build the sample programs + end + end + + task build: %w[main:build samples:build] + +Referencing a task in a separate namespace can be achieved by +prefixing the task name with the namespace and a colon +(e.g. "main:build" refers to the :build task in the +main+ namespace). +Nested namespaces are supported. + +Note that the name given in the +task+ command is always the unadorned +task name without any namespace prefixes. The +task+ command always +defines a task in the current namespace. + +=== FileTasks + +File task names are not scoped by the namespace command. Since the +name of a file task is the name of an actual file in the file system, +it makes little sense to include file task names in name space. +Directory tasks (created by the +directory+ command) are a type of +file task and are also not affected by namespaces. + +=== Name Resolution + +When looking up a task name, rake will start with the current +namespace and attempt to find the name there. If it fails to find a +name in the current namespace, it will search the parent namespaces +until a match is found (or an error occurs if there is no match). + +The "rake" namespace is a special implicit namespace that refers to +the toplevel names. + +If a task name begins with a "^" character, the name resolution will +start in the parent namespace. Multiple "^" characters are allowed. + +Here is an example file with multiple :run tasks and how various names +resolve in different locations. + + task :run + + namespace "one" do + task :run + + namespace "two" do + task :run + + # :run => "one:two:run" + # "two:run" => "one:two:run" + # "one:two:run" => "one:two:run" + # "one:run" => "one:run" + # "^run" => "one:run" + # "^^run" => "rake:run" (the top level task) + # "rake:run" => "rake:run" (the top level task) + end + + # :run => "one:run" + # "two:run" => "one:two:run" + # "^run" => "rake:run" + end + + # :run => "rake:run" + # "one:run" => "one:run" + # "one:two:run" => "one:two:run" + +== FileLists + +FileLists are the way Rake manages lists of files. You can treat a +FileList as an array of strings for the most part, but FileLists +support some additional operations. + +=== Creating a FileList + +Creating a file list is easy. Just give it the list of file names: + + fl = FileList['file1.rb', file2.rb'] + +Or give it a glob pattern: + + fl = FileList['*.rb'] + +== Odds and Ends + +=== do/end versus { } + +Blocks may be specified with either a +do+/+end+ pair, or with curly +braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the +actions for tasks and rules. Because the rakefile idiom tends to +leave off parentheses on the task/file/rule methods, unusual +ambiguities can arise when using curly braces. + +For example, suppose that the method +object_files+ returns a list of +object files in a project. Now we use +object_files+ as the +prerequisites in a rule specified with actions in curly braces. + + # DON'T DO THIS! + file "prog" => object_files { + # Actions are expected here (but it doesn't work)! + } + +Because curly braces have a higher precedence than +do+/+end+, the +block is associated with the +object_files+ method rather than the ++file+ method. + +This is the proper way to specify the task ... + + # THIS IS FINE + file "prog" => object_files do + # Actions go here + end + +== Rakefile Path + +When issuing the +rake+ command in a terminal, Rake will look +for a Rakefile in the current directory. If a Rakefile is not found, +it will search parent directories until one is found. + +For example, if a Rakefile resides in the +project/+ directory, +moving deeper into the project's directory tree will not have an adverse +effect on rake tasks: + + $ pwd + /home/user/project + + $ cd lib/foo/bar + $ pwd + /home/user/project/lib/foo/bar + + $ rake run_pwd + /home/user/project + +As far as rake is concerned, all tasks are run from the directory in +which the Rakefile resides. + +=== Multiple Rake Files + +Not all tasks need to be included in a single Rakefile. Additional +rake files (with the file extension "+.rake+") may be placed in ++rakelib+ directory located at the top level of a project (i.e. +the same directory that contains the main +Rakefile+). + +Also, rails projects may include additional rake files in the ++lib/tasks+ directory. + +=== Clean and Clobber Tasks + +Through require 'rake/clean' Rake provides +clean+ and +clobber+ +tasks: + ++clean+ :: + Clean up the project by deleting scratch files and backup files. Add files + to the +CLEAN+ FileList to have the +clean+ target handle them. + ++clobber+ :: + Clobber all generated and non-source files in a project. The task depends + on +clean+, so all the +CLEAN+ files will be deleted as well as files in the + +CLOBBER+ FileList. The intent of this task is to return a project to its + pristine, just unpacked state. + +You can add file names or glob patterns to both the +CLEAN+ and +CLOBBER+ +lists. + +=== Phony Task + +The phony task can be used as a dependency to allow file-based tasks to use +non-file-based-tasks as prerequisites without forcing them to rebuild. You +can require 'rake/phony' to add the +phony+ task. + +---- + +== See + +* README.rdoc -- Main documentation for Rake. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc new file mode 100644 index 0000000..0e1c338 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc @@ -0,0 +1,151 @@ += Why rake? + +Ok, let me state from the beginning that I never intended to write this +code. I'm not convinced it is useful, and I'm not convinced anyone +would even be interested in it. All I can say is that Why's onion truck +must by been passing through the Ohio valley. + +What am I talking about? ... A Ruby version of Make. + +See, I can sense you cringing already, and I agree. The world certainly +doesn't need yet another reworking of the "make" program. I mean, we +already have "ant". Isn't that enough? + +It started yesterday. I was helping a coworker fix a problem in one of +the Makefiles we use in our project. Not a particularly tough problem, +but during the course of the conversation I began lamenting some of the +shortcomings of make. In particular, in one of my makefiles I wanted to +determine the name of a file dynamically and had to resort to some +simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you +could just use Ruby inside a Makefile" I said. + +My coworker (a recent convert to Ruby) agreed, but wondered what it +would look like. So I sketched the following on the whiteboard... + + "What if you could specify the make tasks in Ruby, like this ..." + + task "build" do + java_compile(...args, etc ...) + end + + "The task function would register "build" as a target to be made, + and the block would be the action executed whenever the build + system determined that it was time to do the build target." + +We agreed that would be cool, but writing make from scratch would be WAY +too much work. And that was the end of that! + +... Except I couldn't get the thought out of my head. What exactly +would be needed to make the about syntax work as a make file? Hmmm, you +would need to register the tasks, you need some way of specifying +dependencies between tasks, and some way of kicking off the process. +Hey! What if we did ... and fifteen minutes later I had a working +prototype of Ruby make, complete with dependencies and actions. + +I showed the code to my coworker and we had a good laugh. It was just +about a page worth of code that reproduced an amazing amount of the +functionality of make. We were both truly stunned with the power of +Ruby. + +But it didn't do everything make did. In particular, it didn't have +timestamp based file dependencies (where a file is rebuilt if any of its +prerequisite files have a later timestamp). Obviously THAT would be a +pain to add and so Ruby Make would remain an interesting experiment. + +... Except as I walked back to my desk, I started thinking about what +file based dependencies would really need. Rats! I was hooked again, +and by adding a new class and two new methods, file/timestamp +dependencies were implemented. + +Ok, now I was really hooked. Last night (during CSI!) I massaged the +code and cleaned it up a bit. The result is a bare-bones replacement +for make in exactly 100 lines of code. + +For the curious, you can see it at ... +* doc/proto_rake.rdoc + +Oh, about the name. When I wrote the example Ruby Make task on my +whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ... +Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves +and Rake would clean them up ... or something like that. Anyways, the +name stuck. + +Some quick examples ... + +A simple task to delete backup files ... + + task :clean do + Dir['*~'].each {|fn| rm fn rescue nil} + end + +Note that task names are symbols (they are slightly easier to type +than quoted strings ... but you may use quoted string if you would +rather). Rake makes the methods of the FileUtils module directly +available, so we take advantage of the rm command. Also note +the use of "rescue nil" to trap and ignore errors in the rm +command. + +To run it, just type "rake clean". Rake will automatically find a +Rakefile in the current directory (or above!) and will invoke the +targets named on the command line. If there are no targets explicitly +named, rake will invoke the task "default". + +Here's another task with dependencies ... + + task :clobber => [:clean] do + rm_r "tempdir" + end + +Task :clobber depends upon task :clean, so :clean will be run before +:clobber is executed. + +Files are specified by using the "file" command. It is similar to the +task command, except that the task name represents a file, and the task +will be run only if the file doesn't exist, or if its modification time +is earlier than any of its prerequisites. + +Here is a file based dependency that will compile "hello.cc" to +"hello.o". + + file "hello.cc" + file "hello.o" => ["hello.cc"] do |t| + srcfile = t.name.sub(/\.o$/, ".cc") + sh %{g++ #{srcfile} -c -o #{t.name}} + end + +I normally specify file tasks with string (rather than symbols). Some +file names can't be represented by symbols. Plus it makes the +distinction between them more clear to the casual reader. + +Currently writing a task for each and every file in the project would be +tedious at best. I envision a set of libraries to make this job +easier. For instance, perhaps something like this ... + + require 'rake/ctools' + Dir['*.c'].each do |fn| + c_source_file(fn) + end + +where "c_source_file" will create all the tasks need to compile all the +C source files in a directory. Any number of useful libraries could be +created for rake. + +That's it. There's no documentation (other than whats in this +message). Does this sound interesting to anyone? If so, I'll continue +to clean it up and write it up and publish it on RAA. Otherwise, I'll +leave it as an interesting exercise and a tribute to the power of Ruby. + +Why /might/ rake be interesting to Ruby programmers. I don't know, +perhaps ... + +* No weird make syntax (only weird Ruby syntax :-) +* No need to edit or read XML (a la ant) +* Platform independent build scripts. +* Will run anywhere Ruby exists, so no need to have "make" installed. + If you stay away from the "sys" command and use things like + 'ftools', you can have a perfectly platform independent + build script. Also rake is only 100 lines of code, so it can + easily be packaged along with the rest of your code. + +So ... Sorry for the long rambling message. Like I said, I never +intended to write this code at all. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake new file mode 100755 index 0000000..a00975f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby + +#-- +# Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +#++ + +require "rake" + +Rake.application.run diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb new file mode 100644 index 0000000..2006fba --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true +#-- +# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +#++ + +module Rake; end + +require_relative "rake/version" + +require "rbconfig" +require "fileutils" +require "singleton" +require "monitor" +require "optparse" + +require_relative "rake/ext/string" + +require_relative "rake/win32" + +require_relative "rake/linked_list" +require_relative "rake/cpu_counter" +require_relative "rake/scope" +require_relative "rake/task_argument_error" +require_relative "rake/rule_recursion_overflow_error" +require_relative "rake/rake_module" +require_relative "rake/trace_output" +require_relative "rake/pseudo_status" +require_relative "rake/task_arguments" +require_relative "rake/invocation_chain" +require_relative "rake/task" +require_relative "rake/file_task" +require_relative "rake/file_creation_task" +require_relative "rake/multi_task" +require_relative "rake/dsl_definition" +require_relative "rake/file_utils_ext" +require_relative "rake/file_list" +require_relative "rake/default_loader" +require_relative "rake/early_time" +require_relative "rake/late_time" +require_relative "rake/name_space" +require_relative "rake/task_manager" +require_relative "rake/application" +require_relative "rake/backtrace" + +# :stopdoc: +# +# Some top level Constants. + +FileList = Rake::FileList +RakeFileUtils = Rake::FileUtilsExt diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb new file mode 100644 index 0000000..87ae47b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb @@ -0,0 +1,854 @@ +# frozen_string_literal: true +require "optparse" + +require_relative "task_manager" +require_relative "file_list" +require_relative "thread_pool" +require_relative "thread_history_display" +require_relative "trace_output" +require_relative "win32" + +module Rake + + CommandLineOptionError = Class.new(StandardError) + + ## + # Rake main application object. When invoking +rake+ from the + # command line, a Rake::Application object is created and run. + + class Application + include TaskManager + include TraceOutput + + # The name of the application (typically 'rake') + attr_reader :name + + # The original directory where rake was invoked. + attr_reader :original_dir + + # Name of the actual rakefile used. + attr_reader :rakefile + + # Number of columns on the terminal + attr_accessor :terminal_columns + + # List of the top level task names (task names from the command line). + attr_reader :top_level_tasks + + # Override the detected TTY output state (mostly for testing) + attr_writer :tty_output + + DEFAULT_RAKEFILES = [ + "rakefile", + "Rakefile", + "rakefile.rb", + "Rakefile.rb" + ].freeze + + # Initialize a Rake::Application object. + def initialize + super + @name = "rake" + @rakefiles = DEFAULT_RAKEFILES.dup + @rakefile = nil + @pending_imports = [] + @imported = [] + @loaders = {} + @default_loader = Rake::DefaultLoader.new + @original_dir = Dir.pwd + @top_level_tasks = [] + add_loader("rb", DefaultLoader.new) + add_loader("rf", DefaultLoader.new) + add_loader("rake", DefaultLoader.new) + @tty_output = STDOUT.tty? + @terminal_columns = ENV["RAKE_COLUMNS"].to_i + + set_default_options + end + + # Run the Rake application. The run method performs the following + # three steps: + # + # * Initialize the command line options (+init+). + # * Define the tasks (+load_rakefile+). + # * Run the top level tasks (+top_level+). + # + # If you wish to build a custom rake command, you should call + # +init+ on your application. Then define any tasks. Finally, + # call +top_level+ to run your top level tasks. + def run(argv = ARGV) + standard_exception_handling do + init "rake", argv + load_rakefile + top_level + end + end + + # Initialize the command line parameters and app name. + def init(app_name="rake", argv = ARGV) + standard_exception_handling do + @name = app_name + begin + args = handle_options argv + rescue ArgumentError + # Backward compatibility for capistrano + args = handle_options + end + load_debug_at_stop_feature + collect_command_line_tasks(args) + end + end + + def load_debug_at_stop_feature + return unless ENV["RAKE_DEBUG"] + require "debug/session" + DEBUGGER__::start no_sigint_hook: true, nonstop: true + Rake::Task.prepend Module.new { + def execute(*) + exception = DEBUGGER__::SESSION.capture_exception_frames(/(exe|bin|lib)\/rake/) do + super + end + + if exception + STDERR.puts exception.message + DEBUGGER__::SESSION.enter_postmortem_session exception + raise exception + end + end + } + rescue LoadError + end + private :load_debug_at_stop_feature + + # Find the rakefile and then load it and any pending imports. + def load_rakefile + standard_exception_handling do + raw_load_rakefile + end + end + + # Run the top level tasks of a Rake application. + def top_level + run_with_threads do + if options.show_tasks + display_tasks_and_comments + elsif options.show_prereqs + display_prerequisites + else + top_level_tasks.each { |task_name| invoke_task(task_name) } + end + end + end + + # Run the given block with the thread startup and shutdown. + def run_with_threads + thread_pool.gather_history if options.job_stats == :history + + yield + + thread_pool.join if defined?(@thread_pool) + if options.job_stats + stats = thread_pool.statistics + puts "Maximum active threads: #{stats[:max_active_threads]} + main" + puts "Total threads in play: #{stats[:total_threads_in_play]} + main" + end + ThreadHistoryDisplay.new(thread_pool.history).show if + options.job_stats == :history + end + + # Add a loader to handle imported files ending in the extension + # +ext+. + def add_loader(ext, loader) + ext = ".#{ext}" unless ext =~ /^\./ + @loaders[ext] = loader + end + + # Application options from the command line + def options + @options ||= Struct.new( + :always_multitask, :backtrace, :build_all, :dryrun, + :ignore_deprecate, :ignore_system, :job_stats, :load_system, + :nosearch, :rakelib, :show_all_tasks, :show_prereqs, + :show_task_pattern, :show_tasks, :silent, :suppress_backtrace_pattern, + :thread_pool_size, :trace, :trace_output, :trace_rules + ).new + end + + # Return the thread pool used for multithreaded processing. + def thread_pool # :nodoc: + @thread_pool ||= ThreadPool.new(options.thread_pool_size || Rake.suggested_thread_count-1) + end + + # internal ---------------------------------------------------------------- + + # Invokes a task with arguments that are extracted from +task_string+ + def invoke_task(task_string) # :nodoc: + name, args = parse_task_string(task_string) + t = self[name] + t.invoke(*args) + end + + def parse_task_string(string) # :nodoc: + /^([^\[]+)(?:\[(.*)\])$/ =~ string.to_s + + name = $1 + remaining_args = $2 + + return string, [] unless name + return name, [] if remaining_args.empty? + + args = [] + + begin + /\s*((?:[^\\,]|\\.)*?)\s*(?:,\s*(.*))?$/ =~ remaining_args + + remaining_args = $2 + args << $1.gsub(/\\(.)/, '\1') + end while remaining_args + + return name, args + end + + # Provide standard exception handling for the given block. + def standard_exception_handling # :nodoc: + yield + rescue SystemExit + # Exit silently with current status + raise + rescue OptionParser::InvalidOption => ex + $stderr.puts ex.message + exit(false) + rescue Exception => ex + # Exit with error message + display_error_message(ex) + exit_because_of_exception(ex) + end + + # Exit the program because of an unhandled exception. + # (may be overridden by subclasses) + def exit_because_of_exception(ex) # :nodoc: + exit(false) + end + + # Display the error message that caused the exception. + def display_error_message(ex) # :nodoc: + trace "#{name} aborted!" + display_exception_details(ex) + trace "Tasks: #{ex.chain}" if has_chain?(ex) + trace "(See full trace by running task with --trace)" unless + options.backtrace + end + + def display_exception_details(ex) # :nodoc: + display_exception_details_seen << ex + + display_exception_message_details(ex) + display_exception_backtrace(ex) if ex.backtrace + display_cause_details(ex.cause) if has_cause?(ex) + end + + def display_cause_details(ex) # :nodoc: + return if display_exception_details_seen.include? ex + + trace "\nCaused by:" + display_exception_details(ex) + end + + def display_exception_details_seen # :nodoc: + Thread.current[:rake_display_exception_details_seen] ||= [] + end + + def has_cause?(ex) # :nodoc: + ex.respond_to?(:cause) && ex.cause + end + + def display_exception_message_details(ex) # :nodoc: + if ex.instance_of?(RuntimeError) + trace ex.message + elsif ex.respond_to?(:detailed_message) + trace "#{ex.class.name}: #{ex.detailed_message(highlight: false)}" + else + trace "#{ex.class.name}: #{ex.message}" + end + end + + def display_exception_backtrace(ex) # :nodoc: + if options.backtrace + trace ex.backtrace.join("\n") + else + trace Backtrace.collapse(ex.backtrace).join("\n") + end + end + + # Warn about deprecated usage. + # + # Example: + # Rake.application.deprecate("import", "Rake.import", caller.first) + # + def deprecate(old_usage, new_usage, call_site) # :nodoc: + unless options.ignore_deprecate + $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + + "Please use '#{new_usage}' instead.\n" + + " at #{call_site}" + end + end + + # Does the exception have a task invocation chain? + def has_chain?(exception) # :nodoc: + exception.respond_to?(:chain) && exception.chain + end + private :has_chain? + + # True if one of the files in RAKEFILES is in the current directory. + # If a match is found, it is copied into @rakefile. + def have_rakefile # :nodoc: + @rakefiles.each do |fn| + if File.exist?(fn) + others = FileList.glob(fn, File::FNM_CASEFOLD) + return others.size == 1 ? others.first : fn + elsif fn == "" + return fn + end + end + return nil + end + + # True if we are outputting to TTY, false otherwise + def tty_output? # :nodoc: + @tty_output + end + + # We will truncate output if we are outputting to a TTY or if we've been + # given an explicit column width to honor + def truncate_output? # :nodoc: + tty_output? || @terminal_columns.nonzero? + end + + # Display the tasks and comments. + def display_tasks_and_comments # :nodoc: + displayable_tasks = tasks.select { |t| + (options.show_all_tasks || t.comment) && + t.name =~ options.show_task_pattern + } + case options.show_tasks + when :tasks + width = displayable_tasks.map { |t| t.name_with_args.length }.max || 10 + if truncate_output? + max_column = terminal_width - name.size - width - 7 + else + max_column = nil + end + + displayable_tasks.each do |t| + printf("#{name} %-#{width}s # %s\n", + t.name_with_args, + max_column ? truncate(t.comment, max_column) : t.comment) + end + when :describe + displayable_tasks.each do |t| + puts "#{name} #{t.name_with_args}" + comment = t.full_comment || "" + comment.split("\n").each do |line| + puts " #{line}" + end + puts + end + when :lines + displayable_tasks.each do |t| + t.locations.each do |loc| + printf "#{name} %-30s %s\n", t.name_with_args, loc + end + end + else + fail "Unknown show task mode: '#{options.show_tasks}'" + end + end + + def terminal_width # :nodoc: + if @terminal_columns.nonzero? + result = @terminal_columns + else + result = unix? ? dynamic_width : 80 + end + (result < 10) ? 80 : result + rescue + 80 + end + + # Calculate the dynamic width of the + def dynamic_width # :nodoc: + @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) + end + + def dynamic_width_stty # :nodoc: + %x{stty size 2>/dev/null}.split[1].to_i + end + + def dynamic_width_tput # :nodoc: + %x{tput cols 2>/dev/null}.to_i + end + + def unix? # :nodoc: + RbConfig::CONFIG["host_os"] =~ + /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i + end + + def windows? # :nodoc: + Win32.windows? + end + + def truncate(string, width) # :nodoc: + if string.nil? + "" + elsif string.length <= width + string + else + (string[0, width - 3] || "") + "..." + end + end + + # Display the tasks and prerequisites + def display_prerequisites # :nodoc: + tasks.each do |t| + puts "#{name} #{t.name}" + t.prerequisites.each { |pre| puts " #{pre}" } + end + end + + def trace(*strings) # :nodoc: + options.trace_output ||= $stderr + trace_on(options.trace_output, *strings) + end + + def sort_options(options) # :nodoc: + options.sort_by { |opt| + opt.select { |o| o.is_a?(String) && o =~ /^-/ }.map(&:downcase).sort.reverse + } + end + private :sort_options + + # A list of all the standard options used in rake, suitable for + # passing to OptionParser. + def standard_rake_options # :nodoc: + sort_options( + [ + ["--all", "-A", + "Show all tasks, even uncommented ones (in combination with -T or -D)", + lambda { |value| + options.show_all_tasks = value + } + ], + ["--backtrace=[OUT]", + "Enable full backtrace. OUT can be stderr (default) or stdout.", + lambda { |value| + options.backtrace = true + select_trace_output(options, "backtrace", value) + } + ], + ["--build-all", "-B", + "Build all prerequisites, including those which are up-to-date.", + lambda { |value| + options.build_all = true + } + ], + ["--comments", + "Show commented tasks only", + lambda { |value| + options.show_all_tasks = !value + } + ], + ["--describe", "-D [PATTERN]", + "Describe the tasks (matching optional PATTERN), then exit.", + lambda { |value| + select_tasks_to_show(options, :describe, value) + } + ], + ["--directory", "-C [DIRECTORY]", + "Change to DIRECTORY before doing anything.", + lambda { |value| + Dir.chdir value + @original_dir = Dir.pwd + } + ], + ["--dry-run", "-n", + "Do a dry run without executing actions.", + lambda { |value| + Rake.verbose(true) + Rake.nowrite(true) + options.dryrun = true + options.trace = true + } + ], + ["--execute", "-e CODE", + "Execute some Ruby code and exit.", + lambda { |value| + eval(value) + exit + } + ], + ["--execute-print", "-p CODE", + "Execute some Ruby code, print the result, then exit.", + lambda { |value| + puts eval(value) + exit + } + ], + ["--execute-continue", "-E CODE", + "Execute some Ruby code, " + + "then continue with normal task processing.", + lambda { |value| eval(value) } + ], + ["--jobs", "-j [NUMBER]", + "Specifies the maximum number of tasks to execute in parallel. " + + "(default is number of CPU cores + 4)", + lambda { |value| + if value.nil? || value == "" + value = Float::INFINITY + elsif value =~ /^\d+$/ + value = value.to_i + else + value = Rake.suggested_thread_count + end + value = 1 if value < 1 + options.thread_pool_size = value - 1 + } + ], + ["--job-stats [LEVEL]", + "Display job statistics. " + + "LEVEL=history displays a complete job list", + lambda { |value| + if value =~ /^history/i + options.job_stats = :history + else + options.job_stats = true + end + } + ], + ["--libdir", "-I LIBDIR", + "Include LIBDIR in the search path for required modules.", + lambda { |value| $:.push(value) } + ], + ["--multitask", "-m", + "Treat all tasks as multitasks.", + lambda { |value| options.always_multitask = true } + ], + ["--no-search", "--nosearch", + "-N", "Do not search parent directories for the Rakefile.", + lambda { |value| options.nosearch = true } + ], + ["--prereqs", "-P", + "Display the tasks and dependencies, then exit.", + lambda { |value| options.show_prereqs = true } + ], + ["--quiet", "-q", + "Do not log messages to standard output.", + lambda { |value| Rake.verbose(false) } + ], + ["--rakefile", "-f [FILENAME]", + "Use FILENAME as the rakefile to search for.", + lambda { |value| + value ||= "" + @rakefiles.clear + @rakefiles << value + } + ], + ["--rakelibdir", "--rakelib", "-R RAKELIBDIR", + "Auto-import any .rake files in RAKELIBDIR. " + + "(default is 'rakelib')", + lambda { |value| + options.rakelib = value.split(File::PATH_SEPARATOR) + } + ], + ["--require", "-r MODULE", + "Require MODULE before executing rakefile.", + lambda { |value| + begin + require value + rescue LoadError => ex + begin + rake_require value + rescue LoadError + raise ex + end + end + } + ], + ["--rules", + "Trace the rules resolution.", + lambda { |value| options.trace_rules = true } + ], + ["--silent", "-s", + "Like --quiet, but also suppresses the " + + "'in directory' announcement.", + lambda { |value| + Rake.verbose(false) + options.silent = true + } + ], + ["--suppress-backtrace PATTERN", + "Suppress backtrace lines matching regexp PATTERN. " + + "Ignored if --trace is on.", + lambda { |value| + options.suppress_backtrace_pattern = Regexp.new(value) + } + ], + ["--system", "-g", + "Using system wide (global) rakefiles " + + "(usually '~/.rake/*.rake').", + lambda { |value| options.load_system = true } + ], + ["--no-system", "--nosystem", "-G", + "Use standard project Rakefile search paths, " + + "ignore system wide rakefiles.", + lambda { |value| options.ignore_system = true } + ], + ["--tasks", "-T [PATTERN]", + "Display the tasks (matching optional PATTERN) " + + "with descriptions, then exit. " + + "-AT combination displays all the tasks, including those without descriptions.", + lambda { |value| + select_tasks_to_show(options, :tasks, value) + } + ], + ["--trace=[OUT]", "-t", + "Turn on invoke/execute tracing, enable full backtrace. " + + "OUT can be stderr (default) or stdout.", + lambda { |value| + options.trace = true + options.backtrace = true + select_trace_output(options, "trace", value) + Rake.verbose(true) + } + ], + ["--verbose", "-v", + "Log message to standard output.", + lambda { |value| Rake.verbose(true) } + ], + ["--version", "-V", + "Display the program version.", + lambda { |value| + puts "rake, version #{Rake::VERSION}" + exit + } + ], + ["--where", "-W [PATTERN]", + "Describe the tasks (matching optional PATTERN), then exit.", + lambda { |value| + select_tasks_to_show(options, :lines, value) + options.show_all_tasks = true + } + ], + ["--no-deprecation-warnings", "-X", + "Disable the deprecation warnings.", + lambda { |value| + options.ignore_deprecate = true + } + ], + ]) + end + + def select_tasks_to_show(options, show_tasks, value) # :nodoc: + options.show_tasks = show_tasks + options.show_task_pattern = Regexp.new(value || "") + Rake::TaskManager.record_task_metadata = true + end + private :select_tasks_to_show + + def select_trace_output(options, trace_option, value) # :nodoc: + value = value.strip unless value.nil? + case value + when "stdout" + options.trace_output = $stdout + when "stderr", nil + options.trace_output = $stderr + else + fail CommandLineOptionError, + "Unrecognized --#{trace_option} option '#{value}'" + end + end + private :select_trace_output + + # Read and handle the command line options. Returns the command line + # arguments that we didn't understand, which should (in theory) be just + # task names and env vars. + def handle_options(argv) # :nodoc: + set_default_options + + OptionParser.new do |opts| + opts.banner = "#{Rake.application.name} [-f rakefile] {options} targets..." + opts.separator "" + opts.separator "Options are ..." + + opts.on_tail("-h", "--help", "-H", "Display this help message.") do + puts opts + exit + end + + standard_rake_options.each { |args| opts.on(*args) } + opts.environment("RAKEOPT") + end.parse(argv) + end + + # Similar to the regular Ruby +require+ command, but will check + # for *.rake files in addition to *.rb files. + def rake_require(file_name, paths=$LOAD_PATH, loaded=$LOADED_FEATURES) # :nodoc: + fn = file_name + ".rake" + return false if loaded.include?(fn) + paths.each do |path| + full_path = File.join(path, fn) + if File.exist?(full_path) + Rake.load_rakefile(full_path) + loaded << fn + return true + end + end + fail LoadError, "Can't find #{file_name}" + end + + def find_rakefile_location # :nodoc: + here = Dir.pwd + until (fn = have_rakefile) + Dir.chdir("..") + return nil if Dir.pwd == here || options.nosearch + here = Dir.pwd + end + [fn, here] + ensure + Dir.chdir(Rake.original_dir) + end + + def print_rakefile_directory(location) # :nodoc: + $stderr.puts "(in #{Dir.pwd})" unless + options.silent or original_dir == location + end + + def raw_load_rakefile # :nodoc: + rakefile, location = find_rakefile_location + if (!options.ignore_system) && + (options.load_system || rakefile.nil?) && + system_dir && File.directory?(system_dir) + print_rakefile_directory(location) + glob("#{system_dir}/*.rake") do |name| + add_import name + end + else + fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if + rakefile.nil? + @rakefile = rakefile + Dir.chdir(location) + print_rakefile_directory(location) + Rake.load_rakefile(File.expand_path(@rakefile)) if + @rakefile && @rakefile != "" + options.rakelib.each do |rlib| + glob("#{rlib}/*.rake") do |name| + add_import name + end + end + end + load_imports + end + + def glob(path, &block) # :nodoc: + FileList.glob(path.tr("\\", "/")).each(&block) + end + private :glob + + # The directory path containing the system wide rakefiles. + def system_dir # :nodoc: + @system_dir ||= ENV["RAKE_SYSTEM"] || standard_system_dir + end + + # The standard directory containing system wide rake files. + if Win32.windows? + def standard_system_dir #:nodoc: + Win32.win32_system_dir + end + else + def standard_system_dir #:nodoc: + File.join(Dir.home, ".rake") + end + end + private :standard_system_dir + + # Collect the list of tasks on the command line. If no tasks are + # given, return a list containing only the default task. + # Environmental assignments are processed at this time as well. + # + # `args` is the list of arguments to peruse to get the list of tasks. + # It should be the command line that was given to rake, less any + # recognised command-line options, which OptionParser.parse will + # have taken care of already. + def collect_command_line_tasks(args) # :nodoc: + @top_level_tasks = [] + args.each do |arg| + if arg =~ /^(\w+)=(.*)$/m + ENV[$1] = $2 + else + @top_level_tasks << arg unless arg =~ /^-/ + end + end + @top_level_tasks.push(default_task_name) if @top_level_tasks.empty? + end + + # Default task name ("default"). + # (May be overridden by subclasses) + def default_task_name # :nodoc: + "default" + end + + # Add a file to the list of files to be imported. + def add_import(fn) # :nodoc: + @pending_imports << fn + end + + # Load the pending list of imported files. + def load_imports # :nodoc: + while fn = @pending_imports.shift + next if @imported.member?(fn) + fn_task = lookup(fn) and fn_task.invoke + ext = File.extname(fn) + loader = @loaders[ext] || @default_loader + loader.load(fn) + if fn_task = lookup(fn) and fn_task.needed? + fn_task.reenable + fn_task.invoke + loader.load(fn) + end + @imported << fn + end + end + + def rakefile_location(backtrace=caller) # :nodoc: + backtrace.map { |t| t[/([^:]+):/, 1] } + + re = /^#{@rakefile}$/ + re = /#{re.source}/i if windows? + + backtrace.find { |str| str =~ re } || "" + end + + def set_default_options # :nodoc: + options.always_multitask = false + options.backtrace = false + options.build_all = false + options.dryrun = false + options.ignore_deprecate = false + options.ignore_system = false + options.job_stats = false + options.load_system = false + options.nosearch = false + options.rakelib = %w[rakelib] + options.show_all_tasks = false + options.show_prereqs = false + options.show_task_pattern = nil + options.show_tasks = nil + options.silent = false + options.suppress_backtrace_pattern = nil + options.thread_pool_size = Rake.suggested_thread_count + options.trace = false + options.trace_output = $stderr + options.trace_rules = false + end + + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb new file mode 100644 index 0000000..c87f2f9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +module Rake + module Backtrace # :nodoc: all + SYS_KEYS = RbConfig::CONFIG.keys.grep(/(?:[a-z]prefix|libdir)\z/) + SYS_PATHS = RbConfig::CONFIG.values_at(*SYS_KEYS).uniq + + [ File.join(File.dirname(__FILE__), "..") ] + + SUPPRESSED_PATHS = SYS_PATHS. + map { |s| s.tr("\\", "/") }. + map { |f| File.expand_path(f) }. + reject { |s| s.nil? || s =~ /^ *$/ } + SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|") + SUPPRESSED_PATHS_RE << "|^" + SUPPRESSED_PATHS_RE << "|^org\\/jruby\\/\\w+\\.java" if + Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == "jruby" + + SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i + + def self.collapse(backtrace) + pattern = Rake.application.options.suppress_backtrace_pattern || + SUPPRESS_PATTERN + backtrace.reject { |elem| elem =~ pattern } + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb new file mode 100644 index 0000000..c49adf9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true +# The 'rake/clean' file defines two file lists (CLEAN and CLOBBER) and +# two rake tasks (:clean and :clobber). +# +# [:clean] Clean up the project by deleting scratch files and backup +# files. Add files to the CLEAN file list to have the :clean +# target handle them. +# +# [:clobber] Clobber all generated and non-source files in a project. +# The task depends on :clean, so all the clean files will +# be deleted as well as files in the CLOBBER file list. +# The intent of this task is to return a project to its +# pristine, just unpacked state. + +require_relative "../rake" + +# :stopdoc: + +module Rake + module Cleaner + extend FileUtils + + module_function + + def cleanup_files(file_names) + file_names.each do |file_name| + cleanup(file_name) + end + end + + def cleanup(file_name, **opts) + begin + opts = { verbose: Rake.application.options.trace }.merge(opts) + rm_r file_name, **opts + rescue StandardError => ex + puts "Failed to remove #{file_name}: #{ex}" unless file_already_gone?(file_name) + end + end + + def file_already_gone?(file_name) + return false if File.exist?(file_name) + + path = file_name + prev = nil + + while path = File.dirname(path) + return false if cant_be_deleted?(path) + break if [prev, "."].include?(path) + prev = path + end + true + end + private_class_method :file_already_gone? + + def cant_be_deleted?(path_name) + File.exist?(path_name) && + (!File.readable?(path_name) || !File.executable?(path_name)) + end + private_class_method :cant_be_deleted? + end +end + +CLEAN = ::Rake::FileList["**/*~", "**/*.bak", "**/core"] +CLEAN.clear_exclude.exclude { |fn| + fn.pathmap("%f").downcase == "core" && File.directory?(fn) +} + +desc "Remove any temporary products." +task :clean do + Rake::Cleaner.cleanup_files(CLEAN) +end + +CLOBBER = ::Rake::FileList.new + +desc "Remove any generated files." +task clobber: [:clean] do + Rake::Cleaner.cleanup_files(CLOBBER) +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb new file mode 100644 index 0000000..eddb77e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +module Rake + ## + # Mixin for creating easily cloned objects. + + module Cloneable # :nodoc: + # The hook that is invoked by 'clone' and 'dup' methods. + def initialize_copy(source) + super + source.instance_variables.each do |var| + src_value = source.instance_variable_get(var) + value = src_value.clone rescue src_value + instance_variable_set(var, value) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb new file mode 100644 index 0000000..75cc0d0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true +module Rake + + # Based on a script at: + # http://stackoverflow.com/questions/891537/ruby-detect-number-of-cpus-installed + class CpuCounter # :nodoc: all + def self.count + new.count_with_default + end + + def count_with_default(default=4) + count || default + rescue StandardError + default + end + + begin + require "etc" + rescue LoadError + else + if Etc.respond_to?(:nprocessors) + def count + return Etc.nprocessors + end + end + end + end +end + +unless Rake::CpuCounter.method_defined?(:count) + Rake::CpuCounter.class_eval <<-'end;', __FILE__, __LINE__+1 + require 'rbconfig' + + def count + if RUBY_PLATFORM == 'java' + count_via_java_runtime + else + case RbConfig::CONFIG['host_os'] + when /linux/ + count_via_cpuinfo + when /darwin|bsd/ + count_via_sysctl + when /mswin|mingw/ + count_via_win32 + else + # Try everything + count_via_win32 || + count_via_sysctl || + count_via_cpuinfo + end + end + end + + def count_via_java_runtime + Java::Java.lang.Runtime.getRuntime.availableProcessors + rescue StandardError + nil + end + + def count_via_win32 + # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0 + result = run_win32( + 'powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores ' \ + '| Select-Object -Property NumberOfCores"' + ) + if !result || $?.exitstatus != 0 + # fallback to deprecated wmic for older systems + result = run_win32("wmic cpu get NumberOfCores") + end + + # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n" + # wmic: "NumberOfCores \n\n4 \n\n\n\n" + result.scan(/\d+/).map(&:to_i).reduce(:+) if result + rescue StandardError + nil + end + + def count_via_cpuinfo + open('/proc/cpuinfo') { |f| f.readlines }.grep(/processor/).size + rescue StandardError + nil + end + + def count_via_sysctl + run 'sysctl', '-n', 'hw.ncpu' + end + + def run(command, *args) + cmd = resolve_command(command) + if cmd + IO.popen [cmd, *args] do |io| + io.read.to_i + end + else + nil + end + end + + def run_win32(command, *args) + IO.popen(command, &:read) + rescue Errno::ENOENT + nil + end + + def resolve_command(command) + look_for_command("/usr/sbin", command) || + look_for_command("/sbin", command) || + in_path_command(command) + end + + def look_for_command(dir, command) + path = File.join(dir, command) + File.exist?(path) ? path : nil + end + + def in_path_command(command) + IO.popen ['which', command] do |io| + io.eof? ? nil : command + end + end + end; +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb new file mode 100644 index 0000000..d3b4650 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +module Rake + + # Default Rakefile loader used by +import+. + class DefaultLoader + + ## + # Loads a rakefile into the current application from +fn+ + + def load(fn) + Rake.load_rakefile(File.expand_path(fn)) + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb new file mode 100644 index 0000000..3799068 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb @@ -0,0 +1,196 @@ +# frozen_string_literal: true +# Rake DSL functions. +require_relative "file_utils_ext" + +module Rake + + ## + # DSL is a module that provides #task, #desc, #namespace, etc. Use this + # when you'd like to use rake outside the top level scope. + # + # For a Rakefile you run from the command line this module is automatically + # included. + + module DSL + + #-- + # Include the FileUtils file manipulation functions in the top + # level module, but mark them private so that they don't + # unintentionally define methods on other objects. + #++ + + include FileUtilsExt + private(*FileUtils.instance_methods(false)) + private(*FileUtilsExt.instance_methods(false)) + + private + + # :call-seq: + # task(task_name) + # task(task_name: dependencies) + # task(task_name, arguments => dependencies) + # + # Declare a basic task. The +task_name+ is always the first argument. If + # the task name contains a ":" it is defined in that namespace. + # + # The +dependencies+ may be a single task name or an Array of task names. + # The +argument+ (a single name) or +arguments+ (an Array of names) define + # the arguments provided to the task. + # + # The task, argument and dependency names may be either symbols or + # strings. + # + # A task with a single dependency: + # + # task clobber: %w[clean] do + # rm_rf "html" + # end + # + # A task with an argument and a dependency: + # + # task :package, [:version] => :test do |t, args| + # # ... + # end + # + # To invoke this task from the command line: + # + # $ rake package[1.2.3] + # + def task(*args, &block) # :doc: + Rake::Task.define_task(*args, &block) + end + + # Declare a file task. + # + # Example: + # file "config.cfg" => ["config.template"] do + # open("config.cfg", "w") do |outfile| + # open("config.template") do |infile| + # while line = infile.gets + # outfile.puts line + # end + # end + # end + # end + # + def file(*args, &block) # :doc: + Rake::FileTask.define_task(*args, &block) + end + + # Declare a file creation task. + # (Mainly used for the directory command). + def file_create(*args, &block) + Rake::FileCreationTask.define_task(*args, &block) + end + + # Declare a set of files tasks to create the given directories on + # demand. + # + # Example: + # directory "testdata/doc" + # + def directory(*args, &block) # :doc: + args = args.flat_map { |arg| arg.is_a?(FileList) ? arg.to_a.flatten : arg } + result = file_create(*args, &block) + dir, _ = *Rake.application.resolve_args(args) + dir = Rake.from_pathname(dir) + Rake.each_dir_parent(dir) do |d| + file_create d do |t| + mkdir_p t.name unless File.exist?(t.name) + end + end + result + end + + # Declare a task that performs its prerequisites in + # parallel. Multitasks does *not* guarantee that its prerequisites + # will execute in any given order (which is obvious when you think + # about it) + # + # Example: + # multitask deploy: %w[deploy_gem deploy_rdoc] + # + def multitask(*args, &block) # :doc: + Rake::MultiTask.define_task(*args, &block) + end + + # Create a new rake namespace and use it for evaluating the given + # block. Returns a NameSpace object that can be used to lookup + # tasks defined in the namespace. + # + # Example: + # + # ns = namespace "nested" do + # # the "nested:run" task + # task :run + # end + # task_run = ns[:run] # find :run in the given namespace. + # + # Tasks can also be defined in a namespace by using a ":" in the task + # name: + # + # task "nested:test" do + # # ... + # end + # + def namespace(name=nil, &block) # :doc: + name = name.to_s if name.kind_of?(Symbol) + name = name.to_str if name.respond_to?(:to_str) + unless name.kind_of?(String) || name.nil? + raise ArgumentError, "Expected a String or Symbol for a namespace name" + end + Rake.application.in_namespace(name, &block) + end + + # Declare a rule for auto-tasks. + # + # Example: + # rule '.o' => '.c' do |t| + # sh 'cc', '-c', '-o', t.name, t.source + # end + # + def rule(*args, &block) # :doc: + Rake::Task.create_rule(*args, &block) + end + + # Describes the next rake task. Duplicate descriptions are discarded. + # Descriptions are shown with rake -T (up to the first + # sentence) and rake -D (the entire description). + # + # Example: + # desc "Run the Unit Tests" + # task test: [:build] do + # # ... run tests + # end + # + def desc(description) # :doc: + Rake.application.last_description = description + end + + # Import the partial Rakefiles +fn+. Imported files are loaded + # _after_ the current file is completely loaded. This allows the + # import statement to appear anywhere in the importing file, and yet + # allowing the imported files to depend on objects defined in the + # importing file. + # + # A common use of the import statement is to include files + # containing dependency declarations. + # + # See also the --rakelibdir command line option. + # + # Example: + # import ".depend", "my_rules" + # + def import(*fns) # :doc: + fns.each do |fn| + Rake.application.add_import(fn) + end + end + end + extend FileUtilsExt +end + +# Extend the main object with the DSL commands. This allows top-level +# calls to task, etc. to work from a Rakefile without polluting the +# object inheritance tree. +self.extend Rake::DSL diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb new file mode 100644 index 0000000..80cc6bf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +module Rake + + # EarlyTime is a fake timestamp that occurs _before_ any other time value. + class EarlyTime + include Comparable + include Singleton + + ## + # The EarlyTime always comes before +other+! + + def <=>(other) + -1 + end + + def to_s # :nodoc: + "" + end + end + + EARLY = EarlyTime.instance +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb new file mode 100644 index 0000000..226f212 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true +class Module + # Check for an existing method in the current class before extending. If + # the method already exists, then a warning is printed and the extension is + # not added. Otherwise the block is yielded and any definitions in the + # block will take effect. + # + # Usage: + # + # class String + # rake_extension("xyz") do + # def xyz + # ... + # end + # end + # end + # + def rake_extension(method) # :nodoc: + if method_defined?(method) + $stderr.puts "WARNING: Possible conflict with Rake extension: " + + "#{self}##{method} already exists" + else + yield + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb new file mode 100644 index 0000000..c82f532 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true +require_relative "core" + +class String + + rake_extension("ext") do + # Replace the file extension with +newext+. If there is no extension on + # the string, append the new extension to the end. If the new extension + # is not given, or is the empty string, remove any existing extension. + # + # +ext+ is a user added method for the String class. + # + # This String extension comes from Rake + def ext(newext="") + return self.dup if [".", ".."].include? self + if newext != "" + newext = "." + newext unless newext =~ /^\./ + end + self.chomp(File.extname(self)) << newext + end + end + + rake_extension("pathmap") do + # Explode a path into individual components. Used by +pathmap+. + # + # This String extension comes from Rake + def pathmap_explode + head, tail = File.split(self) + return [self] if head == self + return [tail] if head == "." || tail == "/" + return [head, tail] if head == "/" + return head.pathmap_explode + [tail] + end + protected :pathmap_explode + + # Extract a partial path from the path. Include +n+ directories from the + # front end (left hand side) if +n+ is positive. Include |+n+| + # directories from the back end (right hand side) if +n+ is negative. + # + # This String extension comes from Rake + def pathmap_partial(n) + dirs = File.dirname(self).pathmap_explode + partial_dirs = + if n > 0 + dirs[0...n] + elsif n < 0 + dirs.reverse[0...-n].reverse + else + "." + end + File.join(partial_dirs) + end + protected :pathmap_partial + + # Perform the pathmap replacement operations on the given path. The + # patterns take the form 'pat1,rep1;pat2,rep2...'. + # + # This String extension comes from Rake + def pathmap_replace(patterns, &block) + result = self + patterns.split(";").each do |pair| + pattern, replacement = pair.split(",") + pattern = Regexp.new(pattern) + if replacement == "*" && block_given? + result = result.sub(pattern, &block) + elsif replacement + result = result.sub(pattern, replacement) + else + result = result.sub(pattern, "") + end + end + result + end + protected :pathmap_replace + + # Map the path according to the given specification. The specification + # controls the details of the mapping. The following special patterns are + # recognized: + # + # %p :: The complete path. + # %f :: The base file name of the path, with its file extension, + # but without any directories. + # %n :: The file name of the path without its file extension. + # %d :: The directory list of the path. + # %x :: The file extension of the path. An empty string if there + # is no extension. + # %X :: Everything *but* the file extension. + # %s :: The alternate file separator if defined, otherwise use # + # the standard file separator. + # %% :: A percent sign. + # + # The %d specifier can also have a numeric prefix (e.g. '%2d'). + # If the number is positive, only return (up to) +n+ directories in the + # path, starting from the left hand side. If +n+ is negative, return (up + # to) +n+ directories from the right hand side of the path. + # + # Examples: + # + # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b' + # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d' + # + # Also the %d, %p, %f, %n, + # %x, and %X operators can take a pattern/replacement + # argument to perform simple string substitutions on a particular part of + # the path. The pattern and replacement are separated by a comma and are + # enclosed by curly braces. The replacement spec comes after the % + # character but before the operator letter. (e.g. "%{old,new}d"). + # Multiple replacement specs should be separated by semi-colons (e.g. + # "%{old,new;src,bin}d"). + # + # Regular expressions may be used for the pattern, and back refs may be + # used in the replacement text. Curly braces, commas and semi-colons are + # excluded from both the pattern and replacement text (let's keep parsing + # reasonable). + # + # For example: + # + # "src/org/onestepback/proj/A.java".pathmap("%{^src,class}X.class") + # + # returns: + # + # "class/org/onestepback/proj/A.class" + # + # If the replacement text is '*', then a block may be provided to perform + # some arbitrary calculation for the replacement. + # + # For example: + # + # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext| + # ext.downcase + # } + # + # Returns: + # + # "/path/to/file.txt" + # + # This String extension comes from Rake + def pathmap(spec=nil, &block) + return self if spec.nil? + result = "".dup + spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| + case frag + when "%f" + result << File.basename(self) + when "%n" + result << File.basename(self).ext + when "%d" + result << File.dirname(self) + when "%x" + result << File.extname(self) + when "%X" + result << self.ext + when "%p" + result << self + when "%s" + result << (File::ALT_SEPARATOR || File::SEPARATOR) + when "%-" + # do nothing + when "%%" + result << "%" + when /%(-?\d+)d/ + result << pathmap_partial($1.to_i) + when /^%\{([^}]*)\}(\d*[dpfnxX])/ + patterns, operator = $1, $2 + result << pathmap("%" + operator).pathmap_replace(patterns, &block) + when /^%/ + fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" + else + result << frag + end + end + result + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb new file mode 100644 index 0000000..3df254c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +require_relative "file_task" +require_relative "early_time" + +module Rake + + # A FileCreationTask is a file task that when used as a dependency will be + # needed if and only if the file has not been created. Once created, it is + # not re-triggered if any of its dependencies are newer, nor does trigger + # any rebuilds of tasks that depend on it whenever it is updated. + # + class FileCreationTask < FileTask + # Is this file task needed? Yes if it doesn't exist. + def needed? + !File.exist?(name) + end + + # Time stamp for file creation task. This time stamp is earlier + # than any other time stamp. + def timestamp + Rake::EARLY + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb new file mode 100644 index 0000000..76078d2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb @@ -0,0 +1,435 @@ +# frozen_string_literal: true +require_relative "cloneable" +require_relative "file_utils_ext" +require_relative "ext/string" + +module Rake + + ## + # A FileList is essentially an array with a few helper methods defined to + # make file manipulation a bit easier. + # + # FileLists are lazy. When given a list of glob patterns for possible files + # to be included in the file list, instead of searching the file structures + # to find the files, a FileList holds the pattern for latter use. + # + # This allows us to define a number of FileList to match any number of + # files, but only search out the actual files when then FileList itself is + # actually used. The key is that the first time an element of the + # FileList/Array is requested, the pending patterns are resolved into a real + # list of file names. + # + class FileList + + include Cloneable + + # == Method Delegation + # + # The lazy evaluation magic of FileLists happens by implementing all the + # array specific methods to call +resolve+ before delegating the heavy + # lifting to an embedded array object (@items). + # + # In addition, there are two kinds of delegation calls. The regular kind + # delegates to the @items array and returns the result directly. Well, + # almost directly. It checks if the returned value is the @items object + # itself, and if so will return the FileList object instead. + # + # The second kind of delegation call is used in methods that normally + # return a new Array object. We want to capture the return value of these + # methods and wrap them in a new FileList object. We enumerate these + # methods in the +SPECIAL_RETURN+ list below. + + # List of array methods (that are not in +Object+) that need to be + # delegated. + ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map(&:to_s) + + # List of additional methods that must be delegated. + MUST_DEFINE = %w[inspect <=>] + + # List of methods that should not be delegated here (we define special + # versions of them explicitly below). + MUST_NOT_DEFINE = %w[to_a to_ary partition * <<] + + # List of delegated methods that return new array values which need + # wrapping. + SPECIAL_RETURN = %w[ + map collect sort sort_by select find_all reject grep + compact flatten uniq values_at + + - & | + ] + + DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).map(&:to_s).sort.uniq + + # Now do the delegation. + DELEGATING_METHODS.each do |sym| + if SPECIAL_RETURN.include?(sym) + ln = __LINE__ + 1 + class_eval %{ + def #{sym}(*args, &block) + resolve + result = @items.send(:#{sym}, *args, &block) + self.class.new.import(result) + end + }, __FILE__, ln + else + ln = __LINE__ + 1 + class_eval %{ + def #{sym}(*args, &block) + resolve + result = @items.send(:#{sym}, *args, &block) + result.object_id == @items.object_id ? self : result + end + }, __FILE__, ln + end + end + + GLOB_PATTERN = %r{[*?\[\{]} + + # Create a file list from the globbable patterns given. If you wish to + # perform multiple includes or excludes at object build time, use the + # "yield self" pattern. + # + # Example: + # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb') + # + # pkg_files = FileList.new('lib/**/*') do |fl| + # fl.exclude(/\bCVS\b/) + # end + # + def initialize(*patterns) + @pending_add = [] + @pending = false + @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup + @exclude_procs = DEFAULT_IGNORE_PROCS.dup + @items = [] + patterns.each { |pattern| include(pattern) } + yield self if block_given? + end + + # Add file names defined by glob patterns to the file list. If an array + # is given, add each element of the array. + # + # Example: + # file_list.include("*.java", "*.cfg") + # file_list.include %w( math.c lib.h *.o ) + # + def include(*filenames) + # TODO: check for pending + filenames.each do |fn| + if fn.respond_to? :to_ary + include(*fn.to_ary) + else + @pending_add << Rake.from_pathname(fn) + end + end + @pending = true + self + end + alias :add :include + + # Register a list of file name patterns that should be excluded from the + # list. Patterns may be regular expressions, glob patterns or regular + # strings. In addition, a block given to exclude will remove entries that + # return true when given to the block. + # + # Note that glob patterns are expanded against the file system. If a file + # is explicitly added to a file list, but does not exist in the file + # system, then an glob pattern in the exclude list will not exclude the + # file. + # + # Examples: + # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c'] + # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c'] + # + # If "a.c" is a file, then ... + # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c'] + # + # If "a.c" is not a file, then ... + # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c'] + # + def exclude(*patterns, &block) + patterns.each do |pat| + if pat.respond_to? :to_ary + exclude(*pat.to_ary) + else + @exclude_patterns << Rake.from_pathname(pat) + end + end + @exclude_procs << block if block_given? + resolve_exclude unless @pending + self + end + + # Clear all the exclude patterns so that we exclude nothing. + def clear_exclude + @exclude_patterns = [] + @exclude_procs = [] + self + end + + # A FileList is equal through array equality. + def ==(array) + to_ary == array + end + + # Return the internal array object. + def to_a + resolve + @items + end + + # Return the internal array object. + def to_ary + to_a + end + + # Lie about our class. + def is_a?(klass) + klass == Array || super(klass) + end + alias kind_of? is_a? + + # Redefine * to return either a string or a new file list. + def *(other) + result = @items * other + case result + when Array + self.class.new.import(result) + else + result + end + end + + def <<(obj) + resolve + @items << Rake.from_pathname(obj) + self + end + + # Resolve all the pending adds now. + def resolve + if @pending + @pending = false + @pending_add.each do |fn| resolve_add(fn) end + @pending_add = [] + resolve_exclude + end + self + end + + def resolve_add(fn) # :nodoc: + case fn + when GLOB_PATTERN + add_matching(fn) + else + self << fn + end + end + private :resolve_add + + def resolve_exclude # :nodoc: + reject! { |fn| excluded_from_list?(fn) } + self + end + private :resolve_exclude + + # Return a new FileList with the results of running +sub+ against each + # element of the original list. + # + # Example: + # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o'] + # + def sub(pat, rep) + inject(self.class.new) { |res, fn| res << fn.sub(pat, rep) } + end + + # Return a new FileList with the results of running +gsub+ against each + # element of the original list. + # + # Example: + # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\") + # => ['lib\\test\\file', 'x\\y'] + # + def gsub(pat, rep) + inject(self.class.new) { |res, fn| res << fn.gsub(pat, rep) } + end + + # Same as +sub+ except that the original file list is modified. + def sub!(pat, rep) + each_with_index { |fn, i| self[i] = fn.sub(pat, rep) } + self + end + + # Same as +gsub+ except that the original file list is modified. + def gsub!(pat, rep) + each_with_index { |fn, i| self[i] = fn.gsub(pat, rep) } + self + end + + # Apply the pathmap spec to each of the included file names, returning a + # new file list with the modified paths. (See String#pathmap for + # details.) + def pathmap(spec=nil, &block) + collect { |fn| fn.pathmap(spec, &block) } + end + + # Return a new FileList with String#ext method applied to + # each member of the array. + # + # This method is a shortcut for: + # + # array.collect { |item| item.ext(newext) } + # + # +ext+ is a user added method for the Array class. + def ext(newext="") + collect { |fn| fn.ext(newext) } + end + + # Grep each of the files in the filelist using the given pattern. If a + # block is given, call the block on each matching line, passing the file + # name, line number, and the matching line of text. If no block is given, + # a standard emacs style file:linenumber:line message will be printed to + # standard out. Returns the number of matched items. + def egrep(pattern, *options) + matched = 0 + each do |fn| + begin + File.open(fn, "r", *options) do |inf| + count = 0 + inf.each do |line| + count += 1 + if pattern.match(line) + matched += 1 + if block_given? + yield fn, count, line + else + puts "#{fn}:#{count}:#{line}" + end + end + end + end + rescue StandardError => ex + $stderr.puts "Error while processing '#{fn}': #{ex}" + end + end + matched + end + + # Return a new file list that only contains file names from the current + # file list that exist on the file system. + def existing + select { |fn| File.exist?(fn) }.uniq + end + + # Modify the current file list so that it contains only file name that + # exist on the file system. + def existing! + resolve + @items = @items.select { |fn| File.exist?(fn) }.uniq + self + end + + # FileList version of partition. Needed because the nested arrays should + # be FileLists in this version. + def partition(&block) # :nodoc: + resolve + result = @items.partition(&block) + [ + self.class.new.import(result[0]), + self.class.new.import(result[1]), + ] + end + + # Convert a FileList to a string by joining all elements with a space. + def to_s + resolve + self.join(" ") + end + + # Add matching glob patterns. + def add_matching(pattern) + self.class.glob(pattern).each do |fn| + self << fn unless excluded_from_list?(fn) + end + end + private :add_matching + + # Should the given file name be excluded from the list? + # + # NOTE: This method was formerly named "exclude?", but Rails + # introduced an exclude? method as an array method and setup a + # conflict with file list. We renamed the method to avoid + # confusion. If you were using "FileList#exclude?" in your user + # code, you will need to update. + def excluded_from_list?(fn) + return true if @exclude_patterns.any? do |pat| + case pat + when Regexp + fn =~ pat + when GLOB_PATTERN + flags = File::FNM_PATHNAME + # Ruby <= 1.9.3 does not support File::FNM_EXTGLOB + flags |= File::FNM_EXTGLOB if defined? File::FNM_EXTGLOB + File.fnmatch?(pat, fn, flags) + else + fn == pat + end + end + @exclude_procs.any? { |p| p.call(fn) } + end + + DEFAULT_IGNORE_PATTERNS = [ + /(^|[\/\\])CVS([\/\\]|$)/, + /(^|[\/\\])\.svn([\/\\]|$)/, + /\.bak$/, + /~$/ + ] + DEFAULT_IGNORE_PROCS = [ + proc { |fn| fn =~ /(^|[\/\\])core$/ && !File.directory?(fn) } + ] + + def import(array) # :nodoc: + @items = array + self + end + + class << self + # Create a new file list including the files listed. Similar to: + # + # FileList.new(*args) + def [](*args) + new(*args) + end + + # Get a sorted list of files matching the pattern. This method + # should be preferred to Dir[pattern] and Dir.glob(pattern) because + # the files returned are guaranteed to be sorted. + def glob(pattern, *args) + Dir.glob(pattern, *args).sort + end + end + end +end + +module Rake + class << self + + # Yield each file or directory component. + def each_dir_parent(dir) # :nodoc: + old_length = nil + while dir != "." && dir.length != old_length + yield(dir) + old_length = dir.length + dir = File.dirname(dir) + end + end + + # Convert Pathname and Pathname-like objects to strings; + # leave everything else alone + def from_pathname(path) # :nodoc: + path = path.to_path if path.respond_to?(:to_path) + path = path.to_str if path.respond_to?(:to_str) + path + end + end +end # module Rake diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb new file mode 100644 index 0000000..8c398bc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +require_relative "task" +require_relative "early_time" + +module Rake + + # A FileTask is a task that includes time based dependencies. If any of a + # FileTask's prerequisites have a timestamp that is later than the file + # represented by this task, then the file must be rebuilt (using the + # supplied actions). + # + class FileTask < Task + + # Is this file task needed? Yes if it doesn't exist, or if its time stamp + # is out of date. + def needed? + begin + out_of_date?(File.mtime(name)) || @application.options.build_all + rescue Errno::ENOENT + true + end + end + + # Time stamp for file task. + def timestamp + begin + File.mtime(name) + rescue Errno::ENOENT + Rake::LATE + end + end + + private + + # Are there any prerequisites with a later time than the given time stamp? + def out_of_date?(stamp) + all_prerequisite_tasks.any? { |prereq| + prereq_task = application[prereq, @scope] + if prereq_task.instance_of?(Rake::FileTask) + prereq_task.timestamp > stamp || @application.options.build_all + else + prereq_task.timestamp > stamp + end + } + end + + # ---------------------------------------------------------------- + # Task class methods. + # + class << self + # Apply the scope to the task name according to the rules for this kind + # of task. File based tasks ignore the scope when creating the name. + def scope_name(scope, task_name) + Rake.from_pathname(task_name) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb new file mode 100644 index 0000000..1510d95 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true +require "rbconfig" +require "fileutils" + +#-- +# This a FileUtils extension that defines several additional commands to be +# added to the FileUtils utility functions. +module FileUtils + # Path to the currently running Ruby program + RUBY = ENV["RUBY"] || File.join( + RbConfig::CONFIG["bindir"], + RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]). + sub(/.*\s.*/m, '"\&"') + + # Run the system command +cmd+. If multiple arguments are given the command + # is run directly (without the shell, same semantics as Kernel::exec and + # Kernel::system). + # + # It is recommended you use the multiple argument form over interpolating + # user input for both usability and security reasons. With the multiple + # argument form you can easily process files with spaces or other shell + # reserved characters in them. With the multiple argument form your rake + # tasks are not vulnerable to users providing an argument like + # ; rm # -rf /. + # + # If a block is given, upon command completion the block is called with an + # OK flag (true on a zero exit status) and a Process::Status object. + # Without a block a RuntimeError is raised when the command exits non-zero. + # + # Examples: + # + # sh 'ls -ltr' + # + # sh 'ls', 'file with spaces' + # + # # check exit status after command runs + # sh %{grep pattern file} do |ok, res| + # if !ok + # puts "pattern not found (status = #{res.exitstatus})" + # end + # end + # + def sh(*cmd, &block) + options = (Hash === cmd.last) ? cmd.pop : {} + shell_runner = block_given? ? block : create_shell_runner(cmd) + + set_verbose_option(options) + verbose = options.delete :verbose + noop = options.delete(:noop) || Rake::FileUtilsExt.nowrite_flag + + Rake.rake_output_message sh_show_command cmd if verbose + + unless noop + res = (Hash === cmd.last) ? system(*cmd) : system(*cmd, options) + status = $? + status = Rake::PseudoStatus.new(1) if !res && status.nil? + shell_runner.call(res, status) + end + end + + def create_shell_runner(cmd) # :nodoc: + show_command = sh_show_command cmd + lambda do |ok, status| + ok or + fail "Command failed with status (#{status.exitstatus}): " + + "[#{show_command}]" + end + end + private :create_shell_runner + + def sh_show_command(cmd) # :nodoc: + cmd = cmd.dup + + if Hash === cmd.first + env = cmd.first + env = env.map { |name, value| "#{name}=#{value}" }.join " " + cmd[0] = env + end + + cmd.join " " + end + private :sh_show_command + + def set_verbose_option(options) # :nodoc: + unless options.key? :verbose + options[:verbose] = + (Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT) || + Rake::FileUtilsExt.verbose_flag + end + end + private :set_verbose_option + + # Run a Ruby interpreter with the given arguments. + # + # Example: + # ruby %{-pe '$_.upcase!' 1 + sh(RUBY, *args, **options, &block) + else + sh("#{RUBY} #{args.first}", **options, &block) + end + end + + LN_SUPPORTED = [true] + + # Attempt to do a normal file link, but fall back to a copy if the link + # fails. + def safe_ln(*args, **options) + if LN_SUPPORTED[0] + begin + return options.empty? ? ln(*args) : ln(*args, **options) + rescue StandardError, NotImplementedError + LN_SUPPORTED[0] = false + end + end + options.empty? ? cp(*args) : cp(*args, **options) + end + + # Split a file path into individual directory names. + # + # Example: + # split_all("a/b/c") => ['a', 'b', 'c'] + # + def split_all(path) + head, tail = File.split(path) + return [tail] if head == "." || tail == "/" + return [head, tail] if head == "/" + return split_all(head) + [tail] + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb new file mode 100644 index 0000000..687d805 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true +require_relative "file_utils" + +module Rake + # + # FileUtilsExt provides a custom version of the FileUtils methods + # that respond to the verbose and nowrite + # commands. + # + module FileUtilsExt + include FileUtils + + class << self + attr_accessor :verbose_flag, :nowrite_flag + end + + DEFAULT = Object.new + + FileUtilsExt.verbose_flag = DEFAULT + FileUtilsExt.nowrite_flag = false + + FileUtils.commands.each do |name| + opts = FileUtils.options_of name + default_options = [] + if opts.include?("verbose") + default_options << "verbose: FileUtilsExt.verbose_flag" + end + if opts.include?("noop") + default_options << "noop: FileUtilsExt.nowrite_flag" + end + + next if default_options.empty? + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args, **options, &block) + super(*args, + #{default_options.join(', ')}, + **options, &block) + end + EOS + end + + # Get/set the verbose flag controlling output from the FileUtils + # utilities. If verbose is true, then the utility method is + # echoed to standard output. + # + # Examples: + # verbose # return the current value of the + # # verbose flag + # verbose(v) # set the verbose flag to _v_. + # verbose(v) { code } # Execute code with the verbose flag set + # # temporarily to _v_. Return to the + # # original value when code is done. + def verbose(value=nil) + oldvalue = FileUtilsExt.verbose_flag + FileUtilsExt.verbose_flag = value unless value.nil? + if block_given? + begin + yield + ensure + FileUtilsExt.verbose_flag = oldvalue + end + end + FileUtilsExt.verbose_flag + end + + # Get/set the nowrite flag controlling output from the FileUtils + # utilities. If verbose is true, then the utility method is + # echoed to standard output. + # + # Examples: + # nowrite # return the current value of the + # # nowrite flag + # nowrite(v) # set the nowrite flag to _v_. + # nowrite(v) { code } # Execute code with the nowrite flag set + # # temporarily to _v_. Return to the + # # original value when code is done. + def nowrite(value=nil) + oldvalue = FileUtilsExt.nowrite_flag + FileUtilsExt.nowrite_flag = value unless value.nil? + if block_given? + begin + yield + ensure + FileUtilsExt.nowrite_flag = oldvalue + end + end + oldvalue + end + + # Use this function to prevent potentially destructive ruby code + # from running when the :nowrite flag is set. + # + # Example: + # + # when_writing("Building Project") do + # project.build + # end + # + # The following code will build the project under normal + # conditions. If the nowrite(true) flag is set, then the example + # will print: + # + # DRYRUN: Building Project + # + # instead of actually building the project. + # + def when_writing(msg=nil) + if FileUtilsExt.nowrite_flag + $stderr.puts "DRYRUN: #{msg}" if msg + else + yield + end + end + + # Send the message to the default rake output (which is $stderr). + def rake_output_message(message) + $stderr.puts(message) + end + + # Check that the options do not contain options not listed in + # +optdecl+. An ArgumentError exception is thrown if non-declared + # options are found. + def rake_check_options(options, *optdecl) + h = options.dup + optdecl.each do |name| + h.delete name + end + raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless + h.empty? + end + + extend self + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb new file mode 100644 index 0000000..44a9954 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true +module Rake + + # InvocationChain tracks the chain of task invocations to detect + # circular dependencies. + class InvocationChain < LinkedList + + # Is the invocation already in the chain? + def member?(invocation) + head == invocation || tail.member?(invocation) + end + + # Append an invocation to the chain of invocations. It is an error + # if the invocation already listed. + def append(invocation) + if member?(invocation) + fail RuntimeError, "Circular dependency detected: #{to_s} => #{invocation}" + end + conj(invocation) + end + + # Convert to string, ie: TOP => invocation => invocation + def to_s + "#{prefix}#{head}" + end + + # Class level append. + def self.append(invocation, chain) + chain.append(invocation) + end + + private + + def prefix + "#{tail} => " + end + + # Null object for an empty chain. + class EmptyInvocationChain < LinkedList::EmptyLinkedList + @parent = InvocationChain + + def member?(obj) + false + end + + def append(invocation) + conj(invocation) + end + + def to_s + "TOP" + end + end + + EMPTY = EmptyInvocationChain.new + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb new file mode 100644 index 0000000..b0d307a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +module Rake + module InvocationExceptionMixin + # Return the invocation chain (list of Rake tasks) that were in + # effect when this exception was detected by rake. May be null if + # no tasks were active. + def chain + @rake_invocation_chain ||= nil + end + + # Set the invocation chain in effect when this exception was + # detected. + def chain=(value) + @rake_invocation_chain = value + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb new file mode 100644 index 0000000..8fe0249 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +module Rake + # LateTime is a fake timestamp that occurs _after_ any other time value. + class LateTime + include Comparable + include Singleton + + def <=>(other) + 1 + end + + def to_s + "" + end + end + + LATE = LateTime.instance +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb new file mode 100644 index 0000000..11fa46f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true +module Rake + + # Polylithic linked list structure used to implement several data + # structures in Rake. + class LinkedList + include Enumerable + attr_reader :head, :tail + + # Polymorphically add a new element to the head of a list. The + # type of head node will be the same list type as the tail. + def conj(item) + self.class.cons(item, self) + end + + # Is the list empty? + # .make guards against a list being empty making any instantiated LinkedList + # object not empty by default + # You should consider overriding this method if you implement your own .make method + def empty? + false + end + + # Lists are structurally equivalent. + def ==(other) + current = self + while !current.empty? && !other.empty? + return false if current.head != other.head + current = current.tail + other = other.tail + end + current.empty? && other.empty? + end + + # Convert to string: LL(item, item...) + def to_s + items = map(&:to_s).join(", ") + "LL(#{items})" + end + + # Same as +to_s+, but with inspected items. + def inspect + items = map(&:inspect).join(", ") + "LL(#{items})" + end + + # For each item in the list. + def each + current = self + while !current.empty? + yield(current.head) + current = current.tail + end + self + end + + # Make a list out of the given arguments. This method is + # polymorphic + def self.make(*args) + # return an EmptyLinkedList if there are no arguments + return empty if !args || args.empty? + + # build a LinkedList by starting at the tail and iterating + # through each argument + # inject takes an EmptyLinkedList to start + args.reverse.inject(empty) do |list, item| + list = cons(item, list) + list # return the newly created list for each item in the block + end + end + + # Cons a new head onto the tail list. + def self.cons(head, tail) + new(head, tail) + end + + # The standard empty list class for the given LinkedList class. + def self.empty + self::EMPTY + end + + protected + + def initialize(head, tail=EMPTY) + @head = head + @tail = tail + end + + # Represent an empty list, using the Null Object Pattern. + # + # When inheriting from the LinkedList class, you should implement + # a type specific Empty class as well. Make sure you set the class + # instance variable @parent to the associated list class (this + # allows conj, cons and make to work polymorphically). + class EmptyLinkedList < LinkedList + @parent = LinkedList + + def initialize + end + + def empty? + true + end + + def self.cons(head, tail) + @parent.cons(head, tail) + end + end + + EMPTY = EmptyLinkedList.new + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb new file mode 100644 index 0000000..46f4bea --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +module Rake + + # Makefile loader to be used with the import file loader. Use this to + # import dependencies from make dependency tools: + # + # require 'rake/loaders/makefile' + # + # file ".depends.mf" => [SRC_LIST] do |t| + # sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" + # end + # + # import ".depends.mf" + # + # See {Importing Dependencies}[link:doc/rakefile_rdoc.html#label-Importing+Dependencies] + # for further details. + + class MakefileLoader + include Rake::DSL + + SPACE_MARK = "\0" # :nodoc: + + # Load the makefile dependencies in +fn+. + def load(fn) # :nodoc: + lines = File.read fn + lines.gsub!(/\\ /, SPACE_MARK) + lines.gsub!(/#[^\n]*\n/m, "") + lines.gsub!(/\\\n/, " ") + lines.each_line do |line| + process_line(line) + end + end + + private + + # Process one logical line of makefile data. + def process_line(line) # :nodoc: + file_tasks, args = line.split(":", 2) + return if args.nil? + dependents = args.split.map { |d| respace(d) } + file_tasks.scan(/\S+/) do |file_task| + file_task = respace(file_task) + file file_task => dependents + end + end + + def respace(str) # :nodoc: + str.tr SPACE_MARK, " " + end + end + + # Install the handler + Rake.application.add_loader("mf", MakefileLoader.new) +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb new file mode 100644 index 0000000..3ae363c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +module Rake + + # Same as a regular task, but the immediate prerequisites are done in + # parallel using Ruby threads. + # + class MultiTask < Task + private + + def invoke_prerequisites(task_args, invocation_chain) # :nodoc: + invoke_prerequisites_concurrently(task_args, invocation_chain) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb new file mode 100644 index 0000000..32f8139 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true +## +# The NameSpace class will lookup task names in the scope defined by a +# +namespace+ command. + +class Rake::NameSpace + + ## + # Create a namespace lookup object using the given task manager + # and the list of scopes. + + def initialize(task_manager, scope_list) + @task_manager = task_manager + @scope = scope_list.dup + end + + ## + # Lookup a task named +name+ in the namespace. + + def [](name) + @task_manager.lookup(name, @scope) + end + + ## + # The scope of the namespace (a LinkedList) + + def scope + @scope.dup + end + + ## + # Return the list of tasks defined in this and nested namespaces. + + def tasks + @task_manager.tasks_in_scope(@scope) + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb new file mode 100644 index 0000000..80a4acf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb @@ -0,0 +1,222 @@ +# frozen_string_literal: true +# Define a package task library to aid in the definition of +# redistributable package files. + +require_relative "../rake" +require_relative "tasklib" + +module Rake + + # Create a packaging task that will package the project into + # distributable files (e.g zip archive or tar files). + # + # The PackageTask will create the following targets: + # + # +:package+ :: + # Create all the requested package files. + # + # +:clobber_package+ :: + # Delete all the package files. This target is automatically + # added to the main clobber target. + # + # +:repackage+ :: + # Rebuild the package files from scratch, even if they are not out + # of date. + # + # "package_dir/name-version.tgz" :: + # Create a gzipped tar package (if need_tar is true). + # + # "package_dir/name-version.tar.gz" :: + # Create a gzipped tar package (if need_tar_gz is true). + # + # "package_dir/name-version.tar.bz2" :: + # Create a bzip2'd tar package (if need_tar_bz2 is true). + # + # "package_dir/name-version.zip" :: + # Create a zip package archive (if need_zip is true). + # + # Example: + # + # Rake::PackageTask.new("rake", "1.2.3") do |p| + # p.need_tar = true + # p.package_files.include("lib/**/*.rb") + # end + # + class PackageTask < TaskLib + # Name of the package (from the GEM Spec). + attr_accessor :name + + # Version of the package (e.g. '1.3.2'). + attr_accessor :version + + # Directory used to store the package files (default is 'pkg'). + attr_accessor :package_dir + + # True if a gzipped tar file (tgz) should be produced (default is + # false). + attr_accessor :need_tar + + # True if a gzipped tar file (tar.gz) should be produced (default + # is false). + attr_accessor :need_tar_gz + + # True if a bzip2'd tar file (tar.bz2) should be produced (default + # is false). + attr_accessor :need_tar_bz2 + + # True if a xz'd tar file (tar.xz) should be produced (default is false) + attr_accessor :need_tar_xz + + # True if a zip file should be produced (default is false) + attr_accessor :need_zip + + # List of files to be included in the package. + attr_accessor :package_files + + # Tar command for gzipped or bzip2ed archives. The default is 'tar'. + attr_accessor :tar_command + + # Zip command for zipped archives. The default is 'zip'. + attr_accessor :zip_command + + # True if parent directory should be omitted (default is false) + attr_accessor :without_parent_dir + + # Create a Package Task with the given name and version. Use +:noversion+ + # as the version to build a package without a version or to provide a + # fully-versioned package name. + + def initialize(name=nil, version=nil) + init(name, version) + yield self if block_given? + define unless name.nil? + end + + # Initialization that bypasses the "yield self" and "define" step. + def init(name, version) + @name = name + @version = version + @package_files = Rake::FileList.new + @package_dir = "pkg" + @need_tar = false + @need_tar_gz = false + @need_tar_bz2 = false + @need_tar_xz = false + @need_zip = false + @tar_command = "tar" + @zip_command = "zip" + @without_parent_dir = false + end + + # Create the tasks defined by this task library. + def define + fail "Version required (or :noversion)" if @version.nil? + @version = nil if :noversion == @version + + desc "Build all the packages" + task :package + + desc "Force a rebuild of the package files" + task repackage: [:clobber_package, :package] + + desc "Remove package products" + task :clobber_package do + rm_r package_dir rescue nil + end + + task clobber: [:clobber_package] + + [ + [need_tar, tgz_file, "z"], + [need_tar_gz, tar_gz_file, "z"], + [need_tar_bz2, tar_bz2_file, "j"], + [need_tar_xz, tar_xz_file, "J"] + ].each do |need, file, flag| + if need + task package: ["#{package_dir}/#{file}"] + file "#{package_dir}/#{file}" => + [package_dir_path] + package_files do + chdir(working_dir) { sh @tar_command, "#{flag}cvf", file, target_dir } + mv "#{package_dir_path}/#{target_dir}", package_dir if without_parent_dir + end + end + end + + if need_zip + task package: ["#{package_dir}/#{zip_file}"] + file "#{package_dir}/#{zip_file}" => + [package_dir_path] + package_files do + chdir(working_dir) { sh @zip_command, "-r", zip_file, target_dir } + mv "#{package_dir_path}/#{zip_file}", package_dir if without_parent_dir + end + end + + directory package_dir_path => @package_files do + @package_files.each do |fn| + f = File.join(package_dir_path, fn) + fdir = File.dirname(f) + mkdir_p(fdir) unless File.exist?(fdir) + if File.directory?(fn) + mkdir_p(f) + else + rm_f f + safe_ln(fn, f) + end + end + end + self + end + + # The name of this package + + def package_name + @version ? "#{@name}-#{@version}" : @name + end + + # The directory this package will be built in + + def package_dir_path + "#{package_dir}/#{package_name}" + end + + # The package name with .tgz added + + def tgz_file + "#{package_name}.tgz" + end + + # The package name with .tar.gz added + + def tar_gz_file + "#{package_name}.tar.gz" + end + + # The package name with .tar.bz2 added + + def tar_bz2_file + "#{package_name}.tar.bz2" + end + + # The package name with .tar.xz added + + def tar_xz_file + "#{package_name}.tar.xz" + end + + # The package name with .zip added + + def zip_file + "#{package_name}.zip" + end + + def working_dir + without_parent_dir ? package_dir_path : package_dir + end + + # target directory relative to working_dir + def target_dir + without_parent_dir ? "." : package_name + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb new file mode 100644 index 0000000..8f62b7c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +# Defines a :phony task that you can use as a dependency. This allows +# file-based tasks to use non-file-based tasks as prerequisites +# without forcing them to rebuild. +# +# See FileTask#out_of_date? and Task#timestamp for more info. + +require_relative "../rake" + +task :phony + +Rake::Task[:phony].tap do |task| + def task.timestamp # :nodoc: + Time.at 0 + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb new file mode 100644 index 0000000..2815ce6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +module Rake + + # Include PrivateReader to use +private_reader+. + module PrivateReader # :nodoc: all + + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + + # Declare a list of private accessors + def private_reader(*names) + attr_reader(*names) + private(*names) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb new file mode 100644 index 0000000..f45af4f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true +module Rake + + # A Promise object represents a promise to do work (a chore) in the + # future. The promise is created with a block and a list of + # arguments for the block. Calling value will return the value of + # the promised chore. + # + # Used by ThreadPool. + # + class Promise # :nodoc: all + NOT_SET = Object.new.freeze # :nodoc: + + attr_accessor :recorder + + # Create a promise to do the chore specified by the block. + def initialize(args, &block) + @mutex = Mutex.new + @result = NOT_SET + @error = NOT_SET + @args = args + @block = block + end + + # Return the value of this promise. + # + # If the promised chore is not yet complete, then do the work + # synchronously. We will wait. + def value + unless complete? + stat :sleeping_on, item_id: object_id + @mutex.synchronize do + stat :has_lock_on, item_id: object_id + chore + stat :releasing_lock_on, item_id: object_id + end + end + error? ? raise(@error) : @result + end + + # If no one else is working this promise, go ahead and do the chore. + def work + stat :attempting_lock_on, item_id: object_id + if @mutex.try_lock + stat :has_lock_on, item_id: object_id + chore + stat :releasing_lock_on, item_id: object_id + @mutex.unlock + else + stat :bailed_on, item_id: object_id + end + end + + private + + # Perform the chore promised + def chore + if complete? + stat :found_completed, item_id: object_id + return + end + stat :will_execute, item_id: object_id + begin + @result = @block.call(*@args) + rescue Exception => e + @error = e + end + stat :did_execute, item_id: object_id + discard + end + + # Do we have a result for the promise + def result? + !@result.equal?(NOT_SET) + end + + # Did the promise throw an error + def error? + !@error.equal?(NOT_SET) + end + + # Are we done with the promise + def complete? + result? || error? + end + + # free up these items for the GC + def discard + @args = nil + @block = nil + end + + # Record execution statistics if there is a recorder + def stat(*args) + @recorder.call(*args) if @recorder + end + + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb new file mode 100644 index 0000000..8b3c989 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +module Rake + + ## + # Exit status class for times the system just gives us a nil. + class PseudoStatus # :nodoc: all + attr_reader :exitstatus + + def initialize(code=0) + @exitstatus = code + end + + def to_i + @exitstatus << 8 + end + + def >>(n) + to_i >> n + end + + def stopped? + false + end + + def exited? + true + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb new file mode 100644 index 0000000..03c2956 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +require "rake/application" + +module Rake + + class << self + # Current Rake Application + def application + @application ||= Rake::Application.new + end + + # Set the current Rake application object. + def application=(app) + @application = app + end + + def suggested_thread_count # :nodoc: + @cpu_count ||= Rake::CpuCounter.count + @cpu_count + 4 + end + + # Return the original directory where the Rake application was started. + def original_dir + application.original_dir + end + + # Load a rakefile. + def load_rakefile(path) + load(path) + end + + # Add files to the rakelib list + def add_rakelib(*files) + application.options.rakelib ||= [] + application.options.rakelib.concat(files) + end + + # Make +block_application+ the default rake application inside a block so + # you can load rakefiles into a different application. + # + # This is useful when you want to run rake tasks inside a library without + # running rake in a sub-shell. + # + # Example: + # + # Dir.chdir 'other/directory' + # + # other_rake = Rake.with_application do |rake| + # rake.load_rakefile + # end + # + # puts other_rake.tasks + + def with_application(block_application = Rake::Application.new) + orig_application = Rake.application + + Rake.application = block_application + + yield block_application + + block_application + ensure + Rake.application = orig_application + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb new file mode 100644 index 0000000..05d89fc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require_relative "file_list" + +# Load the test files from the command line. +argv = ARGV.select do |argument| + case argument + when /^-/ then + argument + when /\*/ then + Rake::FileList[argument].to_a.each do |file| + require File.expand_path file + end + + false + else + path = File.expand_path argument + + abort "\nFile does not exist: #{path}\n\n" unless File.exist?(path) + + require path + + false + end +end + +ARGV.replace argv diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb new file mode 100644 index 0000000..a51e774 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +module Rake + + # Error indicating a recursion overflow error in task selection. + class RuleRecursionOverflowError < StandardError + def initialize(*args) + super + @targets = [] + end + + def add_target(target) + @targets << target + end + + def message + super + ": [" + @targets.reverse.join(" => ") + "]" + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb new file mode 100644 index 0000000..fc1eb6c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true +module Rake + class Scope < LinkedList # :nodoc: all + + # Path for the scope. + def path + map(&:to_s).reverse.join(":") + end + + # Path for the scope + the named path. + def path_with_task_name(task_name) + "#{path}:#{task_name}" + end + + # Trim +n+ innermost scope levels from the scope. In no case will + # this trim beyond the toplevel scope. + def trim(n) + result = self + while n > 0 && !result.empty? + result = result.tail + n -= 1 + end + result + end + + # Scope lists always end with an EmptyScope object. See Null + # Object Pattern) + class EmptyScope < EmptyLinkedList + @parent = Scope + + def path + "" + end + + def path_with_task_name(task_name) + task_name + end + end + + # Singleton null object for an empty scope. + EMPTY = EmptyScope.new + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb new file mode 100644 index 0000000..e61ccb6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb @@ -0,0 +1,434 @@ +# frozen_string_literal: true +require_relative "invocation_exception_mixin" + +module Rake + + ## + # A Task is the basic unit of work in a Rakefile. Tasks have associated + # actions (possibly more than one) and a list of prerequisites. When + # invoked, a task will first ensure that all of its prerequisites have an + # opportunity to run and then it will execute its own actions. + # + # Tasks are not usually created directly using the new method, but rather + # use the +file+ and +task+ convenience methods. + # + class Task + # List of prerequisites for a task. + attr_reader :prerequisites + alias prereqs prerequisites + + # List of order only prerequisites for a task. + attr_reader :order_only_prerequisites + + # List of actions attached to a task. + attr_reader :actions + + # Application owning this task. + attr_accessor :application + + # Array of nested namespaces names used for task lookup by this task. + attr_reader :scope + + # File/Line locations of each of the task definitions for this + # task (only valid if the task was defined with the detect + # location option set). + attr_reader :locations + + # Has this task already been invoked? Already invoked tasks + # will be skipped unless you reenable them. + attr_reader :already_invoked + + # Return task name + def to_s + name + end + + def inspect # :nodoc: + "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>" + end + + # List of sources for task. + attr_writer :sources + def sources + if defined?(@sources) + @sources + else + prerequisites + end + end + + # List of prerequisite tasks + def prerequisite_tasks + (prerequisites + order_only_prerequisites).map { |pre| lookup_prerequisite(pre) } + end + + def lookup_prerequisite(prerequisite_name) # :nodoc: + scoped_prerequisite_task = application[prerequisite_name, @scope] + if scoped_prerequisite_task == self + unscoped_prerequisite_task = application[prerequisite_name] + end + unscoped_prerequisite_task || scoped_prerequisite_task + end + private :lookup_prerequisite + + # List of all unique prerequisite tasks including prerequisite tasks' + # prerequisites. + # Includes self when cyclic dependencies are found. + def all_prerequisite_tasks + seen = {} + collect_prerequisites(seen) + seen.values + end + + def collect_prerequisites(seen) # :nodoc: + prerequisite_tasks.each do |pre| + next if seen[pre.name] + seen[pre.name] = pre + pre.collect_prerequisites(seen) + end + end + protected :collect_prerequisites + + # First source from a rule (nil if no sources) + def source + sources.first + end + + # Create a task named +task_name+ with no actions or prerequisites. Use + # +enhance+ to add actions and prerequisites. + def initialize(task_name, app) + @name = task_name.to_s + @prerequisites = [] + @actions = [] + @already_invoked = false + @comments = [] + @lock = Monitor.new + @application = app + @scope = app.current_scope + @arg_names = nil + @locations = [] + @invocation_exception = nil + @order_only_prerequisites = [] + end + + # Enhance a task with prerequisites or actions. Returns self. + def enhance(deps=nil, &block) + @prerequisites |= deps if deps + @actions << block if block_given? + self + end + + # Name of the task, including any namespace qualifiers. + def name + @name.to_s + end + + # Name of task with argument list description. + def name_with_args # :nodoc: + if arg_description + "#{name}#{arg_description}" + else + name + end + end + + # Argument description (nil if none). + def arg_description # :nodoc: + @arg_names ? "[#{arg_names.join(',')}]" : nil + end + + # Name of arguments for this task. + def arg_names + @arg_names || [] + end + + # Reenable the task, allowing its tasks to be executed if the task + # is invoked again. + def reenable + @already_invoked = false + @invocation_exception = nil + end + + # Clear the existing prerequisites, actions, comments, and arguments of a rake task. + def clear + clear_prerequisites + clear_actions + clear_comments + clear_args + self + end + + # Clear the existing prerequisites of a rake task. + def clear_prerequisites + prerequisites.clear + self + end + + # Clear the existing actions on a rake task. + def clear_actions + actions.clear + self + end + + # Clear the existing comments on a rake task. + def clear_comments + @comments = [] + self + end + + # Clear the existing arguments on a rake task. + def clear_args + @arg_names = nil + self + end + + # Invoke the task if it is needed. Prerequisites are invoked first. + def invoke(*args) + task_args = TaskArguments.new(arg_names, args) + invoke_with_call_chain(task_args, InvocationChain::EMPTY) + end + + # Same as invoke, but explicitly pass a call chain to detect + # circular dependencies. + # + # If multiple tasks depend on this + # one in parallel, they will all fail if the first execution of + # this task fails. + def invoke_with_call_chain(task_args, invocation_chain) + new_chain = Rake::InvocationChain.append(self, invocation_chain) + @lock.synchronize do + begin + if application.options.trace + application.trace "** Invoke #{name} #{format_trace_flags}" + end + + if @already_invoked + if @invocation_exception + if application.options.trace + application.trace "** Previous invocation of #{name} failed #{format_trace_flags}" + end + raise @invocation_exception + else + return + end + end + + @already_invoked = true + + invoke_prerequisites(task_args, new_chain) + execute(task_args) if needed? + rescue Exception => ex + add_chain_to(ex, new_chain) + @invocation_exception = ex + raise ex + end + end + end + protected :invoke_with_call_chain + + def add_chain_to(exception, new_chain) # :nodoc: + exception.extend(InvocationExceptionMixin) unless + exception.respond_to?(:chain) + exception.chain = new_chain if exception.chain.nil? + end + private :add_chain_to + + # Invoke all the prerequisites of a task. + def invoke_prerequisites(task_args, invocation_chain) # :nodoc: + if application.options.always_multitask + invoke_prerequisites_concurrently(task_args, invocation_chain) + else + prerequisite_tasks.each { |p| + prereq_args = task_args.new_scope(p.arg_names) + p.invoke_with_call_chain(prereq_args, invocation_chain) + } + end + end + + # Invoke all the prerequisites of a task in parallel. + def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc: + futures = prerequisite_tasks.map do |p| + prereq_args = task_args.new_scope(p.arg_names) + application.thread_pool.future(p) do |r| + r.invoke_with_call_chain(prereq_args, invocation_chain) + end + end + # Iterate in reverse to improve performance related to thread waiting and switching + futures.reverse_each(&:value) + end + + # Format the trace flags for display. + def format_trace_flags + flags = [] + flags << "first_time" unless @already_invoked + flags << "not_needed" unless needed? + flags.empty? ? "" : "(" + flags.join(", ") + ")" + end + private :format_trace_flags + + # Execute the actions associated with this task. + def execute(args=nil) + args ||= EMPTY_TASK_ARGS + if application.options.dryrun + application.trace "** Execute (dry run) #{name}" + return + end + application.trace "** Execute #{name}" if application.options.trace + application.enhance_with_matching_rule(name) if @actions.empty? + if opts = Hash.try_convert(args) and !opts.empty? + @actions.each { |act| act.call(self, args, **opts) } + else + @actions.each { |act| act.call(self, args) } + end + end + + # Is this task needed? + def needed? + true + end + + # Timestamp for this task. Basic tasks return the current time for their + # time stamp. Other tasks can be more sophisticated. + def timestamp + Time.now + end + + # Add a description to the task. The description can consist of an option + # argument list (enclosed brackets) and an optional comment. + def add_description(description) + return unless description + comment = description.strip + add_comment(comment) if comment && !comment.empty? + end + + def comment=(comment) # :nodoc: + add_comment(comment) + end + + def add_comment(comment) # :nodoc: + return if comment.nil? + @comments << comment unless @comments.include?(comment) + end + private :add_comment + + # Full collection of comments. Multiple comments are separated by + # newlines. + def full_comment + transform_comments("\n") + end + + # First line (or sentence) of all comments. Multiple comments are + # separated by a "/". + def comment + transform_comments(" / ") { |c| first_sentence(c) } + end + + # Transform the list of comments as specified by the block and + # join with the separator. + def transform_comments(separator, &block) + if @comments.empty? + nil + else + block ||= lambda { |c| c } + @comments.map(&block).join(separator) + end + end + private :transform_comments + + # Get the first sentence in a string. The sentence is terminated + # by the first period, exclamation mark, or the end of the line. + # Decimal points do not count as periods. + def first_sentence(string) + string.split(/(?<=\w)(\.|!)[ \t]|(\.$|!)|\n/).first + end + private :first_sentence + + # Set the names of the arguments for this task. +args+ should be + # an array of symbols, one for each argument name. + def set_arg_names(args) + @arg_names = args.map(&:to_sym) + end + + # Return a string describing the internal state of a task. Useful for + # debugging. + def investigation + result = "------------------------------\n".dup + result << "Investigating #{name}\n" + result << "class: #{self.class}\n" + result << "task needed: #{needed?}\n" + result << "timestamp: #{timestamp}\n" + result << "pre-requisites: \n" + prereqs = prerequisite_tasks + prereqs.sort! { |a, b| a.timestamp <=> b.timestamp } + prereqs.each do |p| + result << "--#{p.name} (#{p.timestamp})\n" + end + latest_prereq = prerequisite_tasks.map(&:timestamp).max + result << "latest-prerequisite time: #{latest_prereq}\n" + result << "................................\n\n" + return result + end + + # Format dependencies parameter to pass to task. + def self.format_deps(deps) + deps = [deps] unless deps.respond_to?(:to_ary) + deps.map { |d| Rake.from_pathname(d).to_s } + end + + # Add order only dependencies. + def |(deps) + @order_only_prerequisites |= Task.format_deps(deps) - @prerequisites + self + end + + # ---------------------------------------------------------------- + # Rake Module Methods + # + class << self + + # Clear the task list. This cause rake to immediately forget all the + # tasks that have been assigned. (Normally used in the unit tests.) + def clear + Rake.application.clear + end + + # List of all defined tasks. + def tasks + Rake.application.tasks + end + + # Return a task with the given name. If the task is not currently + # known, try to synthesize one from the defined rules. If no rules are + # found, but an existing file matches the task name, assume it is a file + # task with no dependencies or actions. + def [](task_name) + Rake.application[task_name] + end + + # TRUE if the task name is already defined. + def task_defined?(task_name) + Rake.application.lookup(task_name) != nil + end + + # Define a task given +args+ and an option block. If a rule with the + # given name already exists, the prerequisites and actions are added to + # the existing task. Returns the defined task. + def define_task(*args, &block) + Rake.application.define_task(self, *args, &block) + end + + # Define a rule for synthesizing tasks. + def create_rule(*args, &block) + Rake.application.create_rule(*args, &block) + end + + # Apply the scope to the task name according to the rules for + # this kind of task. Generic tasks will accept the scope as + # part of the name. + def scope_name(scope, task_name) + scope.path_with_task_name(task_name) + end + + end # class << Rake::Task + end # class Rake::Task +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb new file mode 100644 index 0000000..ef20076 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +module Rake + + # Error indicating an ill-formed task declaration. + class TaskArgumentError < ArgumentError + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb new file mode 100644 index 0000000..24abebc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true +module Rake + + ## + # TaskArguments manage the arguments passed to a task. + # + class TaskArguments + include Enumerable + + # Argument names + attr_reader :names + + # Create a TaskArgument object with a list of argument +names+ and a set + # of associated +values+. +parent+ is the parent argument object. + def initialize(names, values, parent=nil) + @names = names + @parent = parent + @hash = {} + @values = values + names.each_with_index { |name, i| + next if values[i].nil? || values[i] == "" + @hash[name.to_sym] = values[i] + } + end + + # Retrieve the complete array of sequential values + def to_a + @values.dup + end + + # Retrieve the list of values not associated with named arguments + def extras + @values[@names.length..-1] || [] + end + + # Create a new argument scope using the prerequisite argument + # names. + def new_scope(names) + values = names.map { |n| self[n] } + self.class.new(names, values + extras, self) + end + + # Find an argument value by name or index. + def [](index) + lookup(index.to_sym) + end + + # Specify a hash of default values for task arguments. Use the + # defaults only if there is no specific value for the given + # argument. + def with_defaults(defaults) + @hash = defaults.merge(@hash) + end + + # Enumerates the arguments and their values + def each(&block) + @hash.each(&block) + end + + # Extracts the argument values at +keys+ + def values_at(*keys) + keys.map { |k| lookup(k) } + end + + # Returns the value of the given argument via method_missing + def method_missing(sym, *args) + lookup(sym.to_sym) + end + + # Returns a Hash of arguments and their values + def to_hash + @hash.dup + end + + def to_s # :nodoc: + inspect + end + + def inspect # :nodoc: + inspection = @hash.map do |k,v| + "#{k.to_s}: #{v.to_s}" + end.join(", ") + + "#<#{self.class} #{inspection}>" + end + + # Returns true if +key+ is one of the arguments + def has_key?(key) + @hash.has_key?(key) + end + alias key? has_key? + + def fetch(*args, &block) + @hash.fetch(*args, &block) + end + + def deconstruct_keys(keys) + keys ? @hash.slice(*keys) : to_hash + end + + protected + + def lookup(name) # :nodoc: + if @hash.has_key?(name) + @hash[name] + elsif @parent + @parent.lookup(name) + end + end + end + + EMPTY_TASK_ARGS = TaskArguments.new([], []) # :nodoc: +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb new file mode 100644 index 0000000..838779c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb @@ -0,0 +1,331 @@ +# frozen_string_literal: true +module Rake + + # The TaskManager module is a mixin for managing tasks. + module TaskManager + # Track the last comment made in the Rakefile. + attr_accessor :last_description + + def initialize # :nodoc: + super + @tasks = Hash.new + @rules = Array.new + @scope = Scope.make + @last_description = nil + end + + def create_rule(*args, &block) # :nodoc: + pattern, args, deps, order_only = resolve_args(args) + pattern = Regexp.new(Regexp.quote(pattern) + "$") if String === pattern + @rules << [pattern, args, deps, order_only, block] + end + + def define_task(task_class, *args, &block) # :nodoc: + task_name, arg_names, deps, order_only = resolve_args(args) + + original_scope = @scope + if String === task_name and + not task_class.ancestors.include? Rake::FileTask + task_name, *definition_scope = *(task_name.split(":").reverse) + @scope = Scope.make(*(definition_scope + @scope.to_a)) + end + + task_name = task_class.scope_name(@scope, task_name) + task = intern(task_class, task_name) + task.set_arg_names(arg_names) unless arg_names.empty? + if Rake::TaskManager.record_task_metadata + add_location(task) + task.add_description(get_description) + end + task.enhance(Task.format_deps(deps), &block) + task | order_only unless order_only.nil? + task + ensure + @scope = original_scope + end + + # Lookup a task. Return an existing task if found, otherwise + # create a task of the current type. + def intern(task_class, task_name) + @tasks[task_name.to_s] ||= task_class.new(task_name, self) + end + + # Find a matching task for +task_name+. + def [](task_name, scopes=nil) + task_name = task_name.to_s + self.lookup(task_name, scopes) or + enhance_with_matching_rule(task_name) or + synthesize_file_task(task_name) or + fail generate_message_for_undefined_task(task_name) + end + + def generate_message_for_undefined_task(task_name) + message = "Don't know how to build task '#{task_name}' "\ + "(See the list of available tasks with `#{Rake.application.name} --tasks`)" + message + generate_did_you_mean_suggestions(task_name) + end + + def generate_did_you_mean_suggestions(task_name) + return "" unless defined?(::DidYouMean::SpellChecker) + + suggestions = ::DidYouMean::SpellChecker.new(dictionary: @tasks.keys).correct(task_name.to_s) + if ::DidYouMean.respond_to?(:formatter)# did_you_mean v1.2.0 or later + ::DidYouMean.formatter.message_for(suggestions) + elsif defined?(::DidYouMean::Formatter) # before did_you_mean v1.2.0 + ::DidYouMean::Formatter.new(suggestions).to_s + else + "" + end + end + + def synthesize_file_task(task_name) # :nodoc: + return nil unless File.exist?(task_name) + define_task(Rake::FileTask, task_name) + end + + # Resolve the arguments for a task/rule. Returns a tuple of + # [task_name, arg_name_list, prerequisites, order_only_prerequisites]. + def resolve_args(args) + if args.last.is_a?(Hash) + deps = args.pop + resolve_args_with_dependencies(args, deps) + else + resolve_args_without_dependencies(args) + end + end + + # Resolve task arguments for a task or rule when there are no + # dependencies declared. + # + # The patterns recognized by this argument resolving function are: + # + # task :t + # task :t, [:a] + # + def resolve_args_without_dependencies(args) + task_name = args.shift + if args.size == 1 && args.first.respond_to?(:to_ary) + arg_names = args.first.to_ary + else + arg_names = args + end + [task_name, arg_names, [], nil] + end + private :resolve_args_without_dependencies + + # Resolve task arguments for a task or rule when there are + # dependencies declared. + # + # The patterns recognized by this argument resolving function are: + # + # task :t, order_only: [:e] + # task :t => [:d] + # task :t => [:d], order_only: [:e] + # task :t, [a] => [:d] + # task :t, [a] => [:d], order_only: [:e] + # + def resolve_args_with_dependencies(args, hash) # :nodoc: + fail "Task Argument Error" if + hash.size != 1 && + (hash.size != 2 || !hash.key?(:order_only)) + order_only = hash.delete(:order_only) + key, value = hash.map { |k, v| [k, v] }.first + if args.empty? + task_name = key + arg_names = [] + deps = value || [] + else + task_name = args.shift + arg_names = key || args.shift|| [] + deps = value || [] + end + deps = [deps] unless deps.respond_to?(:to_ary) + [task_name, arg_names, deps, order_only] + end + private :resolve_args_with_dependencies + + # If a rule can be found that matches the task name, enhance the + # task with the prerequisites and actions from the rule. Set the + # source attribute of the task appropriately for the rule. Return + # the enhanced task or nil of no rule was found. + def enhance_with_matching_rule(task_name, level=0) + fail Rake::RuleRecursionOverflowError, + "Rule Recursion Too Deep" if level >= 16 + @rules.each do |pattern, args, extensions, order_only, block| + if pattern && pattern.match(task_name) + task = attempt_rule(task_name, pattern, args, extensions, block, level) + task | order_only unless order_only.nil? + return task if task + end + end + nil + rescue Rake::RuleRecursionOverflowError => ex + ex.add_target(task_name) + fail ex + end + + # List of all defined tasks in this application. + def tasks + @tasks.values.sort_by { |t| t.name } + end + + # List of all the tasks defined in the given scope (and its + # sub-scopes). + def tasks_in_scope(scope) + prefix = scope.path + tasks.select { |t| + /^#{prefix}:/ =~ t.name + } + end + + # Clear all tasks in this application. + def clear + @tasks.clear + @rules.clear + end + + # Lookup a task, using scope and the scope hints in the task name. + # This method performs straight lookups without trying to + # synthesize file tasks or rules. Special scope names (e.g. '^') + # are recognized. If no scope argument is supplied, use the + # current scope. Return nil if the task cannot be found. + def lookup(task_name, initial_scope=nil) + initial_scope ||= @scope + task_name = task_name.to_s + if task_name =~ /^rake:/ + scopes = Scope.make + task_name = task_name.sub(/^rake:/, "") + elsif task_name =~ /^(\^+)/ + scopes = initial_scope.trim($1.size) + task_name = task_name.sub(/^(\^+)/, "") + else + scopes = initial_scope + end + lookup_in_scope(task_name, scopes) + end + + # Lookup the task name + def lookup_in_scope(name, scope) + loop do + tn = scope.path_with_task_name(name) + task = @tasks[tn] + return task if task + break if scope.empty? + scope = scope.tail + end + nil + end + private :lookup_in_scope + + # Return the list of scope names currently active in the task + # manager. + def current_scope + @scope + end + + # Evaluate the block in a nested namespace named +name+. Create + # an anonymous namespace if +name+ is nil. + def in_namespace(name) + name ||= generate_name + @scope = Scope.new(name, @scope) + ns = NameSpace.new(self, @scope) + yield(ns) + ns + ensure + @scope = @scope.tail + end + + private + + # Add a location to the locations field of the given task. + def add_location(task) + loc = find_location + task.locations << loc if loc + task + end + + # Find the location that called into the dsl layer. + def find_location + locations = caller + i = 0 + while locations[i] + return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/ + i += 1 + end + nil + end + + # Generate an anonymous namespace name. + def generate_name + @seed ||= 0 + @seed += 1 + "_anon_#{@seed}" + end + + def trace_rule(level, message) # :nodoc: + options.trace_output.puts "#{" " * level}#{message}" if + Rake.application.options.trace_rules + end + + # Attempt to create a rule given the list of prerequisites. + def attempt_rule(task_name, task_pattern, args, extensions, block, level) + sources = make_sources(task_name, task_pattern, extensions) + prereqs = sources.map { |source| + trace_rule level, "Attempting Rule #{task_name} => #{source}" + if File.exist?(source) || Rake::Task.task_defined?(source) + trace_rule level, "(#{task_name} => #{source} ... EXIST)" + source + elsif parent = enhance_with_matching_rule(source, level + 1) + trace_rule level, "(#{task_name} => #{source} ... ENHANCE)" + parent.name + else + trace_rule level, "(#{task_name} => #{source} ... FAIL)" + return nil + end + } + task = FileTask.define_task(task_name, { args => prereqs }, &block) + task.sources = prereqs + task + end + + # Make a list of sources from the list of file name extensions / + # translation procs. + def make_sources(task_name, task_pattern, extensions) + result = extensions.map { |ext| + case ext + when /%/ + task_name.pathmap(ext) + when %r{/} + ext + when /^\./ + source = task_name.sub(task_pattern, ext) + source == ext ? task_name.ext(ext) : source + when String, Symbol + ext.to_s + when Proc, Method + if ext.arity == 1 + ext.call(task_name) + else + ext.call + end + else + fail "Don't know how to handle rule dependent: #{ext.inspect}" + end + } + result.flatten + end + + # Return the current description, clearing it in the process. + def get_description + desc = @last_description + @last_description = nil + desc + end + + class << self + attr_accessor :record_task_metadata # :nodoc: + TaskManager.record_task_metadata = false + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb new file mode 100644 index 0000000..597a2d6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +require_relative "../rake" + +module Rake + + # Base class for Task Libraries. + class TaskLib + include Cloneable + include Rake::DSL + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb new file mode 100644 index 0000000..7cf1ece --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb @@ -0,0 +1,189 @@ +# frozen_string_literal: true +require_relative "../rake" +require_relative "tasklib" + +module Rake + + # Create a task that runs a set of tests. + # + # Example: + # require "rake/testtask" + # + # Rake::TestTask.new do |t| + # t.libs << "test" + # t.test_files = FileList['test/test*.rb'] + # t.verbose = true + # end + # + # If rake is invoked with a "TEST=filename" command line option, + # then the list of test files will be overridden to include only the + # filename specified on the command line. This provides an easy way + # to run just one test. + # + # If rake is invoked with a "TESTOPTS=options" command line option, + # then the given options are passed to the test process after a + # '--'. This allows Test::Unit options to be passed to the test + # suite. + # + # Examples: + # + # rake test # run tests normally + # rake test TEST=just_one_file.rb # run just one test file. + # rake test TESTOPTS="-v" # run in verbose mode + # rake test TESTOPTS="--runner=fox" # use the fox test runner + # + class TestTask < TaskLib + + # Name of test task. (default is :test) + attr_accessor :name + + # List of directories added to $LOAD_PATH before running the + # tests. (default is 'lib') + attr_accessor :libs + + # True if verbose test output desired. (default is false) + attr_accessor :verbose + + # Test options passed to the test suite. An explicit + # TESTOPTS=opts on the command line will override this. (default + # is NONE) + attr_accessor :options + + # Request that the tests be run with the warning flag set. + # E.g. warning=true implies "ruby -w" used to run the tests. + # (default is true) + attr_accessor :warning + + # Glob pattern to match test files. (default is 'test/test*.rb') + attr_accessor :pattern + + # Style of test loader to use. Options are: + # + # * :rake -- Rake provided test loading script (default). + # * :testrb -- Ruby provided test loading script. + # * :direct -- Load tests using command line loader. + # + attr_accessor :loader + + # Array of command line options to pass to ruby when running test loader. + attr_accessor :ruby_opts + + # Description of the test task. (default is 'Run tests') + attr_accessor :description + + # Task prerequisites. + attr_accessor :deps + + # Explicitly define the list of test files to be included in a + # test. +list+ is expected to be an array of file names (a + # FileList is acceptable). If both +pattern+ and +test_files+ are + # used, then the list of test files is the union of the two. + def test_files=(list) + @test_files = list + end + + # Create a testing task. + def initialize(name=:test) + @name = name + @libs = ["lib"] + @pattern = nil + @options = nil + @test_files = nil + @verbose = false + @warning = true + @loader = :rake + @ruby_opts = [] + @description = "Run tests" + (@name == :test ? "" : " for #{@name}") + @deps = [] + if @name.is_a?(Hash) + @deps = @name.values.first + @name = @name.keys.first + end + yield self if block_given? + @pattern = "test/test*.rb" if @pattern.nil? && @test_files.nil? + define + end + + # Create the tasks defined by this task lib. + def define + desc @description + task @name => Array(deps) do + FileUtilsExt.verbose(@verbose) do + puts "Use TESTOPTS=\"--verbose\" to pass --verbose" \ + ", etc. to runners." if ARGV.include? "--verbose" + args = + "#{ruby_opts_string} #{run_code} " + + "#{file_list_string} #{option_list}" + ruby args do |ok, status| + if !ok && status.respond_to?(:signaled?) && status.signaled? + raise SignalException.new(status.termsig) + elsif !ok + status = "Command failed with status (#{status.exitstatus})" + details = ": [ruby #{args}]" + message = + if Rake.application.options.trace or @verbose + status + details + else + status + end + + fail message + end + end + end + end + self + end + + def option_list # :nodoc: + (ENV["TESTOPTS"] || + ENV["TESTOPT"] || + ENV["TEST_OPTS"] || + ENV["TEST_OPT"] || + @options || + "") + end + + def ruby_opts_string # :nodoc: + opts = @ruby_opts.dup + opts.unshift("-I\"#{lib_path}\"") unless @libs.empty? + opts.unshift("-w") if @warning + opts.join(" ") + end + + def lib_path # :nodoc: + @libs.join(File::PATH_SEPARATOR) + end + + def file_list_string # :nodoc: + file_list.map { |fn| "\"#{fn}\"" }.join(" ") + end + + def file_list # :nodoc: + if ENV["TEST"] + FileList[ENV["TEST"]] + else + result = [] + result += @test_files.to_a if @test_files + result += FileList[@pattern].to_a if @pattern + result + end + end + + def ruby_version # :nodoc: + RUBY_VERSION + end + + def run_code # :nodoc: + case @loader + when :direct + "-e \"ARGV.each{|f| require f}\"" + when :testrb + "-S testrb" + when :rake + "#{__dir__}/rake_test_loader.rb" + end + end + + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb new file mode 100644 index 0000000..50e2bc8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +require_relative "private_reader" + +module Rake + + class ThreadHistoryDisplay # :nodoc: all + include Rake::PrivateReader + + private_reader :stats, :items, :threads + + def initialize(stats) + @stats = stats + @items = { _seq_: 1 } + @threads = { _seq_: "A" } + end + + def show + puts "Job History:" + stats.each do |stat| + stat[:data] ||= {} + rename(stat, :thread, threads) + rename(stat[:data], :item_id, items) + rename(stat[:data], :new_thread, threads) + rename(stat[:data], :deleted_thread, threads) + printf("%8d %2s %-20s %s\n", + (stat[:time] * 1_000_000).round, + stat[:thread], + stat[:event], + stat[:data].map do |k, v| "#{k}:#{v}" end.join(" ")) + end + end + + private + + def rename(hash, key, renames) + if hash && hash[key] + original = hash[key] + value = renames[original] + unless value + value = renames[:_seq_] + renames[:_seq_] = renames[:_seq_].succ + renames[original] = value + end + hash[key] = value + end + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb new file mode 100644 index 0000000..ea9c0ae --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +require_relative "promise" +require "set" + +module Rake + + class ThreadPool # :nodoc: all + + # Creates a ThreadPool object. The +thread_count+ parameter is the size + # of the pool. + def initialize(thread_count) + @max_active_threads = [thread_count, 0].max + @threads = Set.new + @threads_mon = Monitor.new + @queue = Queue.new + @join_cond = @threads_mon.new_cond + + @history_start_time = nil + @history = [] + @history_mon = Monitor.new + @total_threads_in_play = 0 + end + + # Creates a future executed by the +ThreadPool+. + # + # The args are passed to the block when executing (similarly to + # Thread#new) The return value is an object representing + # a future which has been created and added to the queue in the + # pool. Sending #value to the object will sleep the + # current thread until the future is finished and will return the + # result (or raise an exception thrown from the future) + def future(*args, &block) + promise = Promise.new(args, &block) + promise.recorder = lambda { |*stats| stat(*stats) } + + @queue.enq promise + stat :queued, item_id: promise.object_id + start_thread + promise + end + + # Waits until the queue of futures is empty and all threads have exited. + def join + @threads_mon.synchronize do + begin + stat :joining + @join_cond.wait unless @threads.empty? + stat :joined + rescue Exception => e + stat :joined + $stderr.puts e + $stderr.print "Queue contains #{@queue.size} items. " + + "Thread pool contains #{@threads.count} threads\n" + $stderr.print "Current Thread #{Thread.current} status = " + + "#{Thread.current.status}\n" + $stderr.puts e.backtrace.join("\n") + @threads.each do |t| + $stderr.print "Thread #{t} status = #{t.status}\n" + $stderr.puts t.backtrace.join("\n") + end + raise e + end + end + end + + # Enable the gathering of history events. + def gather_history #:nodoc: + @history_start_time = Time.now if @history_start_time.nil? + end + + # Return a array of history events for the thread pool. + # + # History gathering must be enabled to be able to see the events + # (see #gather_history). Best to call this when the job is + # complete (i.e. after ThreadPool#join is called). + def history # :nodoc: + @history_mon.synchronize { @history.dup }. + sort_by { |i| i[:time] }. + each { |i| i[:time] -= @history_start_time } + end + + # Return a hash of always collected statistics for the thread pool. + def statistics # :nodoc: + { + total_threads_in_play: @total_threads_in_play, + max_active_threads: @max_active_threads, + } + end + + private + + # processes one item on the queue. Returns true if there was an + # item to process, false if there was no item + def process_queue_item #:nodoc: + return false if @queue.empty? + + # Even though we just asked if the queue was empty, it + # still could have had an item which by this statement + # is now gone. For this reason we pass true to Queue#deq + # because we will sleep indefinitely if it is empty. + promise = @queue.deq(true) + stat :dequeued, item_id: promise.object_id + promise.work + return true + + rescue ThreadError # this means the queue is empty + false + end + + def start_thread # :nodoc: + @threads_mon.synchronize do + next unless @threads.count < @max_active_threads + + t = Thread.new do + begin + loop do + break unless process_queue_item + end + ensure + @threads_mon.synchronize do + @threads.delete Thread.current + stat :ended, thread_count: @threads.count + @join_cond.broadcast if @threads.empty? + end + end + end + + @threads << t + stat( + :spawned, + new_thread: t.object_id, + thread_count: @threads.count) + @total_threads_in_play = @threads.count if + @threads.count > @total_threads_in_play + end + end + + def stat(event, data=nil) # :nodoc: + return if @history_start_time.nil? + info = { + event: event, + data: data, + time: Time.now, + thread: Thread.current.object_id, + } + @history_mon.synchronize { @history << info } + end + + # for testing only + + def __queue__ # :nodoc: + @queue + end + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb new file mode 100644 index 0000000..d713a09 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +module Rake + module TraceOutput # :nodoc: all + + # Write trace output to output stream +out+. + # + # The write is done as a single IO call (to print) to lessen the + # chance that the trace output is interrupted by other tasks also + # producing output. + def trace_on(out, *strings) + sep = $\ || "\n" + if strings.empty? + output = sep + else + output = strings.map { |s| + next if s.nil? + s.end_with?(sep) ? s : s + sep + }.join + end + out.print(output) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb new file mode 100644 index 0000000..01df37d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +module Rake + VERSION = "13.3.1" + + module Version # :nodoc: all + MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split "." + + NUMBERS = [MAJOR, MINOR, BUILD, *OTHER] + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb new file mode 100644 index 0000000..6e62031 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +require "rbconfig" + +module Rake + # Win 32 interface methods for Rake. Windows specific functionality + # will be placed here to collect that knowledge in one spot. + module Win32 # :nodoc: all + + # Error indicating a problem in locating the home directory on a + # Win32 system. + class Win32HomeError < RuntimeError + end + + class << self + # True if running on a windows system. + def windows? + RbConfig::CONFIG["host_os"] =~ %r!(msdos|mswin|djgpp|mingw|[Ww]indows)! + end + + # The standard directory containing system wide rake files on + # Win 32 systems. Try the following environment variables (in + # order): + # + # * HOME + # * HOMEDRIVE + HOMEPATH + # * APPDATA + # * USERPROFILE + # + # If the above are not defined, the return nil. + def win32_system_dir #:nodoc: + win32_shared_path = ENV["HOME"] + if win32_shared_path.nil? && ENV["HOMEDRIVE"] && ENV["HOMEPATH"] + win32_shared_path = ENV["HOMEDRIVE"] + ENV["HOMEPATH"] + end + + win32_shared_path ||= ENV["APPDATA"] + win32_shared_path ||= ENV["USERPROFILE"] + raise Win32HomeError, + "Unable to determine home path environment variable." if + win32_shared_path.nil? or win32_shared_path.empty? + normalize(File.join(win32_shared_path, "Rake")) + end + + # Normalize a win32 path so that the slashes are all forward slashes. + def normalize(path) + path.gsub(/\\/, "/") + end + + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec new file mode 100644 index 0000000..5899790 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require_relative "lib/rake/version" + +Gem::Specification.new do |s| + s.name = "rake" + s.version = Rake::VERSION + s.authors = ["Hiroshi SHIBATA", "Eric Hodel", "Jim Weirich"] + s.email = ["hsbt@ruby-lang.org", "drbrain@segment7.net", ""] + + s.summary = "Rake is a Make-like program implemented in Ruby" + s.description = <<~DESCRIPTION + Rake is a Make-like program implemented in Ruby. Tasks and dependencies are + specified in standard Ruby syntax. + Rake has the following features: + * Rakefiles (rake's version of Makefiles) are completely defined in standard Ruby syntax. + No XML files to edit. No quirky Makefile syntax to worry about (is that a tab or a space?) + * Users can specify tasks with prerequisites. + * Rake supports rule patterns to synthesize implicit tasks. + * Flexible FileLists that act like arrays but know about manipulating file names and paths. + * Supports parallel execution of tasks. + DESCRIPTION + s.homepage = "https://github.com/ruby/rake" + s.licenses = ["MIT"] + + s.metadata = { + "bug_tracker_uri" => "https://github.com/ruby/rake/issues", + "changelog_uri" => "https://github.com/ruby/rake/releases", + "documentation_uri" => "https://ruby.github.io/rake", + "source_code_uri" => s.homepage + } + + s.files = [ + "History.rdoc", + "MIT-LICENSE", + "README.rdoc", + "doc/command_line_usage.rdoc", + "doc/example/Rakefile1", + "doc/example/Rakefile2", + "doc/example/a.c", + "doc/example/b.c", + "doc/example/main.c", + "doc/glossary.rdoc", + "doc/jamis.rb", + "doc/proto_rake.rdoc", + "doc/rake.1", + "doc/rakefile.rdoc", + "doc/rational.rdoc", + "exe/rake", + "lib/rake.rb", + "lib/rake/application.rb", + "lib/rake/backtrace.rb", + "lib/rake/clean.rb", + "lib/rake/cloneable.rb", + "lib/rake/cpu_counter.rb", + "lib/rake/default_loader.rb", + "lib/rake/dsl_definition.rb", + "lib/rake/early_time.rb", + "lib/rake/ext/core.rb", + "lib/rake/ext/string.rb", + "lib/rake/file_creation_task.rb", + "lib/rake/file_list.rb", + "lib/rake/file_task.rb", + "lib/rake/file_utils.rb", + "lib/rake/file_utils_ext.rb", + "lib/rake/invocation_chain.rb", + "lib/rake/invocation_exception_mixin.rb", + "lib/rake/late_time.rb", + "lib/rake/linked_list.rb", + "lib/rake/loaders/makefile.rb", + "lib/rake/multi_task.rb", + "lib/rake/name_space.rb", + "lib/rake/packagetask.rb", + "lib/rake/phony.rb", + "lib/rake/private_reader.rb", + "lib/rake/promise.rb", + "lib/rake/pseudo_status.rb", + "lib/rake/rake_module.rb", + "lib/rake/rake_test_loader.rb", + "lib/rake/rule_recursion_overflow_error.rb", + "lib/rake/scope.rb", + "lib/rake/task.rb", + "lib/rake/task_argument_error.rb", + "lib/rake/task_arguments.rb", + "lib/rake/task_manager.rb", + "lib/rake/tasklib.rb", + "lib/rake/testtask.rb", + "lib/rake/thread_history_display.rb", + "lib/rake/thread_pool.rb", + "lib/rake/trace_output.rb", + "lib/rake/version.rb", + "lib/rake/win32.rb", + "rake.gemspec" + ] + s.bindir = "exe" + s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) } + s.require_paths = ["lib"] + + s.required_ruby_version = Gem::Requirement.new(">= 2.3") + s.rdoc_options = ["--main", "README.rdoc"] +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md new file mode 100644 index 0000000..722b21e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md @@ -0,0 +1,27 @@ +The MIT License (MIT) +===================== + +Copyright © 2009 Chad Humphries, David Chelimsky +Copyright © 2006 David Chelimsky, The RSpec Development Team +Copyright © 2005 Steven Baker + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the “Software”), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md new file mode 100644 index 0000000..4af390d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md @@ -0,0 +1,47 @@ +# RSpec + +Behaviour Driven Development for Ruby + +**The rspec metagem repository has been renamed to rspec-metagem, please update +any rspec/rspec Github references to rspec/rspec-metagem, this is in preparation +for a new mono-repo approach to RSpec dev to unify issue tracking and PR management** + +## Description + +rspec is a meta-gem, which depends on the +[rspec-core](https://github.com/rspec/rspec-core), +[rspec-expectations](https://github.com/rspec/rspec-expectations) +and [rspec-mocks](https://github.com/rspec/rspec-mocks) gems. Each of these +can be installed separately and loaded in isolation using `require`. Among +other benefits, this allows you to use rspec-expectations, for example, in +Test::Unit::TestCase if you happen to prefer that style. + +Conversely, if you like RSpec's approach to declaring example groups and +examples (`describe` and `it`) but prefer Test::Unit assertions and +[mocha](https://github.com/freerange/mocha), [rr](https://github.com/rr/rr) +or [flexmock](https://github.com/jimweirich/flexmock) for mocking, you'll be +able to do that without having to install or load the components of RSpec that +you're not using. + +## Documentation + +See http://rspec.info/documentation/ for links to documentation for all gems. + +## Install + + gem install rspec + +## Setup + + rspec --init + +## Contribute + +* [http://github.com/rspec/rspec-dev](http://github.com/rspec/rspec-dev) + +## Also see + +* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) +* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations) +* [https://github.com/rspec/rspec-mocks](https://github.com/rspec/rspec-mocks) +* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb new file mode 100644 index 0000000..36149e0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb @@ -0,0 +1,3 @@ +require 'rspec/core' +require 'rspec/version' + diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb new file mode 100644 index 0000000..0db236d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb @@ -0,0 +1,5 @@ +module RSpec # :nodoc: + module Version # :nodoc: + STRING = '3.13.2' + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document new file mode 100644 index 0000000..52a564f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +- +README.md +LICENSE.md +Changelog.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts new file mode 100644 index 0000000..0e44326 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts @@ -0,0 +1,8 @@ +--exclude features +--no-private +--markup markdown +--default-return void +- +Filtering.md +Changelog.md +LICENSE.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md new file mode 100644 index 0000000..fb1eaff --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md @@ -0,0 +1,2447 @@ +### Development +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-core-v3.13.6...3-13-maintenance) + +### 3.13.6 / 2025-10-19 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.4...rspec-core-v3.13.5) + +Bug Fixes: + +* Add explicit block parameter to `RSpec::World::Null.traverse_example_group_trees_until` to + prevent warning. (@viralpraxis, rspec/rspec#240) + +### 3.13.5 / 2025-06-25 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.4...rspec-core-v3.13.5) + +Bug Fixes: + +* Fix finding failed lines from frozen backtrace arrays. (Jon Rowe, #225) + +### 3.13.4 / 2025-05-27 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.3...rspec-core-v3.13.4) + +Bug Fixes: + +* Fix links in gemspec to point to the monorepo / homepage. + +### 3.13.3 / 2025-02-06 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.4...rspec-core-v3.13.3) + +Bug fixes: + +* Fix reporter memorisation of `ExamplesNotification` used in `RSpec::Core::Reporter#finish` + by reusing an instance across notifcations. (Maxime Lapointe, rspec/rspec#172) +* Fix memorisation of `RSpec::Core::Example#location_rerun_argument`. + (Maxime Lapointe, rspec/rspec#173) + +### 3.13.2 / 2024-10-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.13.1...v3.13.2) + +Bug fixes: + +* `RSpec::Configuration#requires` will reflect files already required, whilst requiring + them. (Jon Rowe, rspec/rspec-core#3117) + +### 3.13.1 / 2024-09-02 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.13.0...v3.13.1) + +Bug fixes: + +* Sort ids to run as the original order to fix `--bisect`. (Maki Kawahara, rspec/rspec-core#3093) + +### 3.13.0 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.3...v3.13.0) + +Enhancements: + +* Support the `--backtrace` flag when using the JSON formatter. (Matt Larraz, rspec/rspec-core#2980) +* Ignore commented out lines in CLI config files (e.g. `.rspec`). (Junichi Ito, rspec/rspec-core#2984) +* Add `pending_failure_output` config option to allow skipping backtraces or + muting pending specs output. (Phil Pirozhkov, rspec/rspec-core#2957) +* Process `--dry-run` before configuration flags that read files so that introspecting + it returns the correct value. (Xenor Chang, rspec/rspec-core#3008) +* Allow specifying custom ordering strategies via `--order`. (Jon Rowe, rspec/rspec-core#3025) +* Use the improved `syntax_suggest` output for `SyntaxError` when available. + (Richard Schneeman, rspec/rspec-core#3015, rspec/rspec-core#3026) +* Add config option (`RSpec::Core::Configuration#full_cause_backtrace`) to print the + entire backtrace of an exception cause. (David Taylor, rspec/rspec-core#3046) + +### 3.12.3 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.2...v3.12.3) + +Bug fixes: + +* Use `__send__` in output wrapper to avoid issues with IO objects that implement `send` + like `Socket`. (Richard Platel, rspec/rspec-core#3045) + +### 3.12.2 / 2023-04-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.1...v3.12.2) + +Bug fixes: + +* Remove link to outdated documentation in generated output. (Jon Rowe, rspec/rspec-core#3035) + +### 3.12.1 / 2023-02-03 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.0...v3.12.1) + +Bug fixes: + +* Prevent multiple calls to `extra_failure_lines` from adding additional whitespace + around them when the lines already contain whitespace. (Jon Rowe, rspec/rspec-core#3006) + +### 3.12.0 / 2022-10-26 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.11.0...v3.12.0) + +* No changes, released to support other gems. + +### 3.11.0 / 2022-02-09 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.2...v3.11.0) + +Enhancements: + +* Improve pluralisation of words ending with `s` (like process). (Joshua Pinter, rspec/rspec-core#2779) +* Add ordering by file modification time (most recent first). (Matheus Richard, rspec/rspec-core#2778) +* Add `to_s` to reserved names for #let and #subject. (Nick Flückiger, rspec/rspec-core#2886) +* Introduce `RSpec.current_scope` to expose the current scope in which + RSpec is executing. e.g. `:before_example_hook`, `:example` etc. (@odinhb, rspec/rspec-core#2895) +* Add named bold colours as options for custom colours. (rspec/rspec-core#2913, rspec/rspec-core#2914) +* Warn when (but not prevent) a `SystemExit` occurs. (Jared Beck, rspec/rspec-core#2926) + +### 3.10.2 / 2022-01-27 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.1...v3.10.2) + +Bug fixes: + +* Ensure bisect communication uses consistent encoding. (Mike Jarema, rspec/rspec-core#2852) +* Fix exception presenter when the root cause exception has nil backtrace. + (Zinovyev Ivan, rspec/rspec-core#2903) +* Fix `inspect` output of `RSpec::Core::Example::Procsy` to namespace correctly. + (Keiko Kaneko, rspec/rspec-core#2915) +* Ensure formatters not exposing `#output` will not crash duplicate check. + (@niceking, rspec/rspec-core#2916) + +### 3.10.1 / 2020-12-27 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.0...v3.10.1) + +Bug fixes: + +* RSpec warning output was missing deprecations from Ruby, these are now included. + (Jon Rowe, rspec/rspec-core#2811) + +### 3.10.0 / 2020-10-30 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.3...v3.10.0) + +Enhancements: + +* Memoize `RSpec::Core::Formatters::ExceptionPresenter#exception_lines` to improve performance + with slow exception messages. (Maxime Lapointe, rspec/rspec-core#2743) +* Add configuration for an error exit code (to disambiguate errored builds from failed builds + by exit status). (Dana Sherson, rspec/rspec-core#2749) + +### 3.9.3 / 2020-09-30 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.2...v3.9.3) + +Bug Fixes: + +* Declare `ruby2_keywords` on `method_missing` for other gems. (Jon Rowe, rspec/rspec-core#2731) +* Ensure custom error codes are returned from bisect runs. (Jon Rowe, rspec/rspec-core#2732) +* Ensure `RSpec::Core::Configuration` predicate config methods return booleans. + (Marc-André Lafortune, rspec/rspec-core#2736) +* Prevent `rspec --bisect` from generating zombie processes while executing + bisect runs. (Benoit Tigeot, Jon Rowe, rspec/rspec-core#2739) +* Predicates for pending examples, (in `RSpec::Core::Example`, `#pending?`, `#skipped?` and + `#pending_fixed?`) now return boolean values rather than truthy values. + (Marc-André Lafortune, rspec/rspec-core#2756, rspec/rspec-core#2758) +* Exceptions which have a message which cannot be cast to a string will no longer + cause a crash. (Jon Rowe, rspec/rspec-core#2761) + +### 3.9.2 / 2020-05-02 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.1...v3.9.2) + +Bug Fixes: + +* Emit a warning when `around` hook is used with `:context` scope + (Phil Pirozhkov, rspec/rspec-core#2687) +* Prevent invalid implementations of `Exception#cause` from being treated as a + valid cause (and causing strange errors) in `RSpec::Core::Formatters::ExceptionPresenter`. + (Jon Rowe, rspec/rspec-core#2703) +* Correctly detect patterns when `rspec_opts` is an array in `RSpec::Core::RakeTask`. + (Marc-André Lafortune, rspec/rspec-core#2704) +* Make `RSpec.clear_examples` reset example counts for example groups. This fixes + an issue with re-running specs not matching ids. (Agis Anastasopoulos, rspec/rspec-core#2723) + +### 3.9.1 / 2019-12-28 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.0...v3.9.1) + +Bug Fixes: + +* Prevent bisect command from blocking when number of specs exceeds file + descriptor limit on OSX or Linux. (Benoit Tigeot, rspec/rspec-core#2669) +* Prevent warnings being issued on Ruby 2.7.0. (Jon Rowe, rspec/rspec-core#2680) + +### 3.9.0 / 2019-10-07 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.2...v3.9.0) + +Enhancements: + +* Improve the handling of errors during loading support files, if a file + errors before loading specs, RSpec will now skip loading the specs. + (David Rodríguez, rspec/rspec-core#2568) +* Add support for --example-matches to run examples by regular expression. + (Sam Joseph, Matt Rider, @okothkongo1, rspec/rspec-core#2586) +* Add `did_you_mean` suggestions for file names encountering a `LoadError` + outside of examples. (@obromios, rspec/rspec-core#2601) +* Add a minimalist quick fix style formatter, only outputs failures as + `file:line:message`. (Romain Tartière, rspec/rspec-core#2614) +* Convert string number values to integer when used for `RSpec::Configuration#fail_fast` + (Viktor Fonic, rspec/rspec-core#2634) +* Issue warning when invalid values are used for `RSpec::Configuration#fail_fast` + (Viktor Fonic, rspec/rspec-core#2634) +* Add support for running the Rake task in a clean environment. + (Jon Rowe, rspec/rspec-core#2632) +* Indent messages by there example group / example in the documentation formatter. + (Samuel Williams, rspec/rspec-core#2649) + +### 3.8.2 / 2019-06-29 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.1...v3.8.2) + +Bug Fixes: + +* Fix `config.define_derived_metadata` so that cascades are not triggered + until metadata has been assigned to the example or example group + (Myron Marston, rspec/rspec-core#2635). + +### 3.8.1 / 2019-06-13 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.0...v3.8.1) + +Bug Fixes: + +* Handle RSpec description(s) with japanese chars in CP932 encoded files. + (Benoit Tigeot, rspec/rspec-core#2575) +* When defining `let` methods that overwrite an existing method, prevent + a warning being issued by removing the old definition. (Jon Rowe, rspec/rspec-core#2593) +* Prevent warning on Ruby 2.6.0-rc1 (Keiji Yoshimi, rspec/rspec-core#2582) +* Fix `config.define_derived_metadata` so that it supports cascades. + (Myron Marston, rspec/rspec-core#2630). + +### 3.8.0 / 2018-08-04 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.1...v3.8.0) + +Enhancements: + +* Improve shell escaping used by `RSpec::Core::RakeTask` and `--bisect` so + that it works on `Pathname` objects. (Andrew Vit, rspec/rspec-core#2479) +* Nicely format errors encountered while loading files specified + by `--require` option. (Myron Marston, rspec/rspec-core#2504) +* Significantly improve the performance of `--bisect` on platforms that + support forking by replacing the shell-based runner with one that uses + forking so that RSpec and the application environment can be booted only + once, instead of once per spec run. (Myron Marston, rspec/rspec-core#2511) +* Provide a configuration API to pick which bisect runner is used for + `--bisect`. Pick a runner via `config.bisect_runner = :shell` or + `config.bisect_runner = :fork` in a file loaded by a `--require` + option passed at the command line or set in `.rspec`. (Myron Marston, rspec/rspec-core#2511) +* Support the [XDG Base Directory + Specification](https://specifications.freedesktop.org/basedir-spec/latest/) + for the global options file. `~/.rspec` is still supported when no + options file is found in `$XDG_CONFIG_HOME/rspec/options` (Magnus Bergmark, rspec/rspec-core#2538) +* Extract `RSpec.world.prepare_example_filtering` that sets up the + example filtering for custom RSpec runners. (Oleg Pudeyev, rspec/rspec-core#2552) + +Bug Fixes: + +* Prevent an `ArgumentError` when truncating backtraces with two identical + backtraces. (Systho, rspec/rspec-core#2515, Benoit Tigeot, rspec/rspec-core#2539) + +### 3.7.1 / 2018-01-02 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.0...v3.7.1) + +Bug Fixes: + +* Work around duplicate config hook regression introduced + by Ruby 2.5's lazy proc allocation. (Myron Marston, rspec/rspec-core#2497) + +### 3.7.0 / 2017-10-17 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0...v3.7.0) + +Enhancements: + +* Add `-n` alias for `--next-failure`. (Ian Ker-Seymer, rspec/rspec-core#2434) +* Improve compatibility with `--enable-frozen-string-literal` option + on Ruby 2.3+. (Pat Allan, rspec/rspec-core#2425, rspec/rspec-core#2427, rspec/rspec-core#2437) +* Do not run `:context` hooks for example groups that have been skipped. + (Devon Estes, rspec/rspec-core#2442) +* Add `errors_outside_of_examples_count` to the JSON formatter. + (Takeshi Arabiki, rspec/rspec-core#2448) + +Bug Fixes: + +* Improve compatibility with frozen string literal flag. (rspec/rspec-core#2425, Pat Allan) + +### 3.6.0 / 2017-05-04 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta2...v3.6.0) + +Enhancements: + +* Add seed information to JSON formatter output. (rspec/rspec-core#2388, Mitsutaka Mimura) +* Include example id in the JSON formatter output. (rspec/rspec-core#2369, Xavier Shay) +* Respect changes to `config.output_stream` after formatters have been + setup. (rspec/rspec-core#2401, rspec/rspec-core#2419, Ilya Lavrov) + +Bug Fixes: + +* Delay formatter loading until the last minute to allow accessing the reporter + without triggering formatter setup. (Jon Rowe, rspec/rspec-core#2243) +* Ensure context hook failures running before an example can access the + reporter. (Jon Jensen, rspec/rspec-core#2387) +* Multiple fixes to allow using the runner multiple times within the same + process: `RSpec.clear_examples` resets the formatter and no longer clears + shared examples, and streams can be used across multiple runs rather than + being closed after the first. (rspec/rspec-core#2368, Xavier Shay) +* Prevent unexpected `example_group_finished` notifications causing an error. + (rspec/rspec-core#2396, VTJamie) +* Fix bugs where `config.when_first_matching_example_defined` hooks would fire + multiple times in some cases. (Yuji Nakayama, rspec/rspec-core#2400) +* Default `last_run_status` to "unknown" when the `status` field in the + persistence file contains an unrecognized value. (rspec/rspec-core#2360, matrinox) +* Prevent `let` from defining an `initialize` method. (rspec/rspec-core#2414, Jon Rowe) + +### 3.6.0.beta2 / 2016-12-12 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta1...v3.6.0.beta2) + +Enhancements: + +* Include count of errors occurring outside examples in default summaries. + (rspec/rspec-core#2351, Jon Rowe) +* Warn when including shared example groups recursively. (rspec/rspec-core#2356, Jon Rowe) +* Improve failure snippet syntax highlighting with CodeRay to highlight + RSpec "keywords" like `expect`. (rspec/rspec-core#2358, Myron Marston) + +### 3.6.0.beta1 / 2016-10-09 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.4...v3.6.0.beta1) + +Enhancements: + +* Warn when duplicate shared examples definitions are loaded due to being + defined in files matching the spec pattern (e.g. `_spec.rb`) (rspec/rspec-core#2278, Devon Estes) +* Improve metadata filtering so that it can match against any object + that implements `===` instead of treating regular expressions as + special. (Myron Marston, rspec/rspec-core#2294) +* Improve `rspec -v` so that it prints out the versions of each part of + RSpec to prevent confusion. (Myron Marston, rspec/rspec-core#2304) +* Add `config.fail_if_no_examples` option which causes RSpec to fail if + no examples are found. (Ewa Czechowska, rspec/rspec-core#2302) +* Nicely format errors encountered while loading spec files. + (Myron Marston, rspec/rspec-core#2323) +* Improve the API for enabling and disabling color output (Josh + Justice, rspec/rspec-core#2321): + * Automatically enable color if the output is a TTY, since color is + nearly always desirable if the output can handle it. + * Introduce new CLI flag to force color on (`--force-color`), even + if the output is not a TTY. `--no-color` continues to work as well. + * Introduce `config.color_mode` for configuring the color from Ruby. + `:automatic` is the default and will produce color if the output is + a TTY. `:on` forces it on and `:off` forces it off. + +### 3.5.4 / 2016-09-30 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.3...v3.5.4) + +Bug Fixes: + +* Remove accumulated `ExampleGroup` constants when reseting RSpec, + preventing a memory leak. (TravisSpangle, rspec/rspec-core#2328) + +### 3.5.3 / 2016-09-02 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.2...v3.5.3) + +Bug Fixes: + +* When applying shared group metadata to a host group, overwrite + conflicting keys if the value in the host group was inherited from + a parent group instead of being specified at that level. + (Myron Marston, rspec/rspec-core#2307) +* Handle errors in `:suite` hooks and provide the same nicely formatted + output as errors that happen in examples. (Myron Marston, rspec/rspec-core#2316) +* Set the exit status to non-zero when an error occurs in an + `after(:context)` hook. (Myron Marston, rspec/rspec-core#2320) + +### 3.5.2 / 2016-07-28 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.1...v3.5.2) + +Bug Fixes: + +* Wait to report `example_finished` until the example's `execution_result` + has been completely filled in. (Myron Marston, rspec/rspec-core#2291) +* Make sure example block is still available when using `duplicate_with` + to clone examples. (bootstraponline, rspec/rspec-core#2298) +* Don't include the default `--pattern` in the Rake task when + `rspec_opts` specifies its own. (Jon Rowe, rspec/rspec-core#2305) + +### 3.5.1 / 2016-07-06 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0...v3.5.1) + +Bug Fixes: + +* Ensure that config hooks that are added to existing example groups are + added only once. (Eugene Kenny, rspec/rspec-core#2280) + +### 3.5.0 / 2016-07-01 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta4...v3.5.0) + +Enhancements: + +* Include any `SPEC_OPTS` in reproduction command printed at the end of + a bisect run. (Simon Coffey, rspec/rspec-core#2274) + +Bug Fixes: + +* Handle `--bisect` in `SPEC_OPTS` environment variable correctly so as + to avoid infinite recursion. (Simon Coffey, rspec/rspec-core#2271) + +### 3.5.0.beta4 / 2016-06-05 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta3...v3.5.0.beta4) + +Enhancements: + +* Filter out bundler stackframes from backtraces by default, since + Bundler 1.12 now includes its own frames in stack traces produced + by using `bundle exec`. (Myron Marston, rspec/rspec-core#2240) +* HTML Formatter uses exception presenter to get failure message + for consistency with other formatters. (@mrageh, rspec/rspec-core#2222) +* Load spec files in the order of the directories or files passed + at the command line, making it easy to make some specs run before + others in a one-off manner. For example, `rspec spec/unit + spec/acceptance --order defined` will run unit specs before acceptance + specs. (Myron Marston, rspec/rspec-core#2253) +* Add new `config.include_context` API for configuring global or + filtered inclusion of shared contexts in example groups. + (Myron Marston, rspec/rspec-core#2256) +* Add new `config.shared_context_metadata_behavior = :apply_to_host_groups` + option, which causes shared context metadata to be inherited by the + metadata hash of all host groups and examples instead of configuring + implicit auto-inclusion based on the passed metadata. (Myron Marston, rspec/rspec-core#2256) + +Bug Fixes: + +* Fix `--bisect` so it works on large spec suites that were previously triggering + "Argument list too long errors" due to all the spec locations being passed as + CLI args. (Matt Jones, rspec/rspec-core#2223). +* Fix deprecated `:example_group`-based filtering so that it properly + applies to matching example groups. (Myron Marston, rspec/rspec-core#2234) +* Fix `NoMethodError` caused by Java backtraces on JRuby. (Michele Piccirillo, rspec/rspec-core#2244) + +### 3.5.0.beta3 / 2016-04-02 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta2...v3.5.0.beta3) + +Enhancements: + +* Add new `config.filter_run_when_matching` API, intended to replace + the combination of `config.filter_run` and + `config.run_all_when_everything_filtered` (Myron Marston, rspec/rspec-core#2206) + +Bug Fixes: + +* Use the encoded string logic for source extraction. (Jon Rowe, rspec/rspec-core#2183) +* Fix rounding issue in duration formatting helper. (Fabersky, Jon Rowe, rspec/rspec-core#2208) +* Fix failure snippet extraction so that `def-end` snippets + ending with `end`-only line can be extracted properly. + (Yuji Nakayama, rspec/rspec-core#2215) + +### 3.5.0.beta2 / 2016-03-10 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta1...v3.5.0.beta2) + +Enhancements: + +* Remove unneeded `:execution_result` example group metadata, saving a + bit of memory. (Myron Marston, rspec/rspec-core#2172) +* Apply hooks registered with `config` to previously defined groups. + (Myron Marston, rspec/rspec-core#2189) +* `RSpec::Core::Configuration#reporter` is now public API under SemVer. + (Jon Rowe, rspec/rspec-core#2193) +* Add new `config.when_first_matching_example_defined` hook. (Myron + Marston, rspec/rspec-core#2175) + +### 3.5.0.beta1 / 2016-02-06 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.4...v3.5.0.beta1) + +Enhancements: + +* Add `RSpec::Core::ExampleGroup.currently_executing_a_context_hook?`, + primarily for use by rspec-rails. (Sam Phippen, rspec/rspec-core#2131) + +Bug Fixes: + +* Ensure `MultipleExceptionError` does not contain a recursive reference + to itself. (Sam Phippen, rspec/rspec-core#2133) + +### 3.4.4 / 2016-03-09 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.3...v3.4.4) + +Bug Fixes: + +* Fix `RSpec::Core::RakeTask` so that it works with Rake 11. + (Travis Grathwell, rspec/rspec-core#2197) + +### 3.4.3 / 2016-02-19 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.2...v3.4.3) + +Bug Fixes: + +* Prevent a `TypeError` from occurring when running via the rake task when + Ruby crashes. (Patrik Wenger, rspec/rspec-core#2161) +* Only consider example and group declaration lines from a specific file + when applying line number filtering, instead of considering all + declaration lines from all spec files. (Myron Marston, rspec/rspec-core#2170) +* Fix failure snippet extraction so that snippets that contain `do-end` style + block and end with `end`-only line can be extracted properly. + (Yuji Nakayama, rspec/rspec-core#2173) +* Prevent infinite recursion when an exception is caused by itself. + (Jon Rowe, rspec/rspec-core#2128) + +### 3.4.2 / 2016-01-26 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.1...v3.4.2) + +Bug Fixes: + +* Fix `rspec --profile` when an example calls `abort` or `exit`. + (Bradley Schaefer, rspec/rspec-core#2144) +* Fix `--drb` so that when no DRb server is running, it prevents + the DRb connection error from being listed as the cause of all + expectation failures. (Myron Marston, rspec/rspec-core#2156) +* Fix syntax highlighter so that it works when the `coderay` gem is + installed as a rubygem but not already available on your load path + (as happens when you use bundler). (Myron Marston, rspec/rspec-core#2159) + +### 3.4.1 / 2015-11-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.0...v3.4.1) + +Bug Fixes: + +* Fix backtrace formatter to handle backtraces that are `nil`. + (Myron Marston, rspec/rspec-core#2118) + +### 3.4.0 / 2015-11-11 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.3.2...v3.4.0) + +Enhancements: + +* Combine multiple `--pattern` arguments making them equivalent to + `--pattern=1,2,...,n`. (Jon Rowe, rspec/rspec-core#2002) +* Improve `inspect` and `to_s` output for `RSpec::Core::Example` + objects, replacing Ruby's excessively verbose output. (Gavin Miller, rspec/rspec-core#1922) +* Add `silence_filter_announcements` configuration option. + (David Raffensperger, rspec/rspec-core#2007) +* Add optional `example_finished` notification to the reporter protocol for + when you don't care about the example outcome. (Jon Rowe, rspec/rspec-core#2013) +* Switch `--bisect` to a recursion-based bisection algorithm rather than + a permutation-based one. This better handles cases where an example + depends upon multiple other examples instead of just one and minimizes + the number of runs necessary to determine that an example set cannot be + minimized further. (Simon Coffey, rspec/rspec-core#1997) +* Allow simple filters (e.g. `:symbol` key only) to be triggered by truthey + values. (Tim Mertens, rspec/rspec-core#2035) +* Remove unneeded warning about need for `ansicon` on Windows when using + RSpec's `--color` option. (Ashley Engelund, rspec/rspec-core#2038) +* Add option to configure RSpec to raise errors when issuing warnings. + (Jon Rowe, rspec/rspec-core#2052) +* Append the root `cause` of a failure or error to the printed failure + output when a `cause` is available. (Adam Magan) +* Stop rescuing `NoMemoryError`, `SignalExcepetion`, `Interrupt` and + `SystemExit`. It is dangerous to interfere with these. (Myron Marston, rspec/rspec-core#2063) +* Add `config.project_source_dirs` setting which RSpec uses to determine + if a backtrace line comes from your project source or from some + external library. It defaults to `spec`, `lib` and `app` but can be + configured differently. (Myron Marston, rspec/rspec-core#2088) +* Improve failure line detection so that it looks for the failure line + in any project source directory instead of just in the spec file. + In addition, if no backtrace lines can be found from a project source + file, we fall back to displaying the source of the first backtrace + line. This should virtually eliminate the "Unable to find matching + line from backtrace" messages. (Myron Marston, rspec/rspec-core#2088) +* Add support for `:extra_failure_lines` example metadata that will + be appended to the failure output. (bootstraponline, rspec/rspec-core#2092). +* Add `RSpec::Core::Example#duplicate_with` to produce new examples + with cloned metadata. (bootstraponline, rspec/rspec-core#2098) +* Add `RSpec::Core::Configuration#on_example_group_definition` to register + hooks to be invoked when example groups are created. (bootstraponline, rspec/rspec-core#2094) +* Add `add_example` and `remove_example` to `RSpec::Core::ExampleGroup` to + allow manipulating an example groups examples. (bootstraponline, rspec/rspec-core#2095) +* Display multiline failure source lines in failure output when Ripper is + available (MRI >= 1.9.2, and JRuby >= 1.7.5 && < 9.0.0.0.rc1). + (Yuji Nakayama, rspec/rspec-core#2083) +* Add `max_displayed_failure_line_count` configuration option + (defaults to 10). (Yuji Nakayama, rspec/rspec-core#2083) +* Enhance `fail_fast` option so it can take a number (e.g. `--fail-fast=3`) + to force the run to abort after the specified number of failures. + (Jack Scotti, rspec/rspec-core#2065) +* Syntax highlight the failure snippets in text formatters when `color` + is enabled and the `coderay` gem is installed on a POSIX system. + (Myron Marston, rspec/rspec-core#2109) + +Bug Fixes: + +* Lock `example_status_persistence_file` when reading from and writing + to it to prevent race conditions when multiple processes try to use + it. (Ben Woosley, rspec/rspec-core#2029) +* Fix regression in 3.3 that caused spec file names with square brackets in + them (such as `1[]_spec.rb`) to not be loaded properly. (Myron Marston, rspec/rspec-core#2041) +* Fix output encoding issue caused by ASCII literal on 1.9.3 (Jon Rowe, rspec/rspec-core#2072) +* Fix requires in `rspec/core/rake_task.rb` to avoid double requires + seen by some users. (Myron Marston, rspec/rspec-core#2101) + +### 3.3.2 / 2015-07-15 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.3.1...v3.3.2) + +Bug Fixes: + +* Fix formatters to handle exceptions for which `backtrace` returns `nil`. + (Myron Marston, rspec/rspec-core#2023) +* Fix duplicate formatter detection so that it allows subclasses of formatters + to be added. (Sebastián Tello, rspec/rspec-core#2019) + +### 3.3.1 / 2015-06-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.3.0...v3.3.1) + +Bug Fixes: + +* Correctly run `before(:suite)` (and friends) in the context of an example + group instance, thus making the expected RSpec environment available. + (Jon Rowe, rspec/rspec-core#1986) + +### 3.3.0 / 2015-06-12 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.3...v3.3.0) + +Enhancements: + +* Expose the reporter used to run examples via `RSpec::Core::Example#reporter`. + (Jon Rowe, rspec/rspec-core#1866) +* Make `RSpec::Core::Reporter#message` a public supported API. (Jon Rowe, rspec/rspec-core#1866) +* Allow custom formatter events to be published via + `RSpec::Core::Reporter#publish(event_name, hash_of_attributes)`. (Jon Rowe, rspec/rspec-core#1869) +* Remove dependency on the standard library `Set` and replace with `RSpec::Core::Set`. + (Jon Rowe, rspec/rspec-core#1870) +* Assign a unique id to each example and group so that they can be + uniquely identified, even for shared examples (and similar situations) + where the location isn't unique. (Myron Marston, rspec/rspec-core#1884) +* Use the example id in the rerun command printed for failed examples + when the location is not unique. (Myron Marston, rspec/rspec-core#1884) +* Add `config.example_status_persistence_file_path` option, which is + used to persist the last run status of each example. (Myron Marston, rspec/rspec-core#1888) +* Add `:last_run_status` metadata to each example, which indicates what + happened the last time an example ran. (Myron Marston, rspec/rspec-core#1888) +* Add `--only-failures` CLI option which filters to only the examples + that failed the last time they ran. (Myron Marston, rspec/rspec-core#1888) +* Add `--next-failure` CLI option which allows you to repeatedly focus + on just one of the currently failing examples, then move on to the + next failure, etc. (Myron Marston, rspec/rspec-core#1888) +* Make `--order random` ordering stable, so that when you rerun a + subset with a given seed, the examples will be order consistently + relative to each other. (Myron Marston, rspec/rspec-core#1908) +* Set example group constant earlier so errors when evaluating the context + include the example group name (Myron Marson, rspec/rspec-core#1911) +* Make `let` and `subject` threadsafe. (Josh Cheek, rspec/rspec-core#1858) +* Add version information into the JSON formatter. (Mark Swinson, rspec/rspec-core#1883) +* Add `--bisect` CLI option, which will repeatedly run your suite in + order to isolate the failures to the smallest reproducible case. + (Myron Marston, rspec/rspec-core#1917) +* For `config.include`, `config.extend` and `config.prepend`, apply the + module to previously defined matching example groups. (Eugene Kenny, rspec/rspec-core#1935) +* When invalid options are parsed, notify users where they came from + (e.g. `.rspec` or `~/.rspec` or `ENV['SPEC_OPTS']`) so they can + easily find the source of the problem. (Myron Marston, rspec/rspec-core#1940) +* Add pending message contents to the json formatter output. (Jon Rowe, rspec/rspec-core#1949) +* Add shared group backtrace to the output displayed by the built-in + formatters for pending examples that have been fixed. (Myron Marston, rspec/rspec-core#1946) +* Add support for `:aggregate_failures` metadata. Tag an example or + group with this metadata and it'll use rspec-expectations' + `aggregate_failures` feature to allow multiple failures in an example + and list them all, rather than aborting on the first failure. (Myron + Marston, rspec/rspec-core#1946) +* When no formatter implements #message add a fallback to prevent those + messages being lost. (Jon Rowe, rspec/rspec-core#1980) +* Profiling examples now takes into account time spent in `before(:context)` + hooks. (Denis Laliberté, Jon Rowe, rspec/rspec-core#1971) +* Improve failure output when an example has multiple exceptions, such + as one from an `it` block and one from an `after` block. (Myron Marston, rspec/rspec-core#1985) + +Bug Fixes: + +* Handle invalid UTF-8 strings within exception methods. (Benjamin Fleischer, rspec/rspec-core#1760) +* Fix Rake Task quoting of file names with quotes to work properly on + Windows. (Myron Marston, rspec/rspec-core#1887) +* Fix `RSpec::Core::RakeTask#failure_message` so that it gets printed + when the task failed. (Myron Marston, rspec/rspec-core#1905) +* Make `let` work properly when defined in a shared context that is applied + to an individual example via metadata. (Myron Marston, rspec/rspec-core#1912) +* Ensure `rspec/autorun` respects configuration defaults. (Jon Rowe, rspec/rspec-core#1933) +* Prevent modules overriding example group defined methods when included, + prepended or extended by config defined after an example group. (Eugene Kenny, rspec/rspec-core#1935) +* Fix regression which caused shared examples to be mistakenly run when specs + where filtered to a particular location. (Ben Axnick, rspec/rspec-core#1963) +* Fix time formatting logic so that it displays 70 seconds as "1 minute, + 10 seconds" rather than "1 minute, 1 second". (Paul Brennan, rspec/rspec-core#1984) +* Fix regression where the formatter loader would allow duplicate formatters. + (Jon Rowe, rspec/rspec-core#1990) + +### 3.2.3 / 2015-04-06 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.2...v3.2.3) + +Bug Fixes: + +* Fix how the DSL methods are defined so that RSpec is compatible with + gems that define methods of the same name on `Kernel` (such as + the `its-it` gem). (Alex Kwiatkowski, Ryan Ong, rspec/rspec-core#1907) +* Fix `before(:context) { skip }` so that it does not wrongly cause the + spec suite to exit with a non-zero status when no examples failed. + (Myron Marston, rspec/rspec-core#1926) + +### 3.2.2 / 2015-03-11 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.1...v3.2.2) + +Bug Fixes: + +* Fix regression in 3.2.0 that allowed tag-filtered examples to + run even if there was a location filter applied to the spec + file that was intended to limit the file to other examples. + (rspec/rspec-core#1894, Myron Marston) + +### 3.2.1 / 2015-02-23 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.0...v3.2.1) + +Bug Fixes: + +* Notify start-of-run seed _before_ `start` notification rather than + _after_ so that formatters like Fuubar work properly. (Samuel Esposito, rspec/rspec-core#1882) + +### 3.2.0 / 2015-02-03 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.7...v3.2.0) + +Enhancements: + +* Improve the `inspect` output of example groups. (Mike Dalton, rspec/rspec-core#1687) +* When rake task fails, only output the command if `verbose` flag is + set. (Ben Snape, rspec/rspec-core#1704) +* Add `RSpec.clear_examples` as a clear way to reset examples in between + spec runs, whilst retaining user configuration. (Alexey Fedorov, rspec/rspec-core#1706) +* Reduce string allocations when defining and running examples by 70% + and 50% respectively. (Myron Marston, rspec/rspec-core#1738) +* Removed dependency on pathname from stdlib. (Sam Phippen, rspec/rspec-core#1703) +* Improve the message presented when a user hits Ctrl-C. + (Alex Chaffee rspec/rspec-core#1717, rspec/rspec-core#1742) +* Improve shared example group inclusion backtrace displayed + in failed example output so that it works for all methods + of including shared example groups and shows all inclusion + locations. (Myron Marston, rspec/rspec-core#1763) +* Issue seed notification at start (as well as the end) of the reporter + run. (Arlandis Word, rspec/rspec-core#1761) +* Improve the documentation of around hooks. (Jim Kingdon, rspec/rspec-core#1772) +* Support prepending of modules into example groups from config and allow + filtering based on metadata. (Arlandis Word, rspec/rspec-core#1806) +* Emit warnings when `:suite` hooks are registered on an example group + (where it has always been ignored) or are registered with metadata + (which has always been ignored). (Myron Marston, rspec/rspec-core#1805) +* Provide a friendly error message when users call RSpec example group + APIs (e.g. `context`, `describe`, `it`, `let`, `before`, etc) from + within an example where those APIs are unavailable. (Myron Marston, rspec/rspec-core#1819) +* Provide a friendly error message when users call RSpec example + APIs (e.g. `expect`, `double`, `stub_const`, etc) from + within an example group where those APIs are unavailable. + (Myron Marston, rspec/rspec-core#1819) +* Add new `RSpec::Core::Sandbox.sandboxed { }` API that facilitates + testing RSpec with RSpec, allowing you to define example groups + and example from within an example without affecting the global + `RSpec.world` state. (Tyler Ball, 1808) +* Apply line-number filters only to the files they are scoped to, + allowing you to mix filtered and unfiltered files. (Myron Marston, rspec/rspec-core#1839) +* When dumping pending examples, include the failure details so that you + don't have to un-pend the example to see it. (Myron Marston, rspec/rspec-core#1844) +* Make `-I` option support multiple values when separated by + `File::PATH_SEPARATOR`, such as `rspec -I foo:bar`. This matches + the behavior of Ruby's `-I` option. (Fumiaki Matsushima, rspec/rspec-core#1855). +* Treat each example as having a singleton example group for the + purposes of applying metadata-based features that normally apply + to example groups to individually tagged examples. For example, + `RSpec.shared_context "Uses redis", :uses_redis` will now apply + to individual examples tagged with `:uses_redis`, as will + `config.include RedisHelpers, :uses_redis`, and + `config.before(:context, :uses_redis) { }`, etc. (Myron Marston, rspec/rspec-core#1749) + +Bug Fixes: + +* When assigning generated example descriptions, surface errors + raised by `matcher.description` in the example description. + (Myron Marston, rspec/rspec-core#1771) +* Don't consider expectations from `after` hooks when generating + example descriptions. (Myron Marston, rspec/rspec-core#1771) +* Don't apply metadata-filtered config hooks to examples in groups + with matching metadata when those examples override the parent + metadata value to not match. (Myron Marston, rspec/rspec-core#1796) +* Fix `config.expect_with :minitest` so that `skip` uses RSpec's + implementation rather than Minitest's. (Jonathan Rochkind, rspec/rspec-core#1822) +* Fix `NameError` caused when duplicate example group aliases are defined and + the DSL is not globally exposed. (Aaron Kromer, rspec/rspec-core#1825) +* When a shared example defined in an external file fails, use the host + example group (from a loaded spec file) for the re-run command to + ensure the command will actually work. (Myron Marston, rspec/rspec-core#1835) +* Fix location filtering to work properly for examples defined in + a nested example group within a shared example group defined in + an external file. (Bradley Schaefer, Xavier Shay, Myron Marston, rspec/rspec-core#1837) +* When a pending example fails (as expected) due to a mock expectation, + set `RSpec::Core::Example::ExecutionResult#pending_exception` -- + previously it was not being set but should have been. (Myron Marston, rspec/rspec-core#1844) +* Fix rake task to work when `rspec-core` is installed in a directory + containing a space. (Guido Günther, rspec/rspec-core#1845) +* Fix regression in 3.1 that caused `describe Regexp` to raise errors. + (Durran Jordan, rspec/rspec-core#1853) +* Fix regression in 3.x that caused the profile information to be printed + after the summary. (Max Lincoln, rspec/rspec-core#1857) +* Apply `--seed` before loading `--require` files so that required files + can access the provided seed. (Myron Marston, rspec/rspec-core#1745) +* Handle `RSpec::Core::Formatters::DeprecationFormatter::FileStream` being + reopened with an IO stream, which sometimes happens with spring. + (Kevin Mook, rspec/rspec-core#1757) + +### 3.1.7 / 2014-10-11 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.6...v3.1.7) + +Bug Fixes: + +* Fix `Metadata.relative_path` so that for a current directory of + `/foo/bar`, `/foo/bar_1` is not wrongly converted to `._1`. + (Akos Vandra, rspec/rspec-core#1730) +* Prevent constant lookup mistakenly finding `RSpec::ExampleGroups` generated + constants on 1.9.2 by appending a trailing `_` to the generated names. + (Jon Rowe, rspec/rspec-core#1737) +* Fix bug in `:pending` metadata. If it got set in any way besides passing + it as part of the metadata literal passed to `it` (such as by using + `define_derived_metadata`), it did not have the desired effect, + instead marking the example as `:passed`. (Myron Marston, rspec/rspec-core#1739) + +### 3.1.6 / 2014-10-08 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.5...v3.1.6) + +Bug Fixes: + +* Fix regression in rake task pattern handling, that prevented patterns + that were relative from the current directory rather than from `spec` + from working properly. (Myron Marston, rspec/rspec-core#1734) +* Prevent rake task from generating duplicate load path entries. + (Myron Marston, rspec/rspec-core#1735) + +### 3.1.5 / 2014-09-29 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.4...v3.1.5) + +Bug Fixes: + +* Fix issue with the rake task incorrectly escaping strings on Windows. + (Jon Rowe rspec/rspec-core#1718) +* Support absolute path patterns. While this wasn't officially supported + previously, setting `rake_task.pattern` to an absolute path pattern in + RSpec 3.0 and before worked since it delegated to `FileList` internally + (but now just forwards the pattern on to the `rspec` command). + (Myron Marston, rspec/rspec-core#1726) + +### 3.1.4 / 2014-09-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.3...v3.1.4) + +Bug Fixes: + +* Fix implicit `subject` when using `describe false` or `describe nil` + so that it returns the provided primitive rather than the string + representation. (Myron Marston, rspec/rspec-core#1710) +* Fix backtrace filtering to allow code in subdirectories of your + current working directory (such as vendor/bundle/...) to be filtered + from backtraces. (Myron Marston, rspec/rspec-core#1708) + +### 3.1.3 / 2014-09-15 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.2...v3.1.3) + +Bug Fixes: + +* Fix yet another regression in rake task pattern handling, to allow + `task.pattern = FileList["..."]` to work. That was never intended + to be supported but accidentally worked in 3.0 and earlier. + (Myron Marston, rspec/rspec-core#1701) +* Fix pattern handling so that files are normalized to absolute paths + before subtracting the `--exclude-pattern` matched files from the + `--pattern` matched files so that it still works even if the patterns + are in slightly different forms (e.g. one starting with `./`). + (Christian Nelson, rspec/rspec-core#1698) + +### 3.1.2 / 2014-09-08 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.1...v3.1.2) + +Bug Fixes: + +* Fix another regression in rake task pattern handling, so that patterns + that start with `./` still work. (Christian Nelson, rspec/rspec-core#1696) + +### 3.1.1 / 2014-09-05 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.0...v3.1.1) + +Bug Fixes: + +* Fix a regression in rake task pattern handling, so that `rake_task.pattern = array` + works again. While we never intended to support array values (or even knew that worked!), + the implementation from 3.0 and earlier used `FileList` internally, which allows arrays. + The fix restores the old behavior. (Myron Marston, rspec/rspec-core#1694) + +### 3.1.0 / 2014-09-04 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.4...v3.1.0) + +Enhancements: + +* Update files generated by `rspec --init` so that warnings are enabled + in commented out section of `spec_helper` rather than `.rspec` so users + have to consciously opt-in to the setting. (Andrew Hooker, rspec/rspec-core#1572) +* Update `spec_helper` generated by `rspec --init` so that it sets the new + rspec-expectations `include_chain_clauses_in_custom_matcher_descriptions` + config option (which will be on by default in RSpec 4) and also sets the + rspec-mocks `verify_partial_doubles` option (which will also default + to on in RSpec 4). (Myron Marston, rspec/rspec-core#1647) +* Provide an `inspect` output for example procsy objects (used in around + hooks) that doesn't make them look like procs. (Jon Rowe, rspec/rspec-core#1620) +* Remove a few unneeded `require` statements from + `rspec/core/rake_task.rb`, making it even more lighterweight. + (Myron Marston, rspec/rspec-core#1640) +* Allow rspec-core to be used when neither rspec-mocks or + rspec-expectations are installed, without requiring any + user configuration. (Sam Phippen, Myron Marston, rspec/rspec-core#1615) +* Don't filter out gems from backtraces by default. (The RSpec + gems will still be filtered). User feedback has indicated + that including gems in default backtraces will be useful. + (Myron Marston, rspec/rspec-core#1641) +* Add new `config.filter_gems_from_backtrace "rack", "rake"` API + to easily filter the named gems from backtraces. (Myron Marston, rspec/rspec-core#1682) +* Fix default backtrace filters so that the RSpec binary is + excluded when installing RSpec as a bundler `:git` dependency. + (Myron Marston, rspec/rspec-core#1648) +* Simplify command generated by the rake task so that it no longer + includes unnecessary `-S`. (Myron Marston, rspec/rspec-core#1559) +* Add `--exclude-pattern` CLI option, `config.exclude_pattern =` config + option and `task.exclude_pattern =` rake task config option. Matching + files will be excluded. (John Gesimondo, Myron Marston, rspec/rspec-core#1651, rspec/rspec-core#1671) +* When an around hook fails to execute the example, mark it as + pending (rather than passing) so the user is made aware of the + fact that the example did not actually run. (Myron Marston, rspec/rspec-core#1660) +* Remove dependency on `FileUtils` from the standard library so that users do + not get false positives where their code relies on it but they are not + requiring it. (Sam Phippen, rspec/rspec-core#1565) + +Bug Fixes: + +* Fix rake task `t.pattern =` option so that it does not run all specs + when it matches no files, by passing along a `--pattern` option to + the `rspec` command, rather than resolving the file list and passing + along the files individually. (Evgeny Zislis, rspec/rspec-core#1653) +* Fix rake task default pattern so that it follows symlinks properly. + (Myron Marston, rspec/rspec-core#1672) +* Fix default pattern used with `rspec` command so that it follows + symlinks properly. (Myron Marston, rspec/rspec-core#1672) +* Change how we assign constant names to example group classes so that + it avoids a problem with `describe "Core"`. (Daniela Wellisz, rspec/rspec-core#1679) +* Handle rendering exceptions that have a different encoding than that + of their original source file. (Jon Rowe, rspec/rspec-core#1681) +* Allow access to message_lines without colour for failed examples even + when they're part of a shared example group. (tomykaira, rspec/rspec-core#1689) + +### 3.0.4 / 2014-08-14 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.3...v3.0.4) + +Bug Fixes: + +* Fix processing order of CLI options so that if `config.files_to_run` + is accessed from a file loaded by `--require`, `--pattern` is still + applied. (Myron Marston, rspec/rspec-core#1652) +* Fix `config.pattern=` so that it still takes affect even if + `config.files_to_run` has already been accessed. (Myron Marston, rspec/rspec-core#1652) + +### 3.0.3 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.2...v3.0.3) + +Bug Fixes: + +* Properly convert both parts of a description into strings before + concatenation. (@nicklink483, rspec/rspec-core#1636) +* Exclude the working directory when figuring out folders to ignore. + (Jon Rowe, Myron Marston, rspec/rspec-core#1616) +* Allow `::RSpec::Core::Notifications::FailedExampleNotification#message_lines` + to be accessed without a colouriser. (@tomykaira, rspec/rspec-core#1637) + +### 3.0.2 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.1...v3.0.2) + +Bug Fixes: + +* Fix regression in CLI option handling that prevented `--tag slow` + passed at the command line from overriding `--tag ~slow` in `.rspec`. + (Colin Jones, rspec/rspec-core#1602) +* Fix metadata `:example_group` deprecation warning so that it gets + issued at the call site of the configuration that specified it as + a filter rather than later when an example group is defined. + (Myron Marston, rspec/rspec-core#1562) +* Make the line that is printed when a shared example group fails indicating + where the concrete example group is white, separating it from the stack trace + that is produced for the failure. (Sam Phippen, Jon Rowe, rspec/rspec-core#1606) + +### 3.0.1 / 2014-06-12 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0...v3.0.1) + +Bug Fixes: + +* Fix a couple ruby warnings caused by rspec-core when loaded. + (Prem Sichanugrist, rspec/rspec-core#1584) +* Example groups named `Config` will no longer cause a Ruby warning to be + issued. (Jimmy Cuadra, rspec/rspec-core#1580) + +### 3.0.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.rc1...v3.0.0) + +Bug Fixes: + +* Fix `BaseTextFormatter` so that it does not re-close a closed output + stream. (Myron Marston) +* Fix regression in metadata that caused the metadata hash of a top-level + example group to have a `:parent_example_group` key even though it has + no parent example group. (Myron Marston) + +Enhancements: + +* Alter the default `spec_helper.rb` to no longer recommend + `config.full_backtrace = true` see rspec/rspec-core#1536 for discussion. (Jon Rowe) + +### 3.0.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.beta2...v3.0.0.rc1) + +Breaking Changes for 3.0.0: + +* Change `described_class` so that in a nested group like `describe + MyClass`, it returns `MyClass` rather than the outer group's described + class. (Myron Marston) +* Refactor filter manager so that it no longer subclasses Hash and has a + tighter, more domain-specific interface. (Sergey Pchelincev) +* Remove legacy colours definitions from `BaseTextFormatter`. (Jon Rowe) +* Remove console color definitions from `BaseTextFormatter`. (Jon Rowe) +* Restructure example group metadata so that the computed keys are + exposed directly off of the metadata hash rather than being on + a nested `:example_group` subhash. In addition, the parent example + group metadata is now available as `[:parent_example_group]` rather + than `[:example_group][:example_group]`. Deprecated access via the + old key structure is still provided. (Myron Marston) +* Remove `:describes` metadata key. It duplicates `:described_class` + for no good reason. Deprecated access via `:describes` is still + provided. (Myron Marston) +* Rename `:example_group_block` metadata key to `:block`. + (Myron Marston) +* Remove deprecated `RSpec::Core::Example#options`. (Myron Marston) +* Move `BaseTextFormatter#colorize_summary` to `SummaryNotification#colorize_with` + (Jon Rowe). +* `describe some_hash` treated `some_hash` as metadata in RSpec 2.x but + will treat it as the described object in RSpec 3.0. Metadata must + always come after the description args. (Myron Marston) +* Remove deprecated `display_name` alias of `ExampleGroup.description`. + (Myron Marston) +* Remove deprecated `describes` alias of `ExampleGroup.described_class`. + (Myron Marston) +* Remove deprecated `RSpec::Core::ExampleGroup.alias_it_behaves_like_to`. + Use `RSpec::Core::Configuration#alias_it_behaves_like_to` instead. + (Myron Marston) +* Remove deprecated `RSpec::Core::ExampleGroup.alias_example_to`. + Use `RSpec::Core::Configuration#alias_example_to` instead. + (Myron Marston) +* Removed `focused` example alias and change example/group aliases + `fit`, `focus`, `fcontext` and `fdescribe` to no longer include + `:focused => true` metadata. They only contain `:focus => true` + metadata now. This means that you will need to filter them with + `filter_run :focus`, not `filter_run :focused`. (Myron Marston) +* Remove `--line-number` filtering. It's semantically dubious since it's + a global filter (potentially applied to multiple files) but there's no + meaningful connection between the same line number in multiple files. + Instead use the `rspec path/to/spec.rb:23:46` form, which is terser + and makes more sense as it is scoped to a file. (Myron Marston) +* Remove `--default_path` as an alias for `--default-path`. (Jon Rowe) +* Remove deprecated `share_examples_for`. There's still + `shared_examples` and `shared_examples_for`. (Myron Marston) +* Rename `RSpec::Core::Configuration#warnings` to + `RSpec::Core::Configuration#warnings?` since it's a boolean flag. + (Myron Marston) +* RSpec's global state is no longer reset after a spec run. This gives + more flexibility to alternate runners to decide when and if they + want the state reset. Alternate runners are now responsible for + calling this (or doing a similar reset) if they are going to run + the spec suite multiple times in the same process. (Sam Phippen) +* Merge `RSpec::Core::CommandLine` (never formally declared public) + into `RSpec::Core::Runner`. (Myron Marston) +* Remove `color_enabled` as an alias of `color`. (Jon Rowe) +* Remove `backtrace_cleaner` as an alias of `backtrace_formatter`. (Jon Rowe) +* Remove `filename_pattern` as an alias of `pattern`. (Jon Rowe) +* Extract support for legacy formatters to `rspec-legacy_formatters`. (Jon Rowe) +* `RSpec::Configuration#formatters` now returns a dup to prevent mutation. (Jon Rowe) +* Replace `stdlib` as an available expectation framework with `test_unit` and + `minitest`. (Aaron Kromer) +* Remove backtrace formatting helpers from `BaseTextFormatter`. (Jon Rowe) +* Extract profiler support to `ProfileFormatter` and `ProfileNotification`. + Formatters should implement `dump_profile` if they wish to respond to `--profile`. + (Jon Rowe) +* Extract remaining formatter state to reporter and notifications. Introduce + `ExamplesNotification` to share information about examples that was previously + held in `BaseFormatter`. (Jon Rowe) + +Enhancements: + +* Add `config.default_formatter` attribute, which can be used to set a + formatter which will only be used if no other formatter is set + (e.g. via `--formatter`). (Myron Marston) +* Support legacy colour definitions in `LegacyFormatterAdaptor`. (Jon Rowe) +* Migrate `execution_result` (exposed by metadata) from a hash to a + first-class object with appropriate attributes. `status` is now + stored and returned as a symbol rather than a string. It retains + deprecated hash behavior for backwards compatibility. (Myron Marston) +* Provide console code helper for formatters. (Jon Rowe) +* Use raw ruby hashes for the metadata hashes rather than a subclass of + a hash. Computed metadata entries are now computed in advance rather + than being done lazily on first access. (Myron Marston) +* Add `:block` metadata entry to the example metadata, bringing + parity with `:block` in the example group metadata. (Myron Marston) +* Add `fspecify` and `fexample` as aliases of `specify` and `example` + with `:focus => true` metadata for parity with `fit`. (Myron Marston) +* Add legacy support for `colorize_summary`. (Jon Rowe) +* Restructure runner so it can be more easily customized in a subclass + for an alternate runner. (Ben Hoskings) +* Document `RSpec::Core::ConfigurationOptions` as an officially + supported public API. (Myron Marston) +* Add `--deprecation-out` CLI option which directs deprecation warnings + to the named file. (Myron Marston) +* Minitest 5 compatability for `expect_with :stdlib` (now available as + `expect_with :minitest`). (Xavier Shay) +* Reporter now notifies formatters of the load time of RSpec and your + specs via `StartNotification` and `SummaryNotification`. (Jon Rowe) +* Add `disable_monkey_patching!` config option that disables all monkey + patching from whatever pieces of RSpec you use. (Alexey Fedorov) +* Add `Pathname` support for setting all output streams. (Aaron Kromer) +* Add `config.define_derived_metadata`, which can be used to apply + additional metadata to all groups or examples that match a given + filter. (Myron Marston) +* Provide formatted and colorized backtraces via `FailedExampleNotification` + and send `PendingExampleFixedNotifications` when the error is due to a + passing spec you expect to fail. (Jon Rowe) +* Add `dump_profile` to formatter API to allow formatters to implement + support for `--profile`. (Jon Rowe) +* Allow colourising text via `ConsoleCodes` with RSpec 'states' + (e.g. `:success`, `:failure`) rather than direct colour codes. (Jon Rowe) +* Expose `fully_formatted` methods off the formatter notification objects + that make it easy for a custom formatter to produce formatted output + like rspec-core's. (Myron Marston) + +Bug Fixes: + +* Fix `spec_helper.rb` file generated by `rspec --init` so that the + recommended settings correctly use the documentation formatter + when running one file. (Myron Marston) +* Fix ordering problem where descriptions were generated after + tearing down mocks, which resulted in unexpected exceptions. + (Bradley Schaefer, Aaron Kromer, Andrey Savchenko) +* Allow a symbol to be used as an implicit subject (e.g. `describe + :foo`). (Myron Marston) +* Prevent creating an isolated context (i.e. using `RSpec.describe`) when + already inside a context. There is no reason to do this, and it could + potentially cause unexpected bugs. (Xavier Shay) +* Fix shared example group scoping so that when two shared example + groups share the same name at different levels of nested contexts, + the one in the nearest context is used. (Myron Marston) +* Fix `--warnings` option so that it enables warnings immediately so + that it applies to files loaded by `--require`. (Myron Marston) +* Issue a warning when you set `config.deprecation_stream` too late for + it to take effect because the reporter has already been setup. (Myron Marston) +* Add the full `RSpec::Core::Example` interface to the argument yielded + to `around` hooks. (Myron Marston) +* Line number always takes precendence when running specs with filters. + (Xavier Shay) +* Ensure :if and :unless metadata filters are treated as a special case + and are always in-effect. (Bradley Schaefer) +* Ensure the currently running installation of RSpec is used when + the rake task shells out to `rspec`, even if a newer version is also + installed. (Postmodern) +* Using a legacy formatter as default no longer causes an infinite loop. + (Xavier Shay) + +### 3.0.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.beta1...v3.0.0.beta2) + +Breaking Changes for 3.0.0: + +* Make `mock_with` option more strict. Strings are no longer supported + (e.g. `mock_with "mocha"`) -- use a symbol instead. Also, unrecognized + values will now result in an error rather than falling back to the + null mocking adapter. If you want to use the null mocking adapter, + use `mock_with :nothing` (as has been documented for a long time). + (Myron Marston) +* Remove support for overriding RSpec's built-in `:if` and `:unless` + filters. (Ashish Dixit) +* Custom formatters are now required to call + `RSpec::Core::Formatters.register(formatter_class, *notifications)` + where `notifications` is the list of events the formatter wishes to + be notified about. Notifications are handled by methods matching the + names on formatters. This allows us to add or remove notifications + without breaking existing formatters. (Jon Rowe) +* Change arguments passed to formatters. Rather than passing multiple + arguments (which limits are ability to add additional arguments as + doing so would break existing formatters), we now pass a notification + value object that exposes the same data via attributes. This will + allow us to add new bits of data to a notification event without + breaking existing formatters. (Jon Rowe) +* Remove support for deprecated `:alias` option for + `RSpec.configuration.add_setting`. (Myron Marston) +* Remove support for deprecated `RSpec.configuration.requires = [...]`. + (Myron Marston) +* Remove support for deprecated `--formatter` CLI option. (Myron Marston) +* Remove support for deprecated `--configure` CLI option. (Myron Marston) +* Remove support for deprecated `RSpec::Core::RakeTask#spec_opts=`. + (Myron Marston) +* An example group level `pending` block or `:pending` metadata now executes + the example and cause a failure if it passes, otherwise it will be pending if + it fails. The old "never run" behaviour is still used for `xexample`, `xit`, + and `xspecify`, or via a new `skip` method or `:skip` metadata option. + (Xavier Shay) +* After calling `pending` inside an example, the remainder of the example will + now be run. If it passes a failure is raised, otherwise the example is marked + pending. The old "never run" behaviour is provided a by a new `skip` method. + (Xavier Shay) +* Pending blocks inside an example have been removed as a feature with no + direct replacement. Use `skip` or `pending` without a block. (Xavier Shay) +* Pending statement is no longer allowed in `before(:all)` hooks. Use `skip` + instead. (Xavier Shay) +* Remove `show_failures_in_pending_blocks` configuration option. (Xavier Shay) +* Remove support for specifying the documentation formatter using + 's', 'n', 'spec' or 'nested'. (Jon Rowe) + +Enhancements: + +* Add example run time to JSON formatter output. (Karthik Kastury) +* Add more suggested settings to the files generated by + `rspec --init`. (Myron Marston) +* Add `config.alias_example_group_to`, which can be used to define a + new method that defines an example group with the provided metadata. + (Michi Huber) +* Add `xdescribe` and `xcontext` as shortcuts to skip an example group. + (Myron Marston) +* Add `fdescribe` and `fcontext` as shortcuts to focus an example group. + (Myron Marston) +* Don't autorun specs via `#at_exit` by default. `require 'rspec/autorun'` + is only needed when running specs via `ruby`, as it always has been. + Running specs via `rake` or `rspec` are both unaffected. (Ben Hoskings) +* Add `expose_dsl_globally` config option, defaulting to true. When disabled + it will remove the monkey patches rspec-core adds to `main` and `Module` + (e.g. `describe`, `shared_examples_for`, etc). (Jon Rowe) +* Expose RSpec DSL entry point methods (`describe`, + `shared_examples_for`, etc) on the `RSpec` constant. Intended for use + when `expose_dsl_globally` is set to `false`. (Jon Rowe) +* For consistency, expose all example group aliases (including + `context`) on the `RSpec` constant. If `expose_dsl_globally` is set to + `true`, also expose them on `main` and `Module`. Historically, only `describe` + was exposed. (Jon Rowe, Michi Huber) +* Add hook scope `:example` as an alias for `:each`, and `:context` as an alias + for `:all`. (John Feminella) + +Bug Fixes: + +* Fix failure (undefined method `path`) in end-of-run summary + when `raise_errors_for_deprecations!` is configured. (Myron Marston) +* Issue error when attempting to use `-i` or `--I` on command line, + too close to `-I` to be considered short hand for `--init`. (Jon Rowe) +* Prevent adding formatters to an output target if the same + formatter has already been added to that output. (Alex Peattie) +* Allow a matcher-generated example description to be used when + the example is pending. (Myron Marston) +* Ensure the configured `failure_exit_code` is used by the rake + task when there is a failure. (Jon Rowe) +* Restore behaviour whereby system exclusion filters take priority over working + directory (was broken in beta1). (Jon Rowe) +* Prevent RSpec mangling file names that have substrings containing `line_number` + or `default_path`. (Matijs van Zuijlen) +* Fix failure line detection so that it handles relative file paths + (which can happen when running specs through `ruby` using `rspec/autorun`). + (Myron Marston, rspec/rspec-core#1829) + +### 3.0.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.1...v3.0.0.beta1) + +Breaking Changes for 3.0.0: + +* Remove explicit support for 1.8.6. (Jon Rowe) +* Remove `RSpec::Core::ExampleGroup#example` and + `RSpec::Core::ExampleGroup#running_example` methods. If you need + access to the example (e.g. to get its metadata), use a block arg + instead. (David Chelimsky) +* Remove `TextMateFormatter`, it has been moved to `rspec-tmbundle`. + (Aaron Kromer) +* Remove RCov integration. (Jon Rowe) +* Remove deprecated support for RSpec 1 constructs (Myron Marston): + * The `Spec` and `Rspec` constants (rather than `RSpec`). + * `Spec::Runner.configure` rather than `RSpec.configure`. + * `Rake::SpecTask` rather than `RSpec::Core::RakeTask`. +* Remove deprecated support for `share_as`. (Myron Marston) +* Remove `--debug` option (and corresponding option on + `RSpec::Core::Configuration`). Instead, use `-r` to + load whichever debugger gem you wish to use (e.g. `ruby-debug`, + `debugger`, or `pry`). (Myron Marston) +* Extract Autotest support to a seperate gem. (Jon Rowe) +* Raise an error when a `let` or `subject` declaration is + accessed in a `before(:all)` or `after(:all)` hook. (Myron Marston) +* Extract `its` support to a separate gem. (Peter Alfvin) +* Disallow use of a shared example group from sibling contexts, making them + fully isolated. 2.14 and 2.99 allowed this but printed a deprecation warning. + (Jon Rowe) +* Remove `RSpec::Core::Configuration#output` and + `RSpec::Core::Configuration#out` aliases of + `RSpec::Core::Configuration#output_stream`. (Myron Marston) +* Remove legacy ordering APIs deprecated in 2.99.0.beta1. (Myron + Marston) + +Enhancements: + +* Replace unmaintained syntax gem with coderay gem. (Xavier Shay) +* Times in profile output are now bold instead of `failure_color`. + (Matthew Boedicker) +* Add `--no-fail-fast` command line option. (Gonzalo Rodríguez-Baltanás Díaz) +* Runner now considers the local system ip address when running under Drb. + (Adrian CB) +* JsonFormatter now includes `--profile` information. (Alex / @MasterLambaster) +* Always treat symbols passed as metadata args as hash + keys with true values. RSpec 2 supported this with the + `treat_symbols_as_metadata_keys_with_true_values` but + now this behavior is always enabled. (Myron Marston) +* Add `--dry-run` option, which prints the formatter output + of your suite without running any examples or hooks. + (Thomas Stratmann, Myron Marston) +* Document the configuration options and default values in the `spec_helper.rb` + file that is generated by RSpec. (Parker Selbert) +* Give generated example group classes a friendly name derived + from the docstring, rather than something like "Nested_2". + (Myron Marston) +* Avoid affecting randomization of user code when shuffling + examples so that users can count on their own seeds + working. (Travis Herrick) +* Ordering is no longer a single global property of the test suite. + Each group can pick an ordering using `:order` metadata. (Andy + Lindeman, Sam Phippen, Myron Marston) +* Allow named custom ordering strategies to be registered, which can + then be used on individual example groups. (Andy Lindeman, Sam + Phippen, Myron Marston) + +Deprecations: + +* `treat_symbols_as_metadata_keys_with_true_values` is deprecated and no + longer has an affect now that the behavior it enabled is always + enabled. (Myron Marston) + +### 2.99.2 / 2014-08-19 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.1...v2.99.2) + +Enhancements: + +* Improve deprecation warning for RSpec 3 change in `describe ` + behavior. (Jon Rowe, rspec/rspec-core#1667) + +### 2.99.1 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0...v2.99.1) + +Bug Fixes: + +* Add missing deprecation warning for when `RSpec::Core::Runner` is used + multiple times in the same process. In 2.x RSpec's global state was + automatically cleared between runs but in 3.0 you need to call `RSpec.reset` + manually in these situations. (Sam Phippen, rspec/rspec-core#1587) +* Prevent deprecation being accidentally issues when doubles used with `be_` + matchers due to automatically generated descriptions. (Jon Rowe, rspec/rspec-core#1573) +* Load `rspec/core` when loading `rspec/core/rake_task` to ensure we can + issue deprecations correctly. (Jon Rowe, rspec/rspec-core#1612) + +### 2.99.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.rc1...v2.99.0) + +Bug Fixes: + +* Fix `BaseTextFormatter` so that it does not re-close a closed output + stream. (Myron Marston) +* Use `RSpec::Configuration#backtrace_exclusion_patterns` rather than the + deprecated `RSpec::Configuration#backtrace_clean_patterns` when mocking + with rr. (David Dollar) + +### 2.99.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.beta2...v2.99.0.rc1) + +Enhancements: + +* Add `--deprecation-out` CLI option which directs deprecation warnings + to the named file. (Myron Marston) +* Backport support for `skip` in metadata to skip execution of an example. + (Xavier Shay, rspec/rspec-core#1472) +* Add `Pathname` support for setting all output streams. (Aaron Kromer) +* Add `test_unit` and `minitest` expectation frameworks. (Aaron Kromer) + +Deprecations: + +* Deprecate `RSpec::Core::Pending::PendingDeclaredInExample`, use + `SkipDeclaredInExample` instead. (Xavier Shay) +* Issue a deprecation when `described_class` is accessed from within + a nested `describe ` example group, since `described_class` + will return the innermost described class in RSpec 3 rather than the + outermost described class, as it behaved in RSpec 2. (Myron Marston) +* Deprecate `RSpec::Core::FilterManager::DEFAULT_EXCLUSIONS`, + `RSpec::Core::FilterManager::STANDALONE_FILTERS` and use of + `#empty_without_conditional_filters?` on those filters. (Sergey Pchelincev) +* Deprecate `RSpec::Core::Example#options` in favor of + `RSpec::Core::Example#metadata`. (Myron Marston) +* Issue warning when passing a symbol or hash to `describe` or `context` + as the first argument. In RSpec 2.x this would be treated as metadata + but in RSpec 3 it'll be treated as the described object. To continue + having it treated as metadata, pass a description before the symbol or + hash. (Myron Marston) +* Deprecate `RSpec::Core::BaseTextFormatter::VT100_COLORS` and + `RSpec::Core::BaseTextFormatter::VT100_COLOR_CODES` in favour + of `RSpec::Core::BaseTextFormatter::ConsoleCodes::VT100_CODES` and + `RSpec::Core::BaseTextFormatter::ConsoleCodes::VT100_CODE_VALUES`. + (Jon Rowe) +* Deprecate `RSpec::Core::ExampleGroup.display_name` in favor of + `RSpec::Core::ExampleGroup.description`. (Myron Marston) +* Deprecate `RSpec::Core::ExampleGroup.describes` in favor of + `RSpec::Core::ExampleGroup.described_class`. (Myron Marston) +* Deprecate `RSpec::Core::ExampleGroup.alias_example_to` in favor of + `RSpec::Core::Configuration#alias_example_to`. (Myron Marston) +* Deprecate `RSpec::Core::ExampleGroup.alias_it_behaves_like_to` in favor + of `RSpec::Core::Configuration#alias_it_behaves_like_to`. (Myron Marston) +* Deprecate `RSpec::Core::ExampleGroup.focused` in favor of + `RSpec::Core::ExampleGroup.focus`. (Myron Marston) +* Add deprecation warning for `config.filter_run :focused` since + example aliases `fit` and `focus` will no longer include + `:focused` metadata but will continue to include `:focus`. (Myron Marston) +* Deprecate filtering by `:line_number` (e.g. `--line-number` from the + CLI). Use location filtering instead. (Myron Marston) +* Deprecate `--default_path` as an alternative to `--default-path`. (Jon Rowe) +* Deprecate `RSpec::Core::Configuration#warnings` in favor of + `RSpec::Core::Configuration#warnings?`. (Myron Marston) +* Deprecate `share_examples_for` in favor of `shared_examples_for` or + just `shared_examples`. (Myron Marston) +* Deprecate `RSpec::Core::CommandLine` in favor of + `RSpec::Core::Runner`. (Myron Marston) +* Deprecate `#color_enabled`, `#color_enabled=` and `#color?` in favour of + `#color`, `#color=` and `#color_enabled? output`. (Jon Rowe) +* Deprecate `#filename_pattern` in favour of `#pattern`. (Jon Rowe) +* Deprecate `#backtrace_cleaner` in favour of `#backtrace_formatter`. (Jon Rowe) +* Deprecate mutating `RSpec::Configuration#formatters`. (Jon Rowe) +* Deprecate `stdlib` as an available expectation framework in favour of + `test_unit` and `minitest`. (Aaron Kromer) + +Bug Fixes: + +* Issue a warning when you set `config.deprecation_stream` too late for + it to take effect because the reporter has already been setup. (Myron Marston) +* `skip` with a block should not execute the block. (Xavier Shay) + +### 2.99.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.beta1...v2.99.0.beta2) + +Enhancements: + +* Add `is_expected` for one-liners that read well with the + `expect`-based syntax. `is_expected` is simply defined as + `expect(subject)` and can be used in an expression like: + `it { is_expected.to read_well }`. (Myron Marston) +* Backport `skip` from RSpec 3, which acts like `pending` did in RSpec 2 + when not given a block, since the behavior of `pending` is changing in + RSpec 3. (Xavier Shay) + +Deprecations: + +* Deprecate inexact `mock_with` config options. RSpec 3 will only support + the exact symbols `:rspec`, `:mocha`, `:flexmock`, `:rr` or `:nothing` + (or any module that implements the adapter interface). RSpec 2 did + fuzzy matching but this will not be supported going forward. + (Myron Marston) +* Deprecate `show_failures_in_pending_blocks` config option. To achieve + the same behavior as the option enabled, you can use a custom + formatter instead. (Xavier Shay) +* Add a deprecation warning for the fact that the behavior of `pending` + is changing in RSpec 3 -- rather than skipping the example (as it did + in 2.x when no block was provided), it will run the example and mark + it as failed if no exception is raised. Use `skip` instead to preserve + the old behavior. (Xavier Shay) +* Deprecate 's', 'n', 'spec' and 'nested' as aliases for documentation + formatter. (Jon Rowe) +* Deprecate `RSpec::Core::Reporter#abort` in favor of + `RSpec::Core::Reporter#finish`. (Jon Rowe) + +Bug Fixes: + +* Fix failure (undefined method `path`) in end-of-run summary + when `raise_errors_for_deprecations!` is configured. (Myron Marston) +* Fix issue were overridding spec ordering from the command line wasn't + fully recognised interally. (Jon Rowe) + +### 2.99.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.7...v2.99.0.beta1) + +Enhancements + +* Block-based DSL methods that run in the context of an example + (`it`, `before(:each)`, `after(:each)`, `let` and `subject`) + now yield the example as a block argument. (David Chelimsky) +* Warn when the name of more than one example group is submitted to + `include_examples` and it's aliases. (David Chelimsky) +* Add `expose_current_running_example_as` config option for + use during the upgrade process when external gems use the + deprecated `RSpec::Core::ExampleGroup#example` and + `RSpec::Core::ExampleGroup#running_example` methods. (Myron Marston) +* Limit spamminess of deprecation messages. (Bradley Schaefer, Loren Segal) +* Add `config.raise_errors_for_deprecations!` option, which turns + deprecations warnings into errors to surface the full backtrace + of the call site. (Myron Marston) + +Deprecations + +* Deprecate `RSpec::Core::ExampleGroup#example` and + `RSpec::Core::ExampleGroup#running_example` methods. If you need + access to the example (e.g. to get its metadata), use a block argument + instead. (David Chelimsky) +* Deprecate use of `autotest/rspec2` in favour of `rspec-autotest`. (Jon Rowe) +* Deprecate RSpec's built-in debugger support. Use a CLI option like + `-rruby-debug` (for the ruby-debug gem) or `-rdebugger` (for the + debugger gem) instead. (Myron Marston) +* Deprecate `RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values = false`. + RSpec 3 will not support having this option set to `false`. (Myron Marston) +* Deprecate accessing a `let` or `subject` declaration in + a `after(:all)` hook. (Myron Marston, Jon Rowe) +* Deprecate built-in `its` usage in favor of `rspec-its` gem due to planned + removal in RSpec 3. (Peter Alfvin) +* Deprecate `RSpec::Core::PendingExampleFixedError` in favor of + `RSpec::Core::Pending::PendingExampleFixedError`. (Myron Marston) +* Deprecate `RSpec::Core::Configuration#out` and + `RSpec::Core::Configuration#output` in favor of + `RSpec::Core::Configuration#output_stream`. (Myron Marston) +* Deprecate legacy ordering APIs. + * You should use `register_ordering(:global)` instead of these: + * `RSpec::Core::Configuration#order_examples` + * `RSpec::Core::Configuration#order_groups` + * `RSpec::Core::Configuration#order_groups_and_examples` + * These are deprecated with no replacement because in RSpec 3 + ordering is a property of individual example groups rather than + just a global property of the entire test suite: + * `RSpec::Core::Configuration#order` + * `RSpec::Core::Configuration#randomize?` + * `--order default` is deprecated in favor of `--order defined` + (Myron Marston) + +### 2.14.8 / 2014-02-27 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.7...v2.14.8) + +Bug fixes: + +* Fix regression with the `textmateformatter` that prevented backtrace links + from being clickable. (Stefan Daschek) + +### 2.14.7 / 2013-10-29 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.6...v2.14.7) + +Bug fixes: + +* Fix regression in 2.14.6 that broke the Fivemat formatter. + It depended upon either + `example.execution_result[:exception].pending_fixed?` (which + was removed in 2.14.6 to fix an issue with frozen error objects) + or `RSpec::Core::PendingExampleFixedError` (which was renamed + to `RSpec::Core::Pending::PendingExampleFixedError` in 2.8. + This fix makes a constant alias for the old error name. + (Myron Marston) + +### 2.14.6 / 2013-10-15 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.5...v2.14.6) + +Bug fixes: + +* Format stringified numbers correctly when mathn library is loaded. + (Jay Hayes) +* Fix an issue that prevented the use of frozen error objects. (Lars + Gierth) + +### 2.14.5 / 2013-08-13 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.4...v2.14.5) + +Bug fixes: + +* Fix a `NoMethodError` that was being raised when there were no shared + examples or contexts declared and `RSpec.world.reset` is invoked. + (thepoho, Jon Rowe, Myron Marston) +* Fix a deprecation warning that was being incorrectly displayed when + `shared_examples` are declared at top level in a `module` scope. + (Jon Rowe) +* Fix after(:all) hooks so consecutive (same context) scopes will run even if + one raises an error. (Jon Rowe, Trejkaz) +* JsonFormatter no longer dies if `dump_profile` isn't defined (Alex / @MasterLambaster, Jon Rowe) + +### 2.14.4 / 2013-07-21 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.3...v2.14.4) + +Bug fixes + +* Fix regression in 2.14: ensure configured requires (via `-r` option) + are loaded before spec files are loaded. This allows the spec files + to programatically change the file pattern (Jon Rowe). +* Autoload `RSpec::Mocks` and `RSpec::Expectations` when referenced if + they are not already loaded (`RSpec::Matches` has been autoloaded + for a while). In the `rspec` gem, we changed it recently to stop + loading `rspec/mocks` and `rspec/expectations` by default, as some + users reported problems where they were intending to use mocha, + not rspec-mocks, but rspec-mocks was loaded and causing a conflict. + rspec-core loads mocks and expectations at the appropriate time, so + it seemed like a safe change -- but caused a problem for some authors + of libraries that integrate with RSpec. This fixes that problem. + (Myron Marston) +* Gracefully handle a command like `rspec --profile path/to/spec.rb`: + the `path/to/spec.rb` arg was being wrongly treated as the `profile` + integer arg, which got cast `0` using `to_i`, causing no profiled + examples to be printed. (Jon Rowe) + +### 2.14.3 / 2013-07-13 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.2...v2.14.3) + +Bug fixes + +* Fix deprecation notices issued from `RSpec::Core::RakeTask` so + that they work properly when all of rspec-core is not loaded. + (This was a regression in 2.14) (Jon Rowe) + +### 2.14.2 / 2013-07-09 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.1...v2.14.2) + +Bug fixes + +* Fix regression caused by 2.14.1 release: formatters that + report that they `respond_to?` a notification, but had + no corresponding method would raise an error when registered. + The new fix is to just implement `start` on the deprecation + formatter to fix the original JRuby/ruby-debug issue. + (Jon Rowe) + +### 2.14.1 / 2013-07-08 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.0...v2.14.1) + +Bug fixes + +* Address deprecation formatter failure when using `ruby-debug` on + JRuby: fix `RSpec::Core::Reporter` to not send a notification + when the formatter's implementation of the notification method + comes from `Kernel` (Alex Portnov, Jon Rowe). + +### 2.14.0 / 2013-07-06 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.0.rc1...v2.14.0) + +Enhancements + +* Apply focus to examples defined with `fit` (equivalent of + `it "description", focus: true`) (Michael de Silva) + +Bug fix + +* Ensure methods defined by `let` take precedence over others + when there is a name collision (e.g. from an included module). + (Jon Rowe, Andy Lindeman and Myron Marston) + +### 2.14.0.rc1 / 2013-05-27 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.13.1...v2.14.0.rc1) + +Enhancements + +* Improved Windows detection inside Git Bash, for better `--color` handling. +* Add profiling of the slowest example groups to `--profile` option. + The output is sorted by the slowest average example groups. +* Don't show slow examples if there's a failure and both `--fail-fast` + and `--profile` options are used (Paweł Gościcki). +* Rather than always adding `spec` to the load path, add the configured + `--default-path` to the load path (which defaults to `spec`). This + better supports folks who choose to put their specs in a different + directory (John Feminella). +* Add some logic to test time duration precision. Make it a + function of time, dropping precision as the time increases. (Aaron Kromer) +* Add new `backtrace_inclusion_patterns` config option. Backtrace lines + that match one of these patterns will _always_ be included in the + backtrace, even if they match an exclusion pattern, too (Sam Phippen). +* Support ERB trim mode using the `-` when parsing `.rspec` as ERB + (Gabor Garami). +* Give a better error message when let and subject are called without a block. + (Sam Phippen). +* List the precedence of `.rspec-local` in the configuration documentation + (Sam Phippen) +* Support `{a,b}` shell expansion syntax in `--pattern` option + (Konstantin Haase). +* Add cucumber documentation for --require command line option + (Bradley Schaefer) +* Expose configuration options via config: + * `config.libs` returns the libs configured to be added onto the load path + * `full_backtrace?` returns the state of the backtrace cleaner + * `debug?` returns true when the debugger is loaded + * `line_numbers` returns the line numbers we are filtering by (if any) + * `full_description` returns the RegExp used to filter descriptions + (Jon Rowe) +* Add setters for RSpec.world and RSpec.configuration (Alex Soulim) +* Configure ruby's warning behaviour with `--warnings` (Jon Rowe) +* Fix an obscure issue on old versions of `1.8.7` where `Time.dup` wouldn't + allow access to `Time.now` (Jon Rowe) +* Make `shared_examples_for` context aware, so that keys may be safely reused + in multiple contexts without colliding. (Jon Rowe) +* Add a configurable `deprecation_stream` (Jon Rowe) +* Publish deprecations through a formatter (David Chelimsky) + +Bug fixes + +* Make JSON formatter behave the same when it comes to `--profile` as + the text formatter (Paweł Gościcki). +* Fix named subjects so that if an inner group defines a method that + overrides the named method, `subject` still retains the originally + declared value (Myron Marston). +* Fix random ordering so that it does not cause `rand` in examples in + nested sibling contexts to return the same value (Max Shytikov). +* Use the new `backtrace_inclusion_patterns` config option to ensure + that folks who develop code in a directory matching one of the default + exclusion patterns (e.g. `gems`) still get the normal backtrace + filtering (Sam Phippen). +* Fix ordering of `before` hooks so that `before` hooks declared in + `RSpec.configure` run before `before` hooks declared in a shared + context (Michi Huber and Tejas Dinkar). +* Fix `Example#full_description` so that it gets filled in by the last + matcher description (as `Example#description` already did) when no + doc string has been provided (David Chelimsky). +* Fix the memoized methods (`let` and `subject`) leaking `define_method` + as a `public` method. (Thomas Holmes and Jon Rowe) (rspec/rspec-core#873) +* Fix warnings coming from the test suite. (Pete Higgins) + +Deprecations + +* Deprecate `Configuration#backtrace_clean_patterns` in favor of + `Configuration#backtrace_exclusion_patterns` for greater consistency + and symmetry with new `backtrace_inclusion_patterns` config option + (Sam Phippen). +* Deprecate `Configuration#requires=` in favor of using ruby's + `require`. Requires specified by the command line can still be + accessed by the `Configuration#require` reader. (Bradley Schaefer) +* Deprecate calling `SharedExampleGroups` defined across sibling contexts + (Jon Rowe) + +### 2.13.1 / 2013-03-12 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.13.0...v2.13.1) + +Bug fixes + +* Use hook classes as proxies rather than extending hook blocks to support + lambdas for before/after/around hooks. (David Chelimsky) +* Fix regression in 2.13.0 that caused confusing behavior when overriding + a named subject with an unnamed subject in an inner group and then + referencing the outer group subject's name. The fix for this required + us to disallow using `super` in a named subject (which is confusing, + anyway -- named subjects create 2 methods, so which method on the + parent example group are you `super`ing to?) but `super` in an unnamed + subject continues to work (Myron Marston). +* Do not allow a referenced `let` or `subject` in `before(:all)` to cause + other `let` declarations to leak across examples (Myron Marston). +* Work around odd ruby 1.9 bug with `String#match` that was triggered + by passing it a regex from a `let` declaration. For more info, see + http://bugs.ruby-lang.org/issues/8059 (Aaron Kromer). +* Add missing `require 'set'` to `base_text_formatter.rb` (Tom + Anderson). + +Deprecations + +* Deprecate accessing `let` or `subject` declarations in `before(:all)`. + These were not intended to be called in a `before(:all)` hook, as + they exist to define state that is reset between each example, while + `before(:all)` exists to define state that is shared across examples + in an example group (Myron Marston). + +### 2.13.0 / 2013-02-23 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.2...v2.13.0) + +Enhancements + +* Allow `--profile` option to take a count argument that + determines the number of slow examples to dump + (Greggory Rothmeier). +* Add `subject!` that is the analog to `let!`. It defines an + explicit subject and sets a `before` hook that will invoke + the subject (Zubin Henner). +* Fix `let` and `subject` declaration so that `super` + and `return` can be used in them, just like in a normal + method. (Myron Marston) +* Allow output colors to be configured individually. + (Charlie Maffitt) +* Always dump slow examples when `--profile` option is given, + even when an example failed (Myron Marston). + +Bug fixes + +* Don't blow up when dumping error output for instances + of anonymous error classes (Myron Marston). +* Fix default backtrace filters so lines from projects + containing "gems" in the name are not filtered, but + lines from installed gems still are (Myron Marston). +* Fix autotest command so that is uses double quotes + rather than single quotes for windows compatibility + (Jonas Tingeborn). +* Fix `its` so that uses of `subject` in a `before` or `let` + declaration in the parent group continue to reference the + parent group's subject. (Olek Janiszewski) + +### 2.12.2 / 2012-12-13 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.1...v2.12.2) + +Bug fixes + +* Fix `RSpec::Core::RakeTask` so that it is compatible with rake 0.8.7 + on ruby 1.8.7. We had accidentally broke it in the 2.12 release + (Myron Marston). +* Fix `RSpec::Core::RakeTask` so it is tolerant of the `Rspec` constant + for backwards compatibility (Patrick Van Stee) + +### 2.12.1 / 2012-12-01 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.0...v2.12.1) + +Bug fixes + +* Specs are run even if another at\_exit hook calls `exit`. This allows + Test::Unit and RSpec to run together. (Suraj N. Kurapati) +* Fix full doc string concatenation so that it handles the case of a + method string (e.g. "#foo") being nested under a context string + (e.g. "when it is tuesday"), so that we get "when it is tuesday #foo" + rather than "when it is tuesday#foo". (Myron Marston) +* Restore public API I unintentionally broke in 2.12.0: + `RSpec::Core::Formatters::BaseFormatter#format_backtrce(backtrace, example)` + (Myron Marston). + +### 2.12.0 / 2012-11-12 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.11.1...v2.12.0) + +Enhancements + +* Add support for custom ordering strategies for groups and examples. + (Myron Marston) +* JSON Formatter (Alex Chaffee) +* Refactor rake task internals (Sam Phippen) +* Refactor HtmlFormatter (Pete Hodgson) +* Autotest supports a path to Ruby that contains spaces (dsisnero) +* Provide a helpful warning when a shared example group is redefined. + (Mark Burns). +* `--default_path` can be specified as `--default-line`. `--line_number` can be + specified as `--line-number`. Hyphens are more idiomatic command line argument + separators (Sam Phippen). +* A more useful error message is shown when an invalid command line option is + used (Jordi Polo). +* Add `format_docstrings { |str| }` config option. It can be used to + apply formatting rules to example group and example docstrings. + (Alex Tan) +* Add support for an `.rspec-local` options file. This is intended to + allow individual developers to set options in a git-ignored file that + override the common project options in `.rspec`. (Sam Phippen) +* Support for mocha 0.13.0. (Andy Lindeman) + +Bug fixes + +* Remove override of `ExampleGroup#ancestors`. This is a core ruby method that + RSpec shouldn't override. Instead, define `ExampleGroup#parent_groups`. (Myron + Marston) +* Limit monkey patching of shared example/context declaration methods + (`shared_examples_for`, etc.) to just the objects that need it rather than + every object in the system (Myron Marston). +* Fix Metadata#fetch to support computed values (Sam Goldman). +* Named subject can now be referred to from within subject block in a nested + group (tomykaira). +* Fix `fail_fast` so that it properly exits when an error occurs in a + `before(:all) hook` (Bradley Schaefer). +* Make the order spec files are loaded consistent, regardless of the + order of the files returned by the OS or the order passed at + the command line (Jo Liss and Sam Phippen). +* Ensure instance variables from `before(:all)` are always exposed + from `after(:all)`, even if an error occurs in `before(:all)` + (Sam Phippen). +* `rspec --init` no longer generates an incorrect warning about `--configure` + being deprecated (Sam Phippen). +* Fix pluralization of `1 seconds` (Odin Dutton) +* Fix ANSICON url (Jarmo Pertman) +* Use dup of Time so reporting isn't clobbered by examples that modify Time + without properly restoring it. (David Chelimsky) + +Deprecations + +* `share_as` is no longer needed. `shared_context` and/or + `RSpec::SharedContext` provide better mechanisms (Sam Phippen). +* Deprecate `RSpec.configuration` with a block (use `RSpec.configure`). + + +### 2.11.1 / 2012-07-18 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.11.0...v2.11.1) + +Bug fixes + +* Fix the way we autoload RSpec::Matchers so that custom matchers can be + defined before rspec-core has been configured to definitely use + rspec-expectations. (Myron Marston) +* Fix typo in --help message printed for -e option. (Jo Liss) +* Fix ruby warnings. (Myron Marston) +* Ignore mock expectation failures when the example has already failed. + Mock expectation failures have always been ignored in this situation, + but due to my changes in 27059bf1 it was printing a confusing message. + (Myron Marston). + +### 2.11.0 / 2012-07-07 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.10.1...v2.11.0) + +Enhancements + +* Support multiple `--example` options. (Daniel Doubrovkine @dblock) +* Named subject e.g. `subject(:article) { Article.new }` + * see [http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/](http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/) + for background. + * thanks to Bradley Schaefer for suggesting it and Avdi Grimm for almost + suggesting it. +* `config.mock_with` and `config.expect_with` yield custom config object to a + block if given + * aids decoupling from rspec-core's configuation +* `include_context` and `include_examples` support a block, which gets eval'd + in the current context (vs the nested context generated by `it_behaves_like`). +* Add `config.order = 'random'` to the `spec_helper.rb` generated by `rspec + --init`. +* Delay the loading of DRb (Myron Marston). +* Limit monkey patching of `describe` onto just the objects that need it rather + than every object in the system (Myron Marston). + +Bug fixes + +* Support alternative path separators. For example, on Windows, you can now do + this: `rspec spec\subdir`. (Jarmo Pertman @jarmo) +* When an example raises an error and an after or around hook does as + well, print out the hook error. Previously, the error was silenced and + the user got no feedback about what happened. (Myron Marston) +* `--require` and `-I` are merged among different configuration sources (Andy + Lindeman) +* Delegate to mocha methods instead of aliasing them in mocha adapter. + +### 2.10.1 / 2012-05-19 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.10.0...v2.10.1) + +Bug fixes + +* `RSpec.reset` properly reinits configuration and world +* Call `to_s` before `split` on exception messages that might not always be + Strings (slyphon) + +### 2.10.0 / 2012-05-03 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.9.0...v2.10.0) + +Enhancements + +* Add `prepend_before` and `append_after` hooks (preethiramdev) + * intended for extension libs + * restores rspec-1 behavior +* Reporting of profiled examples (moro) + * Report the total amount of time taken for the top slowest examples. + * Report what percentage the slowest examples took from the total runtime. + +Bug fixes + +* Properly parse `SPEC_OPTS` options. +* `example.description` returns the location of the example if there is no + explicit description or matcher-generated description. +* RDoc fixes (Grzegorz Świrski) +* Do not modify example ancestry when dumping errors (Michael Grosser) + +### 2.9.0 / 2012-03-17 +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0...v2.9.0) + +Enhancements + +* Support for "X minutes X seconds" spec run duration in formatter. (uzzz) +* Strip whitespace from group and example names in doc formatter. +* Removed spork-0.9 shim. If you're using spork-0.8.x, you'll need to upgrade + to 0.9.0. + +Bug fixes + +* Restore `--full_backtrace` option +* Ensure that values passed to `config.filter_run` are respected when running + over DRb (using spork). +* Ensure shared example groups are reset after a run (as example groups are). +* Remove `rescue false` from calls to filters represented as Procs +* Ensure `described_class` gets the closest constant (pyromaniac) +* In "autorun", don't run the specs in the `at_exit` hook if there was an + exception (most likely due to a SyntaxError). (sunaku) +* Don't extend groups with modules already used to extend ancestor groups. +* `its` correctly memoizes nil or false values (Yamada Masaki) + +### 2.8.0 / 2012-01-04 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0.rc2...v2.8.0) + +Bug fixes + +* For metadata filtering, restore passing the entire array to the proc, rather + than each item in the array (weidenfreak) +* Ensure each spec file is loaded only once + * Fixes a bug that caused all the examples in a file to be run when + referenced twice with line numbers in a command, e.g. + * `rspec path/to/file:37 path/to/file:42` + +### 2.8.0.rc2 / 2011-12-19 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0.rc1...v2.8.0.rc2) + +Enhancments + +* new `--init` command (Peter Schröder) + * generates `spec/spec_helper.rb` + * deletes obsolete files (on confirmation) + * merged with and deprecates `--configure` command, which generated + `.rspec` +* use `require_relative` when available (Ian Leitch) +* `include_context` and `include_examples` accept params (Calvin Bascom) +* print the time for every example in the html formatter (Richie Vos) +* several tasty refactoring niblets (Sasha) +* `it "does something", :x => [:foo,'bar',/baz/] (Ivan Neverov) + * supports matching n command line tag values with an example or group + +### 2.8.0.rc1 / 2011-11-06 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.7.1...v2.8.0.rc1) + +Enhancements + +* `--order` (Justin Ko) + * run examples in random order: `--order rand` + * specify the seed: `--order rand:123` +* `--seed SEED` + * equivalent of `--order rand:SEED` +* SharedContext supports `let` (David Chelimsky) +* Filter improvements (David Chelimsky) + * override opposing tags from the command line + * override RSpec.configure tags from the command line + * `--line_number 37` overrides all other filters + * `path/to/file.rb:37` overrides all other filters + * refactor: consolidate filter management in a FilterManger object +* Eliminate Ruby warnings (Matijs van Zuijlen) +* Make reporter.report an API (David Chelimsky) + * supports extension tools like interative_rspec + +Changes + +* change `config.color_enabled` (getter/setter/predicate) to `color` to align + with `--[no]-color` CLI option. + * `color_enabled` is still supported for now, but will likley be deprecated + in a 2.x release so we can remove it in 3.0. + +Bug fixes + +* Make sure the `bar` in `--tag foo:bar` makes it to DRb (Aaron Gibralter) +* Fix bug where full descriptions of groups nested 3 deep were repeated. +* Restore report of time to run to start after files are loaded. + * fixes bug where run times were cumalitive in spork + * fixes compatibility with time-series metrics +* Don't error out when `config.mock_with` or `expect_with` is re-specifying the + current config (Myron Marston) + +* Deprecations + * :alias option on `configuration.add_setting`. Use `:alias_with` on the + original setting declaration instead. + +### 2.7.1 / 2011-10-20 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.7.0...v2.7.1) + +Bug fixes + +* tell autotest the correct place to find the rspec executable + +### 2.7.0 / 2011-10-16 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.4...v2.7.0) + +NOTE: RSpec's release policy dictates that there should not be any backward +incompatible changes in minor releases, but we're making an exception to +release a change to how RSpec interacts with other command line tools. + +As of 2.7.0, you must explicity `require "rspec/autorun"` unless you use the +`rspec` command (which already does this for you). + +Enhancements + +* Add `example.exception` (David Chelimsky) +* `--default_path` command line option (Justin Ko) +* support multiple `--line_number` options (David J. Hamilton) + * also supports `path/to/file.rb:5:9` (runs examples on lines 5 and 9) +* Allow classes/modules to be used as shared example group identifiers (Arthur + Gunn) +* Friendly error message when shared context cannot be found (Sławosz + Sławiński) +* Clear formatters when resetting config (John Bintz) +* Add `xspecify` and xexample as temp-pending methods (David Chelimsky) +* Add `--no-drb` option (Iain Hecker) +* Provide more accurate run time by registering start time before code is + loaded (David Chelimsky) + * reverted in 2.8.0 +* Rake task default pattern finds specs in symlinked dirs (Kelly Felkins) +* Rake task no longer does anything to invoke bundler since Bundler already + handles it for us. Thanks to Andre Arko for the tip. +* Add `--failure-exit-code` option (Chris Griego) + +Bug fixes + +* Include `Rake::DSL` to remove deprecation warnings in Rake > 0.8.7 (Pivotal + Casebook) +* Only eval `let` block once even if it returns `nil` (Adam Meehan) +* Fix `--pattern` option (wasn't being recognized) (David Chelimsky) +* Only implicitly `require "rspec/autorun"` with the `rspec` command (David + Chelimsky) +* Ensure that rspec's `at_exit` defines the exit code (Daniel Doubrovkine) +* Show the correct snippet in the HTML and TextMate formatters (Brian Faherty) + +### 2.6.4 / 2011-06-06 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.3...v2.6.4) + +NOTE: RSpec's release policy dictates that there should not be new +functionality in patch releases, but this minor enhancement slipped in by +accident. As it doesn't add a new API, we decided to leave it in rather than +roll back this release. + +Enhancements + +* Add summary of commands to run individual failed examples. + +Bug fixes + +* Support exclusion filters in DRb. (Yann Lugrin) +* Fix --example escaping when run over DRb. (Elliot Winkler) +* Use standard ANSI codes for color formatting so colors work in a wider set of + color schemes. + +### 2.6.3 / 2011-05-24 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.2...v2.6.3) + +Bug fixes + +* Explicitly convert exit code to integer, avoiding TypeError when return + value of run is IO object proxied by `DRb::DRbObject` (Julian Scheid) +* Clarify behavior of `--example` command line option +* Build using a rubygems-1.6.2 to avoid downstream yaml parsing error + +### 2.6.2 / 2011-05-21 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.1...v2.6.2) + +Bug fixes + +* Warn rather than raise when HOME env var is not defined +* Properly merge command-line exclusions with default :if and :unless (joshcooper) + +### 2.6.1 / 2011-05-19 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.0...v2.6.1) + +Bug fixes + +* Don't extend nil when filters are nil +* `require 'rspec/autorun'` when running rcov. + +### 2.6.0 / 2011-05-12 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.0) + +Enhancements + +* `shared_context` (Damian Nurzynski) + * extend groups matching specific metadata with: + * method definitions + * subject declarations + * let/let! declarations + * etc (anything you can do in a group) +* `its([:key])` works for any subject with #[]. (Peter Jaros) +* `treat_symbols_as_metadata_keys_with_true_values` (Myron Marston) +* Print a deprecation warning when you configure RSpec after defining an + example. All configuration should happen before any examples are defined. + (Myron Marston) +* Pass the exit status of a DRb run to the invoking process. This causes specs + run via DRb to not just return true or false. (Ilkka Laukkanen) +* Refactoring of `ConfigurationOptions#parse_options` (Rodrigo Rosenfeld Rosas) +* Report excluded filters in runner output (tip from andyl) +* Clean up messages for filters/tags. +* Restore --pattern/-P command line option from rspec-1 +* Support false as well as true in config.full_backtrace= (Andreas Tolf + Tolfsen) + +Bug fixes + +* Don't stumble over an exception without a message (Hans Hasselberg) +* Remove non-ascii characters from comments that were choking rcov (Geoffrey + Byers) +* Fixed backtrace so it doesn't include lines from before the autorun at_exit + hook (Myron Marston) +* Include RSpec::Matchers when first example group is defined, rather than just + before running the examples. This works around an obscure bug in ruby 1.9 + that can cause infinite recursion. (Myron Marston) +* Don't send `example_group_[started|finished]` to formatters for empty groups. +* Get specs passing on jruby (Sidu Ponnappa) +* Fix bug where mixing nested groups and outer-level examples gave + unpredictable :line_number behavior (Artur Małecki) +* Regexp.escape the argument to --example (tip from Elliot Winkler) +* Correctly pass/fail pending block with message expectations +* CommandLine returns exit status (0/1) instead of true/false +* Create path to formatter output file if it doesn't exist (marekj). + + +### 2.5.1 / 2011-02-06 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.5.0...v2.5.1) + +NOTE: this release breaks compatibility with rspec/autotest/bundler +integration, but does so in order to greatly simplify it. + +With this release, if you want the generated autotest command to include +'bundle exec', require Autotest's bundler plugin in a .autotest file in the +project's root directory or in your home directory: + + require "autotest/bundler" + +Now you can just type 'autotest' on the command line and it will work as you expect. + +If you don't want 'bundle exec', there is nothing you have to do. + +### 2.5.0 / 2011-02-05 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.4.0...v2.5.0) + +Enhancements + +* Autotest::Rspec2 parses command line args passed to autotest after '--' +* --skip-bundler option for autotest command +* Autotest regexp fixes (Jon Rowe) +* Add filters to html and textmate formatters (Daniel Quimper) +* Explicit passing of block (need for JRuby 1.6) (John Firebaugh) + +Bug fixes + +* fix dom IDs in HTML formatter (Brian Faherty) +* fix bug with --drb + formatters when not running in drb +* include --tag options in drb args (monocle) +* fix regression so now SPEC_OPTS take precedence over CLI options again (Roman + Chernyatchik) +* only call its(:attribute) once (failing example from Brian Dunn) +* fix bizarre bug where rspec would hang after String.alias :to_int :to_i + (Damian Nurzynski) + +Deprecations + +* implicit inclusion of 'bundle exec' when Gemfile present (use autotest's + bundler plugin instead) + +### 2.4.0 / 2011-01-02 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.3.1...v2.4.0) + +Enhancements + +* start the debugger on -d so the stack trace is visible when it stops + (Clifford Heath) +* apply hook filtering to examples as well as groups (Myron Marston) +* support multiple formatters, each with their own output +* show exception classes in failure messages unless they come from RSpec + matchers or message expectations +* before(:all) { pending } sets all examples to pending + +Bug fixes + +* fix bug due to change in behavior of reject in Ruby 1.9.3-dev (Shota + Fukumori) +* fix bug when running in jruby: be explicit about passing block to super (John + Firebaugh) +* rake task doesn't choke on paths with quotes (Janmejay Singh) +* restore --options option from rspec-1 +* require 'ostruct' to fix bug with its([key]) (Kim Burgestrand) +* --configure option generates .rspec file instead of autotest/discover.rb + +### 2.3.1 / 2010-12-16 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.3.0...v2.3.1) + +Bug fixes + +* send debugger warning message to $stdout if RSpec.configuration.error_stream + has not been defined yet. +* HTML Formatter _finally_ properly displays nested groups (Jarmo Pertman) +* eliminate some warnings when running RSpec's own suite (Jarmo Pertman) + +### 2.3.0 / 2010-12-12 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.2.1...v2.3.0) + +Enhancements + +* tell autotest to use "rspec2" if it sees a .rspec file in the project's root + directory + * replaces the need for ./autotest/discover.rb, which will not work with + all versions of ZenTest and/or autotest +* config.expect_with + * :rspec # => rspec/expectations + * :stdlib # => test/unit/assertions + * :rspec, :stdlib # => both + +Bug fixes + +* fix dev Gemfile to work on non-mac-os machines (Lake Denman) +* ensure explicit subject is only eval'd once (Laszlo Bacsi) + +### 2.2.1 / 2010-11-28 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.2.0...v2.2.1) + +Bug fixes + +* alias_method instead of override Kernel#method_missing (John Wilger) +* changed --autotest to --tty in generated command (MIKAMI Yoshiyuki) +* revert change to debugger (had introduced conflict with Rails) + * also restored --debugger/-debug option + +### 2.2.0 / 2010-11-28 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.1.0...v2.2.0) + +Deprecations/changes + +* --debug/-d on command line is deprecated and now has no effect +* win32console is now ignored; Windows users must use ANSICON for color support + (Bosko Ivanisevic) + +Enhancements + +* When developing locally rspec-core now works with the rspec-dev setup or your + local gems +* Raise exception with helpful message when rspec-1 is loaded alongside rspec-2 + (Justin Ko) +* debugger statements _just work_ as long as ruby-debug is installed + * otherwise you get warned, but not fired +* Expose example.metadata in around hooks +* Performance improvments (much faster now) + +Bug fixes + +* Make sure --fail-fast makes it across drb +* Pass -Ilib:spec to rcov + +### 2.1.0 / 2010-11-07 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.1...v2.1.0) + +Enhancments + +* Add skip_bundler option to rake task to tell rake task to ignore the presence + of a Gemfile (jfelchner) +* Add gemfile option to rake task to tell rake task what Gemfile to look for + (defaults to 'Gemfile') +* Allow passing caller trace into Metadata to support extensions (Glenn + Vanderburg) +* Add deprecation warning for Spec::Runner.configure to aid upgrade from + RSpec-1 +* Add deprecated Spec::Rake::SpecTask to aid upgrade from RSpec-1 +* Add 'autospec' command with helpful message to aid upgrade from RSpec-1 +* Add support for filtering with tags on CLI (Lailson Bandeira) +* Add a helpful message about RUBYOPT when require fails in bin/rspec (slyphon) +* Add "-Ilib" to the default rcov options (Tianyi Cui) +* Make the expectation framework configurable (default rspec, of course) + (Justin Ko) +* Add 'pending' to be conditional (Myron Marston) +* Add explicit support for :if and :unless as metadata keys for conditional run + of examples (Myron Marston) +* Add --fail-fast command line option (Jeff Kreeftmeijer) + +Bug fixes + +* Eliminate stack overflow with "subject { self }" +* Require 'rspec/core' in the Raketask (ensures it required when running rcov) + +### 2.0.1 / 2010-10-18 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0...v2.0.1) + +Bug fixes + +* Restore color when using spork + autotest +* Pending examples without docstrings render the correct message (Josep M. + Bach) +* Fixed bug where a failure in a spec file ending in anything but _spec.rb + would fail in a confusing way. +* Support backtrace lines from erb templates in html formatter (Alex Crichton) + +### 2.0.0 / 2010-10-10 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.rc...v2.0.0) + +RSpec-1 compatibility + +* Rake task uses ENV["SPEC"] as file list if present + +Bug fixes + +* Bug Fix: optparse --out foo.txt (Leonardo Bessa) +* Suppress color codes for non-tty output (except autotest) + +### 2.0.0.rc / 2010-10-05 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.beta.22...v2.0.0.rc) + +Enhancements + +* implicitly require unknown formatters so you don't have to require the file + explicitly on the command line (Michael Grosser) +* add --out/-o option to assign output target +* added fail_fast configuration option to abort on first failure +* support a Hash subject (its([:key]) { should == value }) (Josep M. Bach) + +Bug fixes + +* Explicitly require rspec version to fix broken rdoc task (Hans de Graaff) +* Ignore backtrace lines that come from other languages, like Java or + Javascript (Charles Lowell) +* Rake task now does what is expected when setting (or not setting) + fail_on_error and verbose +* Fix bug in which before/after(:all) hooks were running on excluded nested + groups (Myron Marston) +* Fix before(:all) error handling so that it fails examples in nested groups, + too (Myron Marston) + +### 2.0.0.beta.22 / 2010-09-12 + +[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.beta.20...v2.0.0.beta.22) + +Enhancements + +* removed at_exit hook +* CTRL-C stops the run (almost) immediately + * first it cleans things up by running the appropriate after(:all) and + after(:suite) hooks + * then it reports on any examples that have already run +* cleaned up rake task + * generate correct task under variety of conditions + * options are more consistent + * deprecated redundant options +* run 'bundle exec autotest' when Gemfile is present +* support ERB in .rspec options files (Justin Ko) +* depend on bundler for development tasks (Myron Marston) +* add example_group_finished to formatters and reporter (Roman Chernyatchik) + +Bug fixes + +* support paths with spaces when using autotest (Andreas Neuhaus) +* fix module_exec with ruby 1.8.6 (Myron Marston) +* remove context method from top-level + * was conflicting with irb, for example +* errors in before(:all) are now reported correctly (Chad Humphries) + +Removals + +* removed -o --options-file command line option + * use ./.rspec and ~/.rspec diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md new file mode 100644 index 0000000..76dc17d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md @@ -0,0 +1,26 @@ +The MIT License (MIT) +===================== + +* Copyright © 2012 Chad Humphries, David Chelimsky, Myron Marston +* Copyright © 2009 Chad Humphries, David Chelimsky +* Copyright © 2006 David Chelimsky, The RSpec Development Team +* Copyright © 2005 Steven Baker + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md new file mode 100644 index 0000000..8598146 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md @@ -0,0 +1,389 @@ +# rspec-core [![Build Status](https://github.com/rspec/rspec-core/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-core/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-core.svg)](https://codeclimate.com/github/rspec/rspec-core) + +rspec-core provides the structure for writing executable examples of how your +code should behave, and an `rspec` command with tools to constrain which +examples get run and tailor the output. + +## Install + + gem install rspec # for rspec-core, rspec-expectations, rspec-mocks + gem install rspec-core # for rspec-core only + rspec --help + +Want to run against the `main` branch? You'll need to include the dependent +RSpec repos as well. Add the following to your `Gemfile`: + +```ruby +%w[rspec rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| + gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' +end +``` + +## Basic Structure + +RSpec uses the words "describe" and "it" so we can express concepts like a conversation: + + "Describe an order." + "It sums the prices of its line items." + +```ruby +RSpec.describe Order do + it "sums the prices of its line items" do + order = Order.new + + order.add_entry(LineItem.new(:item => Item.new( + :price => Money.new(1.11, :USD) + ))) + order.add_entry(LineItem.new(:item => Item.new( + :price => Money.new(2.22, :USD), + :quantity => 2 + ))) + + expect(order.total).to eq(Money.new(5.55, :USD)) + end +end +``` + +The `describe` method creates an [ExampleGroup](http://rubydoc.info/gems/rspec-core/RSpec/Core/ExampleGroup). Within the +block passed to `describe` you can declare examples using the `it` method. + +Under the hood, an example group is a class in which the block passed to +`describe` is evaluated. The blocks passed to `it` are evaluated in the +context of an _instance_ of that class. + +## Nested Groups + +You can also declare nested groups using the `describe` or `context` +methods: + +```ruby +RSpec.describe Order do + context "with no items" do + it "behaves one way" do + # ... + end + end + + context "with one item" do + it "behaves another way" do + # ... + end + end +end +``` + +Nested groups are subclasses of the outer example group class, providing +the inheritance semantics you'd want for free. + +## Aliases + +You can declare example groups using either `describe` or `context`. +For a top level example group, `describe` and `context` are available +off of `RSpec`. For backwards compatibility, they are also available +off of the `main` object and `Module` unless you disable monkey +patching. + +You can declare examples within a group using any of `it`, `specify`, or +`example`. + +## Shared Examples and Contexts + +Declare a shared example group using `shared_examples`, and then include it +in any group using `include_examples`. + +```ruby +RSpec.shared_examples "collections" do |collection_class| + it "is empty when first created" do + expect(collection_class.new).to be_empty + end +end + +RSpec.describe Array do + include_examples "collections", Array +end + +RSpec.describe Hash do + include_examples "collections", Hash +end +``` + +Nearly anything that can be declared within an example group can be declared +within a shared example group. This includes `before`, `after`, and `around` +hooks, `let` declarations, and nested groups/contexts. + +You can also use the names `shared_context` and `include_context`. These are +pretty much the same as `shared_examples` and `include_examples`, providing +more accurate naming when you share hooks, `let` declarations, helper methods, +etc, but no examples. + +If you want to reuse shared examples or contexts across your RSpec suite you can +define them in a stand alone _*.rb_ files (_spec/support/shared_examples/definition.rb_ +for example). But you will have to manually `require` them (there is no autoloading of +_spec/support/_ directory unless you set it up yourself). + +## Metadata + +rspec-core stores a metadata hash with every example and group, which +contains their descriptions, the locations at which they were +declared, etc, etc. This hash powers many of rspec-core's features, +including output formatters (which access descriptions and locations), +and filtering before and after hooks. + +Although you probably won't ever need this unless you are writing an +extension, you can access it from an example like this: + +```ruby +it "does something" do |example| + expect(example.metadata[:description]).to eq("does something") +end +``` + +### `described_class` + +When a class is passed to `describe`, you can access it from an example +using the `described_class` method, which is a wrapper for +`example.metadata[:described_class]`. + +```ruby +RSpec.describe Widget do + example do + expect(described_class).to equal(Widget) + end +end +``` + +This is useful in extensions or shared example groups in which the specific +class is unknown. Taking the collections shared example group from above, we can +clean it up a bit using `described_class`: + +```ruby +RSpec.shared_examples "collections" do + it "is empty when first created" do + expect(described_class.new).to be_empty + end +end + +RSpec.describe Array do + include_examples "collections" +end + +RSpec.describe Hash do + include_examples "collections" +end +``` + +## A Word on Scope + +RSpec has two scopes: + +* **Example Group**: Example groups are defined by a `describe` or + `context` block, which is eagerly evaluated when the spec file is + loaded. The block is evaluated in the context of a subclass of + `RSpec::Core::ExampleGroup`, or a subclass of the parent example group + when you're nesting them. +* **Example**: Examples -- typically defined by an `it` block -- and any other + blocks with per-example semantics -- such as a `before(:example)` hook -- are + evaluated in the context of + an _instance_ of the example group class to which the example belongs. + Examples are _not_ executed when the spec file is loaded; instead, + RSpec waits to run any examples until all spec files have been loaded, + at which point it can apply filtering, randomization, etc. + +To make this more concrete, consider this code snippet: + +``` ruby +RSpec.describe "Using an array as a stack" do + def build_stack + [] + end + + before(:example) do + @stack = build_stack + end + + it 'is initially empty' do + expect(@stack).to be_empty + end + + context "after an item has been pushed" do + before(:example) do + @stack.push :item + end + + it 'allows the pushed item to be popped' do + expect(@stack.pop).to eq(:item) + end + end +end +``` + +Under the covers, this is (roughly) equivalent to: + +``` ruby +class UsingAnArrayAsAStack < RSpec::Core::ExampleGroup + def build_stack + [] + end + + def before_example_1 + @stack = build_stack + end + + def it_is_initially_empty + expect(@stack).to be_empty + end + + class AfterAnItemHasBeenPushed < self + def before_example_2 + @stack.push :item + end + + def it_allows_the_pushed_item_to_be_popped + expect(@stack.pop).to eq(:item) + end + end +end +``` + +To run these examples, RSpec would (roughly) do the following: + +``` ruby +example_1 = UsingAnArrayAsAStack.new +example_1.before_example_1 +example_1.it_is_initially_empty + +example_2 = UsingAnArrayAsAStack::AfterAnItemHasBeenPushed.new +example_2.before_example_1 +example_2.before_example_2 +example_2.it_allows_the_pushed_item_to_be_popped +``` + +## The `rspec` Command + +When you install the rspec-core gem, it installs the `rspec` executable, +which you'll use to run rspec. The `rspec` command comes with many useful +options. +Run `rspec --help` to see the complete list. + +## Store Command Line Options `.rspec` + +You can store command line options in a `.rspec` file in the project's root +directory, and the `rspec` command will read them as though you typed them on +the command line. + +## Get Started + +Start with a simple example of behavior you expect from your system. Do +this before you write any implementation code: + +```ruby +# in spec/calculator_spec.rb +RSpec.describe Calculator do + describe '#add' do + it 'returns the sum of its arguments' do + expect(Calculator.new.add(1, 2)).to eq(3) + end + end +end +``` + +Run this with the rspec command, and watch it fail: + +``` +$ rspec spec/calculator_spec.rb +./spec/calculator_spec.rb:1: uninitialized constant Calculator +``` + +Address the failure by defining a skeleton of the `Calculator` class: + +```ruby +# in lib/calculator.rb +class Calculator + def add(a, b) + end +end +``` + +Be sure to require the implementation file in the spec: + +```ruby +# in spec/calculator_spec.rb +# - RSpec adds ./lib to the $LOAD_PATH +require "calculator" +``` + +Now run the spec again, and watch the expectation fail: + +``` +$ rspec spec/calculator_spec.rb +F + +Failures: + + 1) Calculator#add returns the sum of its arguments + Failure/Error: expect(Calculator.new.add(1, 2)).to eq(3) + + expected: 3 + got: nil + + (compared using ==) + # ./spec/calculator_spec.rb:6:in `block (3 levels) in ' + +Finished in 0.00131 seconds (files took 0.10968 seconds to load) +1 example, 1 failure + +Failed examples: + +rspec ./spec/calculator_spec.rb:5 # Calculator#add returns the sum of its arguments +``` + +Implement the simplest solution, by changing the definition of `Calculator#add` to: + +```ruby +def add(a, b) + a + b +end +``` + +Now run the spec again, and watch it pass: + +``` +$ rspec spec/calculator_spec.rb +. + +Finished in 0.000315 seconds +1 example, 0 failures +``` + +Use the `documentation` formatter to see the resulting spec: + +``` +$ rspec spec/calculator_spec.rb --format doc +Calculator + #add + returns the sum of its arguments + +Finished in 0.000379 seconds +1 example, 0 failures +``` + +## Contributing + +Once you've set up the environment, you'll need to cd into the working +directory of whichever repo you want to work in. From there you can run the +specs and cucumber features, and make patches. + +NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You +can treat each RSpec repo as an independent project. + +* [Build details](BUILD_DETAIL.md) +* [Code of Conduct](CODE_OF_CONDUCT.md) +* [Detailed contributing guide](CONTRIBUTING.md) +* [Development setup guide](DEVELOPMENT.md) + +## Also see + +* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) +* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations) +* [https://github.com/rspec/rspec-mocks](https://github.com/rspec/rspec-mocks) +* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec new file mode 100755 index 0000000..7ee5fd8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +require 'rspec/core' +RSpec::Core::Runner.invoke diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb new file mode 100644 index 0000000..3080cfd --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb @@ -0,0 +1,3 @@ +require 'rspec/core' +# Ensure the default config is loaded +RSpec::Core::Runner.autorun diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb new file mode 100644 index 0000000..ad9553c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb @@ -0,0 +1,212 @@ +# rubocop:disable Style/GlobalVars +$_rspec_core_load_started_at = Time.now +# rubocop:enable Style/GlobalVars + +require "rspec/support" +RSpec::Support.require_rspec_support "caller_filter" + +RSpec::Support.define_optimized_require_for_rspec(:core) { |f| require_relative f } + +%w[ + version + warnings + + set + flat_map + filter_manager + dsl + notifications + reporter + + hooks + memoized_helpers + metadata + metadata_filter + pending + formatters + ordering + + world + configuration + option_parser + configuration_options + runner + invocations + example + shared_example_group + example_group +].each { |name| RSpec::Support.require_rspec_core name } + +# Namespace for all core RSpec code. +module RSpec + autoload :SharedContext, 'rspec/core/shared_context' + + extend RSpec::Core::Warnings + + class << self + # Setters for shared global objects + # @api private + attr_writer :configuration, :world + end + + # Used to ensure examples get reloaded and user configuration gets reset to + # defaults between multiple runs in the same process. + # + # Users must invoke this if they want to have the configuration reset when + # they use the runner multiple times within the same process. Users must deal + # themselves with re-configuration of RSpec before run. + def self.reset + RSpec::ExampleGroups.remove_all_constants + @world = nil + @configuration = nil + end + + # Used to ensure examples get reloaded between multiple runs in the same + # process and ensures user configuration is persisted. + # + # Users must invoke this if they want to clear all examples but preserve + # current configuration when they use the runner multiple times within the + # same process. + def self.clear_examples + world.reset + configuration.reset_reporter + configuration.start_time = ::RSpec::Core::Time.now + configuration.reset_filters + end + + # Returns the global [Configuration](RSpec/Core/Configuration) object. While + # you _can_ use this method to access the configuration, the more common + # convention is to use [RSpec.configure](RSpec#configure-class_method). + # + # @example + # RSpec.configuration.drb_port = 1234 + # @see RSpec.configure + # @see Core::Configuration + def self.configuration + @configuration ||= RSpec::Core::Configuration.new + end + + # Yields the global configuration to a block. + # @yield [Configuration] global configuration + # + # @example + # RSpec.configure do |config| + # config.add_formatter 'documentation' + # end + # @see Core::Configuration + def self.configure + yield configuration if block_given? + end + + # The example being executed. + # + # The primary audience for this method is library authors who need access + # to the example currently being executed and also want to support all + # versions of RSpec 2 and 3. + # + # @example + # + # RSpec.configure do |c| + # # context.example is deprecated, but RSpec.current_example is not + # # available until RSpec 3.0. + # fetch_current_example = RSpec.respond_to?(:current_example) ? + # proc { RSpec.current_example } : proc { |context| context.example } + # + # c.before(:example) do + # example = fetch_current_example.call(self) + # + # # ... + # end + # end + # + def self.current_example + RSpec::Support.thread_local_data[:current_example] + end + + # Set the current example being executed. + # @api private + def self.current_example=(example) + RSpec::Support.thread_local_data[:current_example] = example + end + + # Set the current scope rspec is executing in + # @api private + def self.current_scope=(scope) + RSpec::Support.thread_local_data[:current_scope] = scope + end + RSpec.current_scope = :suite + + # Get the current RSpec execution scope + # + # Returns (in order of lifecycle): + # * `:suite` as an initial value, this is outside of the test lifecycle. + # * `:before_suite_hook` during `before(:suite)` hooks. + # * `:before_context_hook` during `before(:context)` hooks. + # * `:before_example_hook` during `before(:example)` hooks and `around(:example)` before `example.run`. + # * `:example` within the example run. + # * `:after_example_hook` during `after(:example)` hooks and `around(:example)` after `example.run`. + # * `:after_context_hook` during `after(:context)` hooks. + # * `:after_suite_hook` during `after(:suite)` hooks. + # * `:suite` as a final value, again this is outside of the test lifecycle. + # + # Reminder, `:context` hooks have `:all` alias and `:example` hooks have `:each` alias. + # @return [Symbol] + def self.current_scope + RSpec::Support.thread_local_data[:current_scope] + end + + # @private + # Internal container for global non-configuration data. + def self.world + @world ||= RSpec::Core::World.new + end + + # Namespace for the rspec-core code. + module Core + autoload :ExampleStatusPersister, "rspec/core/example_status_persister" + autoload :Profiler, "rspec/core/profiler" + autoload :DidYouMean, "rspec/core/did_you_mean" + + # @private + # This avoids issues with reporting time caused by examples that + # change the value/meaning of Time.now without properly restoring + # it. + class Time + class << self + define_method(:now, &::Time.method(:now)) + end + end + + # @private path to executable file. + def self.path_to_executable + @path_to_executable ||= File.expand_path('../../../exe/rspec', __FILE__) + end + end + + # @private + MODULES_TO_AUTOLOAD = { + :Matchers => "rspec/expectations", + :Expectations => "rspec/expectations", + :Mocks => "rspec/mocks" + } + + # @private + def self.const_missing(name) + # Load rspec-expectations when RSpec::Matchers is referenced. This allows + # people to define custom matchers (using `RSpec::Matchers.define`) before + # rspec-core has loaded rspec-expectations (since it delays the loading of + # it to allow users to configure a different assertion/expectation + # framework). `autoload` can't be used since it works with ruby's built-in + # require (e.g. for files that are available relative to a load path dir), + # but not with rubygems' extended require. + # + # As of rspec 2.14.1, we no longer require `rspec/mocks` and + # `rspec/expectations` when `rspec` is required, so we want + # to make them available as an autoload. + require MODULES_TO_AUTOLOAD.fetch(name) { return super } + ::RSpec.const_get(name) + end + + Core::DSL.expose_globally! + Core::SharedExampleGroup::TopLevelDSL.expose_globally! +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb new file mode 100644 index 0000000..e0bee52 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb @@ -0,0 +1,65 @@ +module RSpec + module Core + # @private + class BacktraceFormatter + # @private + attr_accessor :exclusion_patterns, :inclusion_patterns + + def initialize + @full_backtrace = false + + patterns = %w[ /lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle: ] + patterns << "org/jruby/" if RUBY_PLATFORM == 'java' + patterns.map! { |s| Regexp.new(s.gsub("/", File::SEPARATOR)) } + + @exclusion_patterns = [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *patterns)] + @inclusion_patterns = [] + + return unless matches?(@exclusion_patterns, File.join(Dir.getwd, "lib", "foo.rb:13")) + inclusion_patterns << Regexp.new(Dir.getwd) + end + + attr_writer :full_backtrace + + def full_backtrace? + @full_backtrace || exclusion_patterns.empty? + end + + def filter_gem(gem_name) + sep = File::SEPARATOR + exclusion_patterns << /#{sep}#{gem_name}(-[^#{sep}]+)?#{sep}/ + end + + def format_backtrace(backtrace, options={}) + return [] unless backtrace + return backtrace if options[:full_backtrace] || backtrace.empty? + + backtrace.map { |l| backtrace_line(l) }.compact. + tap do |filtered| + if filtered.empty? + filtered.concat backtrace + filtered << "" + filtered << " Showing full backtrace because every line was filtered out." + filtered << " See docs for RSpec::Configuration#backtrace_exclusion_patterns and" + filtered << " RSpec::Configuration#backtrace_inclusion_patterns for more information." + end + end + end + + def backtrace_line(line) + Metadata.relative_path(line) unless exclude?(line) + end + + def exclude?(line) + return false if @full_backtrace + matches?(exclusion_patterns, line) && !matches?(inclusion_patterns, line) + end + + private + + def matches?(patterns, line) + patterns.any? { |p| line =~ p } + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb new file mode 100644 index 0000000..c4d304b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb @@ -0,0 +1,62 @@ +RSpec::Support.require_rspec_core "bisect/shell_command" +RSpec::Support.require_rspec_core "bisect/example_minimizer" +RSpec::Support.require_rspec_core "bisect/utilities" +RSpec::Support.require_rspec_core "formatters/bisect_progress_formatter" + +module RSpec + module Core + module Bisect + # The main entry point into the bisect logic. Coordinates among: + # - Bisect::ShellCommand: Generates shell commands to run spec subsets + # - Bisect::ExampleMinimizer: Contains the core bisect logic. + # - A bisect runner: runs a set of examples and returns the results. + # - A bisect formatter: provides progress updates to the user. + # @private + class Coordinator + def self.bisect_with(spec_runner, original_cli_args, formatter) + new(spec_runner, original_cli_args, formatter).bisect + end + + def initialize(spec_runner, original_cli_args, formatter) + @spec_runner = spec_runner + @shell_command = ShellCommand.new(original_cli_args) + @notifier = Bisect::Notifier.new(formatter) + end + + def bisect + repro = start_bisect_runner do |runner| + minimizer = ExampleMinimizer.new(@shell_command, runner, @notifier) + + gracefully_abort_on_sigint(minimizer) + minimizer.find_minimal_repro + minimizer.repro_command_for_currently_needed_ids + end + + @notifier.publish(:bisect_repro_command, :repro => repro) + + true + rescue BisectFailedError => e + @notifier.publish(:bisect_failed, :failure_explanation => e.message) + false + ensure + @notifier.publish(:close) + end + + private + + def start_bisect_runner(&block) + klass = @spec_runner.configuration.bisect_runner_class + klass.start(@shell_command, @spec_runner, &block) + end + + def gracefully_abort_on_sigint(minimizer) + trap('INT') do + repro = minimizer.repro_command_for_currently_needed_ids + @notifier.publish(:bisect_aborted, :repro => repro) + exit(1) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb new file mode 100644 index 0000000..e53ca82 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb @@ -0,0 +1,173 @@ +RSpec::Support.require_rspec_core "bisect/utilities" + +module RSpec + module Core + module Bisect + # @private + # Contains the core bisect logic. Searches for examples we can ignore by + # repeatedly running different subsets of the suite. + class ExampleMinimizer + attr_reader :shell_command, :runner, :all_example_ids, :failed_example_ids + attr_accessor :remaining_ids + + def initialize(shell_command, runner, notifier) + @shell_command = shell_command + @runner = runner + @notifier = notifier + end + + def find_minimal_repro + prep + + _, duration = track_duration do + bisect(non_failing_example_ids) + end + + notify(:bisect_complete, :duration => duration, + :original_non_failing_count => non_failing_example_ids.size, + :remaining_count => remaining_ids.size) + + remaining_ids + failed_example_ids + end + + def bisect(candidate_ids) + notify(:bisect_dependency_check_started) + if get_expected_failures_for?([]) + notify(:bisect_dependency_check_failed) + self.remaining_ids = [] + return + end + notify(:bisect_dependency_check_passed) + + bisect_over(candidate_ids) + end + + def bisect_over(candidate_ids) + return if candidate_ids.one? + + notify( + :bisect_round_started, + :candidate_range => example_range(candidate_ids), + :candidates_count => candidate_ids.size + ) + + slice_size = (candidate_ids.length / 2.0).ceil + lhs, rhs = candidate_ids.each_slice(slice_size).to_a + + ids_to_ignore, duration = track_duration do + [lhs, rhs].find do |ids| + get_expected_failures_for?(remaining_ids - ids) + end + end + + if ids_to_ignore + self.remaining_ids -= ids_to_ignore + notify( + :bisect_round_ignoring_ids, + :ids_to_ignore => ids_to_ignore, + :ignore_range => example_range(ids_to_ignore), + :remaining_ids => remaining_ids, + :duration => duration + ) + bisect_over(candidate_ids - ids_to_ignore) + else + notify( + :bisect_round_detected_multiple_culprits, + :duration => duration + ) + bisect_over(lhs) + bisect_over(rhs) + end + end + + def currently_needed_ids + remaining_ids + failed_example_ids + end + + def repro_command_for_currently_needed_ids + return shell_command.repro_command_from(currently_needed_ids) if remaining_ids + "(Not yet enough information to provide any repro command)" + end + + # @private + # Convenience class for describing a subset of the candidate examples + ExampleRange = Struct.new(:start, :finish) do + def description + if start == finish + "example #{start}" + else + "examples #{start}-#{finish}" + end + end + end + + private + + def example_range(ids) + ExampleRange.new( + non_failing_example_ids.find_index(ids.first) + 1, + non_failing_example_ids.find_index(ids.last) + 1 + ) + end + + def prep + notify(:bisect_starting, :original_cli_args => shell_command.original_cli_args, + :bisect_runner => runner.class.name) + + _, duration = track_duration do + original_results = runner.original_results + @all_example_ids = original_results.all_example_ids + @failed_example_ids = original_results.failed_example_ids + @remaining_ids = non_failing_example_ids + end + + if @failed_example_ids.empty? + raise BisectFailedError, "\n\nNo failures found. Bisect only works " \ + "in the presence of one or more failing examples." + else + notify(:bisect_original_run_complete, :failed_example_ids => failed_example_ids, + :non_failing_example_ids => non_failing_example_ids, + :duration => duration) + end + end + + def non_failing_example_ids + @non_failing_example_ids ||= all_example_ids - failed_example_ids + end + + def get_expected_failures_for?(ids) + ids_to_run = all_example_ids & (ids + failed_example_ids) + notify( + :bisect_individual_run_start, + :command => shell_command.repro_command_from(ids_to_run), + :ids_to_run => ids_to_run + ) + + results, duration = track_duration { runner.run(ids_to_run) } + notify(:bisect_individual_run_complete, :duration => duration, :results => results) + + abort_if_ordering_inconsistent(results) + (failed_example_ids & results.failed_example_ids) == failed_example_ids + end + + def track_duration + start = ::RSpec::Core::Time.now + [yield, ::RSpec::Core::Time.now - start] + end + + def abort_if_ordering_inconsistent(results) + expected_order = all_example_ids & results.all_example_ids + return if expected_order == results.all_example_ids + + raise BisectFailedError, "\n\nThe example ordering is inconsistent. " \ + "`--bisect` relies upon consistent ordering (e.g. by passing " \ + "`--seed` if you're using random ordering) to work properly." + end + + def notify(*args) + @notifier.publish(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb new file mode 100644 index 0000000..16d20dc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb @@ -0,0 +1,140 @@ +require 'stringio' +RSpec::Support.require_rspec_core "formatters/base_bisect_formatter" +RSpec::Support.require_rspec_core "bisect/utilities" + +module RSpec + module Core + module Bisect + # A Bisect runner that runs requested subsets of the suite by forking + # sub-processes. The main process bootstraps RSpec and the application + # environment (including preloading files specified via `--require`) so + # that the individual spec runs do not have to re-pay that cost. Each + # spec run happens in a forked process, ensuring that the spec files are + # not loaded in the main process. + # + # For most projects, bisections that use `ForkRunner` instead of + # `ShellRunner` will finish significantly faster, because the `ShellRunner` + # pays the cost of booting RSpec and the app environment on _every_ run of + # a subset. In contrast, `ForkRunner` pays that cost only once. + # + # However, not all projects can use `ForkRunner`. Obviously, on platforms + # that do not support forking (e.g. Windows), it cannot be used. In addition, + # it can cause problems for some projects that put side-effectful spec + # bootstrapping logic that should run on every spec run directly at the top + # level in a file loaded by `--require`, rather than in a `before(:suite)` + # hook. For example, consider a project that relies on some top-level logic + # in `spec_helper` to boot a Redis server for the test suite, intending the + # Redis bootstrapping to happen on every spec run. With `ShellRunner`, the + # bootstrapping logic will happen for each run of any subset of the suite, + # but for `ForkRunner`, such logic will only get run once, when the + # `RunDispatcher` boots the application environment. This might cause + # problems. The solution is for users to move the bootstrapping logic into + # a `before(:suite)` hook, or use the slower `ShellRunner`. + # + # @private + class ForkRunner + def self.start(shell_command, spec_runner) + instance = new(shell_command, spec_runner) + yield instance + ensure + instance.shutdown + end + + def self.name + :fork + end + + def initialize(shell_command, spec_runner) + @shell_command = shell_command + @channel = Channel.new + @run_dispatcher = RunDispatcher.new(spec_runner, @channel) + end + + def run(locations) + run_descriptor = ExampleSetDescriptor.new(locations, original_results.failed_example_ids) + dispatch_run(run_descriptor) + end + + def original_results + @original_results ||= dispatch_run(ExampleSetDescriptor.new( + @shell_command.original_locations, [])) + end + + def shutdown + @channel.close + end + + private + + def dispatch_run(run_descriptor) + @run_dispatcher.dispatch_specs(run_descriptor) + @channel.receive.tap do |result| + if result.is_a?(String) + raise BisectFailedError.for_failed_spec_run(result) + end + end + end + + # @private + class RunDispatcher + def initialize(runner, channel) + @runner = runner + @channel = channel + + @spec_output = StringIO.new + + runner.configuration.tap do |c| + c.reset_reporter + c.output_stream = @spec_output + c.error_stream = @spec_output + end + end + + def dispatch_specs(run_descriptor) + pid = fork { run_specs(run_descriptor) } + # We don't use Process.waitpid here as it was causing bisects to + # block due to the file descriptor limit on OSX / Linux. We need + # to detach the process to avoid having zombie processes + # consuming slots in the kernel process table during bisect runs. + Process.detach(pid) + end + + private + + def run_specs(run_descriptor) + # :nocov: - Executed in a forked process, by integration/bisect_spec + $stdout = $stderr = @spec_output + formatter = CaptureFormatter.new(run_descriptor.failed_example_ids) + + @runner.configuration.tap do |c| + c.files_or_directories_to_run = run_descriptor.all_example_ids + c.formatter = formatter + c.load_spec_files + end + + # `announce_filters` has the side effect of implementing the logic + # that honors `config.run_all_when_everything_filtered` so we need + # to call it here. When we remove `run_all_when_everything_filtered` + # (slated for RSpec 4), we can remove this call to `announce_filters`. + @runner.world.announce_filters + + @runner.run_specs(@runner.world.ordered_example_groups) + latest_run_results = formatter.results + + if latest_run_results.nil? || latest_run_results.all_example_ids.empty? + @channel.send(@spec_output.string) + else + @channel.send(latest_run_results) + end + # :nocov: + end + end + + class CaptureFormatter < Formatters::BaseBisectFormatter + attr_accessor :results + alias_method :notify_results, :results= + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb new file mode 100644 index 0000000..73f0299 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb @@ -0,0 +1,61 @@ +require 'drb/drb' +require 'drb/acl' +RSpec::Support.require_rspec_core "bisect/utilities" + +module RSpec + module Core + # @private + module Bisect + # @private + # A DRb server that receives run results from a separate RSpec process + # started by the bisect process. + class Server + def self.run + server = new + server.start + yield server + ensure + server.stop + end + + def capture_run_results(files_or_directories_to_run=[], expected_failures=[]) + self.expected_failures = expected_failures + self.files_or_directories_to_run = files_or_directories_to_run + self.latest_run_results = nil + run_output = yield + + if latest_run_results.nil? || latest_run_results.all_example_ids.empty? + raise BisectFailedError.for_failed_spec_run(run_output) + end + + latest_run_results + end + + def start + # Only allow remote DRb requests from this machine. + DRb.install_acl ACL.new(%w[ deny all allow localhost allow 127.0.0.1 allow ::1 ]) + + # We pass `nil` as the first arg to allow it to pick a DRb port. + @drb = DRb.start_service(nil, self) + end + + def stop + @drb.stop_service + end + + def drb_port + @drb_port ||= Integer(@drb.uri[/\d+$/]) + end + + # Fetched via DRb by the BisectDRbFormatter to determine when to abort. + attr_accessor :expected_failures + + # Set via DRb by the BisectDRbFormatter with the results of the run. + attr_accessor :latest_run_results + + # Fetched via DRb to tell clients which files to run + attr_accessor :files_or_directories_to_run + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb new file mode 100644 index 0000000..b68f8b1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb @@ -0,0 +1,126 @@ +RSpec::Support.require_rspec_core "shell_escape" +require 'shellwords' + +module RSpec + module Core + module Bisect + # Provides an API to generate shell commands to run the suite for a + # set of locations, using the given bisect server to capture the results. + # @private + class ShellCommand + attr_reader :original_cli_args + + def initialize(original_cli_args) + @original_cli_args = original_cli_args.reject { |arg| arg.start_with?("--bisect") } + end + + def command_for(locations, server) + parts = [] + + parts << RUBY << load_path + parts << open3_safe_escape(RSpec::Core.path_to_executable) + + parts << "--format" << "bisect-drb" + parts << "--drb-port" << server.drb_port + + parts.concat(reusable_cli_options) + parts.concat(locations.map { |l| open3_safe_escape(l) }) + + parts.join(" ") + end + + def repro_command_from(locations) + parts = [] + + parts.concat environment_repro_parts + parts << "rspec" + parts.concat Formatters::Helpers.organize_ids(locations) + parts.concat original_cli_args_without_locations + + parts.join(" ") + end + + def original_locations + parsed_original_cli_options.fetch(:files_or_directories_to_run) + end + + def bisect_environment_hash + if ENV.key?('SPEC_OPTS') + { 'SPEC_OPTS' => spec_opts_without_bisect } + else + {} + end + end + + def spec_opts_without_bisect + Shellwords.join( + Shellwords.split(ENV.fetch('SPEC_OPTS', '')).reject do |arg| + arg =~ /^--bisect/ + end + ) + end + + private + + include RSpec::Core::ShellEscape + # On JRuby, Open3.popen3 does not handle shellescaped args properly: + # https://github.com/jruby/jruby/issues/2767 + if RSpec::Support::Ruby.jruby? + # :nocov: + alias open3_safe_escape quote + # :nocov: + else + alias open3_safe_escape escape + end + + def environment_repro_parts + bisect_environment_hash.map do |k, v| + %Q(#{k}="#{v}") + end + end + + def reusable_cli_options + @reusable_cli_options ||= begin + opts = original_cli_args_without_locations + + if (port = parsed_original_cli_options[:drb_port]) + opts -= %W[ --drb-port #{port} ] + end + + parsed_original_cli_options.fetch(:formatters) { [] }.each do |(name, out)| + opts -= %W[ --format #{name} -f -f#{name} ] + opts -= %W[ --out #{out} -o -o#{out} ] + end + + opts + end + end + + def original_cli_args_without_locations + @original_cli_args_without_locations ||= begin + files_or_dirs = parsed_original_cli_options.fetch(:files_or_directories_to_run) + @original_cli_args - files_or_dirs + end + end + + def parsed_original_cli_options + @parsed_original_cli_options ||= Parser.parse(@original_cli_args) + end + + def load_path + @load_path ||= "-I#{$LOAD_PATH.map { |p| open3_safe_escape(p) }.join(':')}" + end + + # Path to the currently running Ruby executable, borrowed from Rake: + # https://github.com/ruby/rake/blob/v10.4.2/lib/rake/file_utils.rb#L8-L12 + # Note that we skip `ENV['RUBY']` because we don't have to deal with running + # RSpec from within a MRI source repository: + # https://github.com/ruby/rake/commit/968682759b3b65e42748cd2befb2ff3e982272d9 + RUBY = File.join( + RbConfig::CONFIG['bindir'], + RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']). + sub(/.*\s.*/m, '"\&"') + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb new file mode 100644 index 0000000..34afb19 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb @@ -0,0 +1,73 @@ +require 'open3' +RSpec::Support.require_rspec_core "bisect/server" + +module RSpec + module Core + module Bisect + # Provides an API to run the suite for a set of locations, using + # the given bisect server to capture the results. + # + # Sets of specs are run by shelling out. + # @private + class ShellRunner + def self.start(shell_command, _spec_runner) + Server.run do |server| + yield new(server, shell_command) + end + end + + def self.name + :shell + end + + def initialize(server, shell_command) + @server = server + @shell_command = shell_command + end + + def run(locations) + run_locations(locations, original_results.failed_example_ids) + end + + def original_results + @original_results ||= run_locations(@shell_command.original_locations) + end + + private + + def run_locations(*capture_args) + @server.capture_run_results(*capture_args) do + run_command @shell_command.command_for([], @server) + end + end + + # `Open3.capture2e` does not work on JRuby: + # https://github.com/jruby/jruby/issues/2766 + if Open3.respond_to?(:capture2e) && !RSpec::Support::Ruby.jruby? + def run_command(cmd) + Open3.capture2e(@shell_command.bisect_environment_hash, cmd).first + end + else # for 1.8.7 + # :nocov: + def run_command(cmd) + out = err = nil + + original_spec_opts = ENV['SPEC_OPTS'] + ENV['SPEC_OPTS'] = @shell_command.spec_opts_without_bisect + + Open3.popen3(cmd) do |_, stdout, stderr| + # Reading the streams blocks until the process is complete + out = stdout.read + err = stderr.read + end + + "Stdout:\n#{out}\n\nStderr:\n#{err}" + ensure + ENV['SPEC_OPTS'] = original_spec_opts + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb new file mode 100644 index 0000000..4600f35 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb @@ -0,0 +1,69 @@ +module RSpec + module Core + module Bisect + # @private + ExampleSetDescriptor = Struct.new(:all_example_ids, :failed_example_ids) + + # @private + class BisectFailedError < StandardError + def self.for_failed_spec_run(spec_output) + new("Failed to get results from the spec run. Spec run output:\n\n" + + spec_output) + end + end + + # Wraps a `formatter` providing a simple means to notify it in place + # of an `RSpec::Core::Reporter`, without involving configuration in + # any way. + # @private + class Notifier + def initialize(formatter) + @formatter = formatter + end + + def publish(event, *args) + return unless @formatter.respond_to?(event) + notification = Notifications::CustomNotification.for(*args) + @formatter.__send__(event, notification) + end + end + + # Wraps a pipe to support sending objects between a child and + # parent process. Where supported, encoding is explicitly + # set to ensure binary data is able to pass from child to + # parent. + # @private + class Channel + if String.method_defined?(:encoding) + MARSHAL_DUMP_ENCODING = Marshal.dump("").encoding + end + + def initialize + @read_io, @write_io = IO.pipe + + if defined?(MARSHAL_DUMP_ENCODING) && IO.method_defined?(:set_encoding) + # Ensure the pipe can send any content produced by Marshal.dump + @write_io.set_encoding MARSHAL_DUMP_ENCODING + end + end + + def send(message) + packet = Marshal.dump(message) + @write_io.write("#{packet.bytesize}\n#{packet}") + end + + # rubocop:disable Security/MarshalLoad + def receive + packet_size = Integer(@read_io.gets) + Marshal.load(@read_io.read(packet_size)) + end + # rubocop:enable Security/MarshalLoad + + def close + @read_io.close + @write_io.close + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb new file mode 100644 index 0000000..c207b7a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb @@ -0,0 +1,2419 @@ +RSpec::Support.require_rspec_core "backtrace_formatter" +RSpec::Support.require_rspec_core "ruby_project" +RSpec::Support.require_rspec_core "formatters/deprecation_formatter" +RSpec::Support.require_rspec_core "output_wrapper" + +module RSpec + module Core + # rubocop:disable Metrics/ClassLength + + # Stores runtime configuration information. + # + # Configuration options are loaded from multiple files and joined together + # with command-line switches and the `SPEC_OPTS` environment variable. + # + # Precedence order (where later entries overwrite earlier entries on + # conflicts): + # + # * Global (`$XDG_CONFIG_HOME/rspec/options`, or `~/.rspec` if it does + # not exist) + # * Project-specific (`./.rspec`) + # * Local (`./.rspec-local`) + # * Command-line options + # * `SPEC_OPTS` + # + # For example, an option set in the local file will override an option set + # in your global file. + # + # The global, project-specific and local files can all be overridden with a + # separate custom file using the --options command-line parameter. + # + # @example Standard settings + # RSpec.configure do |c| + # c.drb = true + # c.drb_port = 1234 + # c.default_path = 'behavior' + # end + # + # @example Hooks + # RSpec.configure do |c| + # c.before(:suite) { establish_connection } + # c.before(:example) { log_in_as :authorized } + # c.around(:example) { |ex| Database.transaction(&ex) } + # end + # + # @see RSpec.configure + # @see Hooks + class Configuration + include RSpec::Core::Hooks + + # Module that holds `attr_reader` declarations. It's in a separate + # module to allow us to override those methods and use `super`. + # @private + Readers = Module.new + include Readers + + # @private + class MustBeConfiguredBeforeExampleGroupsError < StandardError; end + + # @private + def self.define_reader(name) + Readers.class_eval do + remove_method name if method_defined?(name) + attr_reader name + end + + define_method(name) { value_for(name) { super() } } + end + + # @private + def self.define_alias(name, alias_name) + alias_method alias_name, name + alias_method "#{alias_name}=", "#{name}=" + define_predicate alias_name + end + + # @private + def self.define_predicate(name) + define_method "#{name}?" do + !!send(name) + end + end + + # @private + # + # Invoked by the `add_setting` instance method. Use that method on a + # `Configuration` instance rather than this class method. + def self.add_setting(name, opts={}) + raise "Use the instance add_setting method if you want to set a default" if opts.key?(:default) + attr_writer name + add_read_only_setting name + + Array(opts[:alias_with]).each do |alias_name| + define_alias(name, alias_name) + end + end + + # @private + # + # As `add_setting` but only add the reader. + def self.add_read_only_setting(name, opts={}) + raise "Use the instance add_setting method if you want to set a default" if opts.key?(:default) + define_reader name + define_predicate name + end + + # @macro [attach] add_setting + # @!attribute [rw] $1 + # + # @macro [attach] define_reader + # @!attribute [r] $1 + + # @macro add_setting + # Path to use if no path is provided to the `rspec` command (default: + # `"spec"`). Allows you to just type `rspec` instead of `rspec spec` to + # run all the examples in the `spec` directory. + # + # @note Other scripts invoking `rspec` indirectly will ignore this + # setting. + # @return [String] + add_read_only_setting :default_path + def default_path=(path) + project_source_dirs << path + @default_path = path + end + + # @macro add_setting + # Run examples over DRb (default: `false`). RSpec doesn't supply the DRb + # server, but you can use tools like spork. + # @return [Boolean] + add_setting :drb + + # @macro add_setting + # The drb_port (default: nil). + add_setting :drb_port + + # @macro add_setting + # Default: `$stderr`. + add_setting :error_stream + + # Indicates if the DSL has been exposed off of modules and `main`. + # Default: true + # @return [Boolean] + def expose_dsl_globally? + Core::DSL.exposed_globally? + end + + # Use this to expose the core RSpec DSL via `Module` and the `main` + # object. It will be set automatically but you can override it to + # remove the DSL. + # Default: true + def expose_dsl_globally=(value) + if value + Core::DSL.expose_globally! + Core::SharedExampleGroup::TopLevelDSL.expose_globally! + else + Core::DSL.remove_globally! + Core::SharedExampleGroup::TopLevelDSL.remove_globally! + end + end + + # Determines where deprecation warnings are printed. + # Defaults to `$stderr`. + # @return [IO, String] IO or filename to write to + define_reader :deprecation_stream + + # Determines where deprecation warnings are printed. + # @param value [IO, String] IO to write to or filename to write to + def deprecation_stream=(value) + if @reporter && !value.equal?(@deprecation_stream) + warn "RSpec's reporter has already been initialized with " \ + "#{deprecation_stream.inspect} as the deprecation stream, so your change to "\ + "`deprecation_stream` will be ignored. You should configure it earlier for " \ + "it to take effect, or use the `--deprecation-out` CLI option. " \ + "(Called from #{CallerFilter.first_non_rspec_line})" + else + @deprecation_stream = value + end + end + + # @macro define_reader + # The file path to use for persisting example statuses. Necessary for the + # `--only-failures` and `--next-failure` CLI options. + # + # @overload example_status_persistence_file_path + # @return [String] the file path + # @overload example_status_persistence_file_path=(value) + # @param value [String] the file path + define_reader :example_status_persistence_file_path + + # Sets the file path to use for persisting example statuses. Necessary for the + # `--only-failures` and `--next-failure` CLI options. + def example_status_persistence_file_path=(value) + @example_status_persistence_file_path = value + clear_values_derived_from_example_status_persistence_file_path + end + + # @macro define_reader + # Indicates if the `--only-failures` (or `--next-failure`) flag is being used. + define_reader :only_failures + alias_method :only_failures?, :only_failures + + # @private + def only_failures_but_not_configured? + only_failures? && !example_status_persistence_file_path + end + + # @macro define_reader + # If specified, indicates the number of failures required before cleaning + # up and exit (default: `nil`). Can also be `true` to fail and exit on first + # failure + define_reader :fail_fast + + # @see fail_fast + def fail_fast=(value) + case value + when true, 'true' + @fail_fast = true + when false, 'false', 0 + @fail_fast = false + when nil + @fail_fast = nil + else + @fail_fast = value.to_i + + if value.to_i == 0 + # TODO: in RSpec 4, consider raising an error here. + RSpec.warning "Cannot set `RSpec.configuration.fail_fast`" \ + " to `#{value.inspect}`. Only `true`, `false`, `nil` and integers" \ + " are valid values." + @fail_fast = true + end + end + end + + # @macro add_setting + # Prints the formatter output of your suite without running any + # examples or hooks. + add_setting :dry_run + + # @macro add_setting + # The exit code to return if there are any failures (default: 1). + # @return [Integer] + add_setting :failure_exit_code + + # @macro add_setting + # The exit code to return if there are any errors outside examples (default: failure_exit_code) + # @return [Integer] + add_setting :error_exit_code + + # @macro add_setting + # Whether or not to fail when there are no RSpec examples (default: false). + # @return [Boolean] + add_setting :fail_if_no_examples + + # @macro define_reader + # Indicates files configured to be required. + # @return [Array] + define_reader :requires + + # @macro define_reader + # Returns dirs that have been prepended to the load path by the `-I` + # command line option. + # @return [Array] + define_reader :libs + + # @macro add_setting + # Determines where RSpec will send its output. + # Default: `$stdout`. + # @return [IO, String] + define_reader :output_stream + + # Set the output stream for reporter. + # @attr value [IO, String] IO to write to or filename to write to, defaults to $stdout + def output_stream=(value) + if @reporter && !value.equal?(@output_stream) + warn "RSpec's reporter has already been initialized with " \ + "#{output_stream.inspect} as the output stream, so your change to "\ + "`output_stream` will be ignored. You should configure it earlier for " \ + "it to take effect. (Called from #{CallerFilter.first_non_rspec_line})" + else + @output_stream = value + output_wrapper.output = @output_stream + end + end + + # @macro define_reader + # Load files matching this pattern (default: `'**{,/*/**}/*_spec.rb'`). + # @return [String] + define_reader :pattern + + # Set pattern to match files to load. + # @attr value [String] the filename pattern to filter spec files by + def pattern=(value) + update_pattern_attr :pattern, value + end + + # @macro define_reader + # Exclude files matching this pattern. + # @return [String] + define_reader :exclude_pattern + + # Set pattern to match files to exclude. + # @attr value [String] the filename pattern to exclude spec files by + def exclude_pattern=(value) + update_pattern_attr :exclude_pattern, value + end + + # @macro add_setting + # Specifies which directories contain the source code for your project. + # When a failure occurs, RSpec looks through the backtrace to find a + # a line of source to print. It first looks for a line coming from + # one of the project source directories so that, for example, it prints + # the expectation or assertion call rather than the source code from + # the expectation or assertion framework. + # @return [Array] + add_setting :project_source_dirs + + # @macro add_setting + # Report the times for the slowest examples (default: `false`). + # Use this to specify the number of examples to include in the profile. + # @return [Boolean] + attr_writer :profile_examples + define_predicate :profile_examples + + # @macro add_setting + # Run all examples if none match the configured filters + # (default: `false`). + # @deprecated Use {#filter_run_when_matching} instead for the specific + # filters that you want to be ignored if none match. + add_setting :run_all_when_everything_filtered + + # @macro add_setting + # Color to use to indicate success. Defaults to `:green` but can be set + # to one of the following: `[:black, :white, :red, :green, :yellow, + # :blue, :magenta, :cyan]` + # @return [Symbol] + add_setting :success_color + + # @macro add_setting + # Color to use to print pending examples. Defaults to `:yellow` but can + # be set to one of the following: `[:black, :white, :red, :green, + # :yellow, :blue, :magenta, :cyan]` + # @return [Symbol] + add_setting :pending_color + + # @macro add_setting + # Color to use to indicate failure. Defaults to `:red` but can be set to + # one of the following: `[:black, :white, :red, :green, :yellow, :blue, + # :magenta, :cyan]` + # @return [Symbol] + add_setting :failure_color + + # @macro add_setting + # The default output color. Defaults to `:white` but can be set to one of + # the following: `[:black, :white, :red, :green, :yellow, :blue, + # :magenta, :cyan]` + # @return [Symbol] + add_setting :default_color + + # @macro add_setting + # Color used when a pending example is fixed. Defaults to `:blue` but can + # be set to one of the following: `[:black, :white, :red, :green, + # :yellow, :blue, :magenta, :cyan]` + # @return [Symbol] + add_setting :fixed_color + + # @macro add_setting + # Color used to print details. Defaults to `:cyan` but can be set to one + # of the following: `[:black, :white, :red, :green, :yellow, :blue, + # :magenta, :cyan]` + # @return [Symbol] + add_setting :detail_color + + # @macro add_setting + # Don't print filter info i.e. "Run options: include {:focus=>true}" + # (default `false`). + # return [Boolean] + add_setting :silence_filter_announcements + + # @deprecated This config option was added in RSpec 2 to pave the way + # for this being the default behavior in RSpec 3. Now this option is + # a no-op. + def treat_symbols_as_metadata_keys_with_true_values=(_value) + RSpec.deprecate( + "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=", + :message => "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values= " \ + "is deprecated, it is now set to true as default and " \ + "setting it to false has no effect." + ) + end + + # @macro define_reader + # Configures how RSpec treats metadata passed as part of a shared example + # group definition. For example, given this shared example group definition: + # + # RSpec.shared_context "uses DB", :db => true do + # around(:example) do |ex| + # MyORM.transaction(:rollback => true, &ex) + # end + # end + # + # ...there are two ways RSpec can treat the `:db => true` metadata, each + # of which has a corresponding config option: + # + # 1. `:trigger_inclusion`: this shared context will be implicitly included + # in any groups (or examples) that have `:db => true` metadata. + # 2. `:apply_to_host_groups`: the metadata will be inherited by the metadata + # hash of all host groups and examples. + # + # `:trigger_inclusion` is the legacy behavior from before RSpec 3.5 but should + # be considered deprecated. Instead, you can explicitly include a group with + # `include_context`: + # + # RSpec.describe "My model" do + # include_context "uses DB" + # end + # + # ...or you can configure RSpec to include the context based on matching metadata + # using an API that mirrors configured module inclusion: + # + # RSpec.configure do |rspec| + # rspec.include_context "uses DB", :db => true + # end + # + # `:apply_to_host_groups` is a new feature of RSpec 3.5 and will be the only + # supported behavior in RSpec 4. + # + # @overload shared_context_metadata_behavior + # @return [:trigger_inclusion, :apply_to_host_groups] the configured behavior + # @overload shared_context_metadata_behavior=(value) + # @param value [:trigger_inclusion, :apply_to_host_groups] sets the configured behavior + define_reader :shared_context_metadata_behavior + # @see shared_context_metadata_behavior + def shared_context_metadata_behavior=(value) + case value + when :trigger_inclusion, :apply_to_host_groups + @shared_context_metadata_behavior = value + else + raise ArgumentError, "Cannot set `RSpec.configuration." \ + "shared_context_metadata_behavior` to `#{value.inspect}`. Only " \ + "`:trigger_inclusion` and `:apply_to_host_groups` are valid values." + end + end + + # Record the start time of the spec suite to measure load time. + # return [Time] + add_setting :start_time + + # @macro add_setting + # Use threadsafe options where available. + # Currently this will place a mutex around memoized values such as let blocks. + # return [Boolean] + add_setting :threadsafe + + # @macro add_setting + # Maximum count of failed source lines to display in the failure reports + # (defaults to `10`). + # return [Integer] + add_setting :max_displayed_failure_line_count + + # @macro full_cause_backtrace + # Display the full backtrace of an exceptions cause (defaults to `false`). + # return [Boolean] + add_setting :full_cause_backtrace + + # @macro add_setting + # Format the output for pending examples. Can be set to: + # - :full (default) - pending examples appear similarly to failures + # - :no_backtrace - same as above, but with no backtrace + # - :skip - do not show the section at all + # return [Symbol] + add_read_only_setting :pending_failure_output + def pending_failure_output=(mode) + raise ArgumentError, + "`pending_failure_output` can be set to :full, :no_backtrace, " \ + "or :skip" unless [:full, :no_backtrace, :skip].include?(mode) + @pending_failure_output = mode + end + + # Determines which bisect runner implementation gets used to run subsets + # of the suite during a bisection. Your choices are: + # + # - `:shell`: Performs a spec run by shelling out, booting RSpec and your + # application environment each time. This runner is the most widely + # compatible runner, but is not as fast. On platforms that do not + # support forking, this is the default. + # - `:fork`: Pre-boots RSpec and your application environment in a parent + # process, and then forks a child process for each spec run. This runner + # tends to be significantly faster than the `:shell` runner but cannot + # be used in some situations. On platforms that support forking, this + # is the default. If you use this runner, you should ensure that all + # of your one-time setup logic goes in a `before(:suite)` hook instead + # of getting run at the top-level of a file loaded by `--require`. + # + # @note This option will only be used by `--bisect` if you set it in a file + # loaded via `--require`. + # + # @return [Symbol] + attr_reader :bisect_runner + def bisect_runner=(value) + if @bisect_runner_class && value != @bisect_runner + raise "`config.bisect_runner = #{value.inspect}` can no longer take " \ + "effect as the #{@bisect_runner.inspect} bisect runnner is already " \ + "in use. This config setting must be set in a file loaded by a " \ + "`--require` option (passed at the CLI or in a `.rspec` file) for " \ + "it to have any effect." + end + + @bisect_runner = value + end + + # @private + # @deprecated Use {#color_mode} = :on, instead of {#color} with {#tty} + add_setting :tty + # @private + attr_writer :files_to_run + # @private + attr_accessor :filter_manager, :world + # @private + attr_accessor :static_config_filter_manager + # @private + attr_reader :backtrace_formatter, :ordering_manager, :loaded_spec_files + + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/MethodLength + + # Build an object to store runtime configuration options and set defaults + def initialize + # rubocop:disable Style/GlobalVars + @start_time = $_rspec_core_load_started_at || ::RSpec::Core::Time.now + # rubocop:enable Style/GlobalVars + @expectation_frameworks = [] + @include_modules = FilterableItemRepository::QueryOptimized.new(:any?) + @extend_modules = FilterableItemRepository::QueryOptimized.new(:any?) + @prepend_modules = FilterableItemRepository::QueryOptimized.new(:any?) + + @bisect_runner = RSpec::Support::RubyFeatures.fork_supported? ? :fork : :shell + @bisect_runner_class = nil + + @before_suite_hooks = [] + @after_suite_hooks = [] + + @mock_framework = nil + @files_or_directories_to_run = [] + @loaded_spec_files = Set.new + @color = false + @color_mode = :automatic + @pattern = '**{,/*/**}/*_spec.rb' + @exclude_pattern = '' + @failure_exit_code = 1 + @error_exit_code = nil # so it can be overridden by failure exit code + @fail_if_no_examples = false + @spec_files_loaded = false + + @backtrace_formatter = BacktraceFormatter.new + + @default_path = 'spec' + @project_source_dirs = %w[ spec lib app ] + @deprecation_stream = $stderr + @output_stream = $stdout + @reporter = nil + @reporter_buffer = nil + @filter_manager = FilterManager.new + @static_config_filter_manager = FilterManager.new + @ordering_manager = Ordering::ConfigurationManager.new + @preferred_options = {} + @failure_color = :red + @success_color = :green + @pending_color = :yellow + @default_color = :white + @fixed_color = :blue + @detail_color = :cyan + @profile_examples = false + @requires = [] + @libs = [] + @derived_metadata_blocks = FilterableItemRepository::QueryOptimized.new(:any?) + @threadsafe = true + @max_displayed_failure_line_count = 10 + @full_cause_backtrace = false + @world = World::Null + @shared_context_metadata_behavior = :trigger_inclusion + @pending_failure_output = :full + + define_built_in_hooks + end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/MethodLength + + # @private + # + # Used to set higher priority option values from the command line. + def force(hash) + ordering_manager.force(hash) + @preferred_options.merge!(hash) + + return unless hash.key?(:example_status_persistence_file_path) + clear_values_derived_from_example_status_persistence_file_path + end + + # @private + def reset + @spec_files_loaded = false + reset_reporter + end + + # @private + def reset_reporter + @reporter = nil + @formatter_loader = nil + @output_wrapper = nil + end + + # @private + def reset_filters + self.filter_manager = FilterManager.new + filter_manager.include_only( + Metadata.deep_hash_dup(static_config_filter_manager.inclusions.rules) + ) + filter_manager.exclude_only( + Metadata.deep_hash_dup(static_config_filter_manager.exclusions.rules) + ) + end + + # @overload add_setting(name) + # @overload add_setting(name, opts) + # @option opts [Symbol] :default + # + # Set a default value for the generated getter and predicate methods: + # + # add_setting(:foo, :default => "default value") + # + # @option opts [Symbol] :alias_with + # + # Use `:alias_with` to alias the setter, getter, and predicate to + # another name, or names: + # + # add_setting(:foo, :alias_with => :bar) + # add_setting(:foo, :alias_with => [:bar, :baz]) + # + # Adds a custom setting to the RSpec.configuration object. + # + # RSpec.configuration.add_setting :foo + # + # Used internally and by extension frameworks like rspec-rails, so they + # can add config settings that are domain specific. For example: + # + # RSpec.configure do |c| + # c.add_setting :use_transactional_fixtures, + # :default => true, + # :alias_with => :use_transactional_examples + # end + # + # `add_setting` creates three methods on the configuration object, a + # setter, a getter, and a predicate: + # + # RSpec.configuration.foo=(value) + # RSpec.configuration.foo + # RSpec.configuration.foo? # Returns true if foo returns anything but nil or false. + def add_setting(name, opts={}) + default = opts.delete(:default) + (class << self; self; end).class_exec do + add_setting(name, opts) + end + __send__("#{name}=", default) if default + end + + # Returns the configured mock framework adapter module. + # @return [Symbol] + def mock_framework + if @mock_framework.nil? + begin + mock_with :rspec + rescue LoadError + mock_with :nothing + end + end + @mock_framework + end + + # Delegates to mock_framework=(framework). + def mock_framework=(framework) + mock_with framework + end + + # Regexps used to exclude lines from backtraces. + # + # Excludes lines from ruby (and jruby) source, installed gems, anything + # in any "bin" directory, and any of the RSpec libs (outside gem + # installs) by default. + # + # You can modify the list via the getter, or replace it with the setter. + # + # To override this behaviour and display a full backtrace, use + # `--backtrace` on the command line, in a `.rspec` file, or in the + # `rspec_options` attribute of RSpec's rake task. + # @return [Array] + def backtrace_exclusion_patterns + @backtrace_formatter.exclusion_patterns + end + + # Set regular expressions used to exclude lines in backtrace. + # @param patterns [Array] set backtrace_formatter exclusion_patterns + def backtrace_exclusion_patterns=(patterns) + @backtrace_formatter.exclusion_patterns = patterns + end + + # Regexps used to include lines in backtraces. + # + # Defaults to [Regexp.new Dir.getwd]. + # + # Lines that match an exclusion _and_ an inclusion pattern + # will be included. + # + # You can modify the list via the getter, or replace it with the setter. + # @return [Array] + def backtrace_inclusion_patterns + @backtrace_formatter.inclusion_patterns + end + + # Set regular expressions used to include lines in backtrace. + # @attr patterns [Array] set backtrace_formatter inclusion_patterns + def backtrace_inclusion_patterns=(patterns) + @backtrace_formatter.inclusion_patterns = patterns + end + + # Adds {#backtrace_exclusion_patterns} that will filter lines from + # the named gems from backtraces. + # + # @param gem_names [Array] Names of the gems to filter + # + # @example + # RSpec.configure do |config| + # config.filter_gems_from_backtrace "rack", "rake" + # end + # + # @note The patterns this adds will match the named gems in their common + # locations (e.g. system gems, vendored with bundler, installed as a + # :git dependency with bundler, etc) but is not guaranteed to work for + # all possible gem locations. For example, if you have the gem source + # in a directory with a completely unrelated name, and use bundler's + # :path option, this will not filter it. + def filter_gems_from_backtrace(*gem_names) + gem_names.each do |name| + @backtrace_formatter.filter_gem(name) + end + end + + # @private + MOCKING_ADAPTERS = { + :rspec => :RSpec, + :flexmock => :Flexmock, + :rr => :RR, + :mocha => :Mocha, + :nothing => :Null + } + + # Sets the mock framework adapter module. + # + # `framework` can be a Symbol or a Module. + # + # Given any of `:rspec`, `:mocha`, `:flexmock`, or `:rr`, configures the + # named framework. + # + # Given `:nothing`, configures no framework. Use this if you don't use + # any mocking framework to save a little bit of overhead. + # + # Given a Module, includes that module in every example group. The module + # should adhere to RSpec's mock framework adapter API: + # + # setup_mocks_for_rspec + # - called before each example + # + # verify_mocks_for_rspec + # - called after each example if the example hasn't yet failed. + # Framework should raise an exception when expectations fail + # + # teardown_mocks_for_rspec + # - called after verify_mocks_for_rspec (even if there are errors) + # + # If the module responds to `configuration` and `mock_with` receives a + # block, it will yield the configuration object to the block e.g. + # + # config.mock_with OtherMockFrameworkAdapter do |mod_config| + # mod_config.custom_setting = true + # end + def mock_with(framework) + framework_module = + if framework.is_a?(Module) + framework + else + const_name = MOCKING_ADAPTERS.fetch(framework) do + raise ArgumentError, + "Unknown mocking framework: #{framework.inspect}. " \ + "Pass a module or one of #{MOCKING_ADAPTERS.keys.inspect}" + end + + RSpec::Support.require_rspec_core "mocking_adapters/#{const_name.to_s.downcase}" + RSpec::Core::MockingAdapters.const_get(const_name) + end + + new_name, old_name = [framework_module, @mock_framework].map do |mod| + mod.respond_to?(:framework_name) ? mod.framework_name : :unnamed + end + + unless new_name == old_name + assert_no_example_groups_defined(:mock_framework) + end + + if block_given? + raise "#{framework_module} must respond to `configuration` so that " \ + "mock_with can yield it." unless framework_module.respond_to?(:configuration) + yield framework_module.configuration + end + + @mock_framework = framework_module + end + + # Returns the configured expectation framework adapter module(s) + def expectation_frameworks + if @expectation_frameworks.empty? + begin + expect_with :rspec + rescue LoadError + expect_with Module.new + end + end + @expectation_frameworks + end + + # Delegates to expect_with(framework). + def expectation_framework=(framework) + expect_with(framework) + end + + # Sets the expectation framework module(s) to be included in each example + # group. + # + # `frameworks` can be `:rspec`, `:test_unit`, `:minitest`, a custom + # module, or any combination thereof: + # + # config.expect_with :rspec + # config.expect_with :test_unit + # config.expect_with :minitest + # config.expect_with :rspec, :minitest + # config.expect_with OtherExpectationFramework + # + # RSpec will translate `:rspec`, `:minitest`, and `:test_unit` into the + # appropriate modules. + # + # ## Configuration + # + # If the module responds to `configuration`, `expect_with` will + # yield the `configuration` object if given a block: + # + # config.expect_with OtherExpectationFramework do |custom_config| + # custom_config.custom_setting = true + # end + def expect_with(*frameworks) + modules = frameworks.map do |framework| + case framework + when Module + framework + when :rspec + require 'rspec/expectations' + + # Tag this exception class so our exception formatting logic knows + # that it satisfies the `MultipleExceptionError` interface. + ::RSpec::Expectations::MultipleExpectationsNotMetError.__send__( + :include, MultipleExceptionError::InterfaceTag + ) + + ::RSpec::Matchers + when :test_unit + require 'rspec/core/test_unit_assertions_adapter' + ::RSpec::Core::TestUnitAssertionsAdapter + when :minitest + require 'rspec/core/minitest_assertions_adapter' + ::RSpec::Core::MinitestAssertionsAdapter + else + raise ArgumentError, "#{framework.inspect} is not supported" + end + end + + if (modules - @expectation_frameworks).any? + assert_no_example_groups_defined(:expect_with) + end + + if block_given? + raise "expect_with only accepts a block with a single argument. " \ + "Call expect_with #{modules.length} times, " \ + "once with each argument, instead." if modules.length > 1 + raise "#{modules.first} must respond to `configuration` so that " \ + "expect_with can yield it." unless modules.first.respond_to?(:configuration) + yield modules.first.configuration + end + + @expectation_frameworks.push(*modules) + end + + # Check if full backtrace is enabled. + # @return [Boolean] is full backtrace enabled + def full_backtrace? + @backtrace_formatter.full_backtrace? + end + + # Toggle full backtrace. + # @attr true_or_false [Boolean] toggle full backtrace display + def full_backtrace=(true_or_false) + @backtrace_formatter.full_backtrace = true_or_false + end + + # Enables color output if the output is a TTY. As of RSpec 3.6, this is + # the default behavior and this option is retained only for backwards + # compatibility. + # + # @deprecated No longer recommended because of complex behavior. Instead, + # rely on the fact that TTYs will display color by default, or set + # {#color_mode} to :on to display color on a non-TTY output. + # @see color_mode + # @see color_enabled? + # @return [Boolean] + def color + value_for(:color) { @color } + end + + # The mode for determining whether to display output in color. One of: + # + # - :automatic - the output will be in color if the output is a TTY (the + # default) + # - :on - the output will be in color, whether or not the output is a TTY + # - :off - the output will not be in color + # + # @see color_enabled? + # @return [Boolean] + def color_mode + value_for(:color_mode) { @color_mode } + end + + # Check if color is enabled for a particular output. + # @param output [IO] an output stream to use, defaults to the current + # `output_stream` + # @return [Boolean] + def color_enabled?(output=output_stream) + case color_mode + when :on then true + when :off then false + else # automatic + output_to_tty?(output) || (color && tty?) + end + end + + # Set the color mode. + attr_writer :color_mode + + # Toggle output color. + # + # @deprecated No longer recommended because of complex behavior. Instead, + # rely on the fact that TTYs will display color by default, or set + # {:color_mode} to :on to display color on a non-TTY output. + attr_writer :color + + # @private + def libs=(libs) + libs.map do |lib| + @libs.unshift lib + $LOAD_PATH.unshift lib + end + end + + # Run examples matching on `description` in all files to run. + # @param description [String, Regexp] the pattern to filter on + def full_description=(description) + filter_run :full_description => Regexp.union(*Array(description).map { |d| Regexp.new(d) }) + end + + # @return [Array] full description filter + def full_description + filter.fetch :full_description, nil + end + + # @overload add_formatter(formatter) + # @overload add_formatter(formatter, output) + # + # @param formatter [Class, String, Object] formatter to use. Can be any of the + # string values supported from the CLI (`p`/`progress`, + # `d`/`doc`/`documentation`, `h`/`html`, or `j`/`json`), any + # class that implements the formatter protocol and has registered + # itself with RSpec as a formatter, or a formatter instance. + # @param output [String, IO] where the formatter will write its output. + # Can be an IO object or a string path to a file. If not provided, + # the configured `output_stream` (`$stdout`, by default) will be used. + # + # Adds a formatter to the set RSpec will use for this run. + # + # @see RSpec::Core::Formatters::Protocol + def add_formatter(formatter, output=output_wrapper) + formatter_loader.add(formatter, output) + end + alias_method :formatter=, :add_formatter + + # The formatter that will be used if no formatter has been set. + # Defaults to 'progress'. + def default_formatter + formatter_loader.default_formatter + end + + # Sets a fallback formatter to use if none other has been set. + # + # @example + # + # RSpec.configure do |rspec| + # rspec.default_formatter = 'doc' + # end + def default_formatter=(value) + formatter_loader.default_formatter = value + end + + # Returns a duplicate of the formatters currently loaded in + # the `FormatterLoader` for introspection. + # + # Note as this is a duplicate, any mutations will be disregarded. + # + # @return [Array] the formatters currently loaded + def formatters + formatter_loader.formatters.dup + end + + # @private + def formatter_loader + @formatter_loader ||= Formatters::Loader.new(Reporter.new(self)) + end + + # @private + # + # This buffer is used to capture all messages sent to the reporter during + # reporter initialization. It can then replay those messages after the + # formatter is correctly initialized. Otherwise, deprecation warnings + # during formatter initialization can cause an infinite loop. + class DeprecationReporterBuffer + def initialize + @calls = [] + end + + def deprecation(*args) + @calls << args + end + + def play_onto(reporter) + @calls.each do |args| + reporter.deprecation(*args) + end + end + end + + # @return [RSpec::Core::Reporter] the currently configured reporter + def reporter + # @reporter_buffer should only ever be set in this method to cover + # initialization of @reporter. + @reporter_buffer || @reporter ||= + begin + @reporter_buffer = DeprecationReporterBuffer.new + formatter_loader.prepare_default output_wrapper, deprecation_stream + @reporter_buffer.play_onto(formatter_loader.reporter) + @reporter_buffer = nil + formatter_loader.reporter + end + end + + # @api private + # + # Defaults `profile_examples` to 10 examples when `@profile_examples` is + # `true`. + def profile_examples + profile = value_for(:profile_examples) { @profile_examples } + if profile && !profile.is_a?(Integer) + 10 + else + profile + end + end + + # @private + def files_or_directories_to_run=(*files) + files = files.flatten + + if (command == 'rspec' || Runner.running_in_drb?) && default_path && files.empty? + files << default_path + end + + @files_or_directories_to_run = files + @files_to_run = nil + end + + # The spec files RSpec will run. + # @return [Array] specified files about to run + def files_to_run + @files_to_run ||= get_files_to_run(@files_or_directories_to_run) + end + + # @private + def last_run_statuses + @last_run_statuses ||= Hash.new(UNKNOWN_STATUS).tap do |statuses| + if (path = example_status_persistence_file_path) + begin + ExampleStatusPersister.load_from(path).inject(statuses) do |hash, example| + status = example[:status] + status = UNKNOWN_STATUS unless VALID_STATUSES.include?(status) + hash[example.fetch(:example_id)] = status + hash + end + rescue SystemCallError => e + RSpec.warning "Could not read from #{path.inspect} (configured as " \ + "`config.example_status_persistence_file_path`) due " \ + "to a system error: #{e.inspect}. Please check that " \ + "the config option is set to an accessible, valid " \ + "file path", :call_site => nil + end + end + end + end + + # @private + UNKNOWN_STATUS = "unknown".freeze + + # @private + FAILED_STATUS = "failed".freeze + + # @private + PASSED_STATUS = "passed".freeze + + # @private + PENDING_STATUS = "pending".freeze + + # @private + VALID_STATUSES = [UNKNOWN_STATUS, FAILED_STATUS, PASSED_STATUS, PENDING_STATUS] + + # @private + def spec_files_with_failures + @spec_files_with_failures ||= last_run_statuses.inject(Set.new) do |files, (id, status)| + files << Example.parse_id(id).first if status == FAILED_STATUS + files + end.to_a + end + + # Creates a method that delegates to `example` including the submitted + # `args`. Used internally to add variants of `example` like `pending`: + # @param name [String] example name alias + # @param args [Array, Hash] metadata for the generated example + # + # @note The specific example alias below (`pending`) is already + # defined for you. + # @note Use with caution. This extends the language used in your + # specs, but does not add any additional documentation. We use this + # in RSpec to define methods like `focus` and `xit`, but we also add + # docs for those methods. + # + # @example + # RSpec.configure do |config| + # config.alias_example_to :pending, :pending => true + # end + # + # # This lets you do this: + # + # RSpec.describe Thing do + # pending "does something" do + # thing = Thing.new + # end + # end + # + # # ... which is the equivalent of + # + # RSpec.describe Thing do + # it "does something", :pending => true do + # thing = Thing.new + # end + # end + def alias_example_to(name, *args) + extra_options = Metadata.build_hash_from(args) + RSpec::Core::ExampleGroup.define_example_method(name, extra_options) + end + + # Creates a method that defines an example group with the provided + # metadata. Can be used to define example group/metadata shortcuts. + # + # @example + # RSpec.configure do |config| + # config.alias_example_group_to :describe_model, :type => :model + # end + # + # shared_context_for "model tests", :type => :model do + # # define common model test helper methods, `let` declarations, etc + # end + # + # # This lets you do this: + # + # RSpec.describe_model User do + # end + # + # # ... which is the equivalent of + # + # RSpec.describe User, :type => :model do + # end + # + # @note The defined aliased will also be added to the top level + # (e.g. `main` and from within modules) if + # `expose_dsl_globally` is set to true. + # @see #alias_example_to + # @see #expose_dsl_globally= + def alias_example_group_to(new_name, *args) + extra_options = Metadata.build_hash_from(args) + RSpec::Core::ExampleGroup.define_example_group_method(new_name, extra_options) + end + + # Define an alias for it_should_behave_like that allows different + # language (like "it_has_behavior" or "it_behaves_like") to be + # employed when including shared examples. + # + # @example + # RSpec.configure do |config| + # config.alias_it_behaves_like_to(:it_has_behavior, 'has behavior:') + # end + # + # # allows the user to include a shared example group like: + # + # RSpec.describe Entity do + # it_has_behavior 'sortability' do + # let(:sortable) { Entity.new } + # end + # end + # + # # which is reported in the output as: + # # Entity + # # has behavior: sortability + # # ...sortability examples here + # + # @note Use with caution. This extends the language used in your + # specs, but does not add any additional documentation. We use this + # in RSpec to define `it_should_behave_like` (for backward + # compatibility), but we also add docs for that method. + def alias_it_behaves_like_to(new_name, report_label='') + RSpec::Core::ExampleGroup.define_nested_shared_group_method(new_name, report_label) + end + alias_method :alias_it_should_behave_like_to, :alias_it_behaves_like_to + + # Adds key/value pairs to the `inclusion_filter`. If `args` + # includes any symbols that are not part of the hash, each symbol + # is treated as a key in the hash with the value `true`. + # + # ### Note + # + # Filters set using this method can be overridden from the command line + # or config files (e.g. `.rspec`). + # + # @example + # # Given this declaration. + # describe "something", :foo => 'bar' do + # # ... + # end + # + # # Any of the following will include that group. + # config.filter_run_including :foo => 'bar' + # config.filter_run_including :foo => /^ba/ + # config.filter_run_including :foo => lambda {|v| v == 'bar'} + # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'} + # + # # Given a proc with an arity of 1, the lambda is passed the value + # # related to the key, e.g. + # config.filter_run_including :foo => lambda {|v| v == 'bar'} + # + # # Given a proc with an arity of 2, the lambda is passed the value + # # related to the key, and the metadata itself e.g. + # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'} + # + # filter_run_including :foo # same as filter_run_including :foo => true + def filter_run_including(*args) + meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering) + filter_manager.include_with_low_priority meta + static_config_filter_manager.include_with_low_priority Metadata.deep_hash_dup(meta) + end + alias_method :filter_run, :filter_run_including + + # Applies the provided filter only if any of examples match, in constrast + # to {#filter_run}, which always applies even if no examples match, in + # which case no examples will be run. This allows you to leave configured + # filters in place that are intended only for temporary use. The most common + # example is focus filtering: `config.filter_run_when_matching :focus`. + # With that configured, you can temporarily focus an example or group + # by tagging it with `:focus` metadata, or prefixing it with an `f` + # (as in `fdescribe`, `fcontext` and `fit`) since those are aliases for + # `describe`/`context`/`it` with `:focus` metadata. + def filter_run_when_matching(*args) + when_first_matching_example_defined(*args) do + filter_run(*args) + end + end + + # Clears and reassigns the `inclusion_filter`. Set to `nil` if you don't + # want any inclusion filter at all. + # + # ### Warning + # + # This overrides any inclusion filters/tags set on the command line or in + # configuration files. + def inclusion_filter=(filter) + meta = Metadata.build_hash_from([filter], :warn_about_example_group_filtering) + filter_manager.include_only meta + end + + alias_method :filter=, :inclusion_filter= + + # Returns the `inclusion_filter`. If none has been set, returns an empty + # hash. + def inclusion_filter + filter_manager.inclusions + end + + alias_method :filter, :inclusion_filter + + # Adds key/value pairs to the `exclusion_filter`. If `args` + # includes any symbols that are not part of the hash, each symbol + # is treated as a key in the hash with the value `true`. + # + # ### Note + # + # Filters set using this method can be overridden from the command line + # or config files (e.g. `.rspec`). + # + # @example + # # Given this declaration. + # describe "something", :foo => 'bar' do + # # ... + # end + # + # # Any of the following will exclude that group. + # config.filter_run_excluding :foo => 'bar' + # config.filter_run_excluding :foo => /^ba/ + # config.filter_run_excluding :foo => lambda {|v| v == 'bar'} + # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'} + # + # # Given a proc with an arity of 1, the lambda is passed the value + # # related to the key, e.g. + # config.filter_run_excluding :foo => lambda {|v| v == 'bar'} + # + # # Given a proc with an arity of 2, the lambda is passed the value + # # related to the key, and the metadata itself e.g. + # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'} + # + # filter_run_excluding :foo # same as filter_run_excluding :foo => true + def filter_run_excluding(*args) + meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering) + filter_manager.exclude_with_low_priority meta + static_config_filter_manager.exclude_with_low_priority Metadata.deep_hash_dup(meta) + end + + # Clears and reassigns the `exclusion_filter`. Set to `nil` if you don't + # want any exclusion filter at all. + # + # ### Warning + # + # This overrides any exclusion filters/tags set on the command line or in + # configuration files. + def exclusion_filter=(filter) + meta = Metadata.build_hash_from([filter], :warn_about_example_group_filtering) + filter_manager.exclude_only meta + end + + # Returns the `exclusion_filter`. If none has been set, returns an empty + # hash. + def exclusion_filter + filter_manager.exclusions + end + + # Tells RSpec to include `mod` in example groups. Methods defined in + # `mod` are exposed to examples (not example groups). Use `filters` to + # constrain the groups or examples in which to include the module. + # + # @example + # + # module AuthenticationHelpers + # def login_as(user) + # # ... + # end + # end + # + # module PreferencesHelpers + # def preferences(user, preferences = {}) + # # ... + # end + # end + # + # module UserHelpers + # def users(username) + # # ... + # end + # end + # + # RSpec.configure do |config| + # config.include(UserHelpers) # included in all groups + # + # # included in examples with `:preferences` metadata + # config.include(PreferenceHelpers, :preferences) + # + # # included in examples with `:type => :request` metadata + # config.include(AuthenticationHelpers, :type => :request) + # + # # included in examples where the `:type` metadata matches a proc condition + # config.include(AuthenticationHelpers, :type => proc { |type, _metadata| [:request, :controller].include?(type) }) + # end + # + # describe "edit profile", :preferences, :type => :request do + # it "can be viewed by owning user" do + # login_as preferences(users(:jdoe), :lang => 'es') + # get "/profiles/jdoe" + # assert_select ".username", :text => 'jdoe' + # end + # end + # + # @note Filtered module inclusions can also be applied to + # individual examples that have matching metadata. Just like + # Ruby's object model is that every object has a singleton class + # which has only a single instance, RSpec's model is that every + # example has a singleton example group containing just the one + # example. + # + # @see #include_context + # @see #extend + # @see #prepend + def include(mod, *filters) + define_mixed_in_module(mod, filters, @include_modules, :include) do |group| + safe_include(mod, group) + end + end + + # Tells RSpec to include the named shared example group in example groups. + # Use `filters` to constrain the groups or examples in which to include + # the example group. + # + # @example + # + # RSpec.shared_context "example admin user" do + # let(:admin_user) { create_user(:admin) } + # end + # + # RSpec.shared_context "example guest user" do + # let(:guest_user) { create_user(:guest) } + # end + # + # RSpec.configure do |config| + # config.include_context "example guest user", :type => :request + # config.include_context "example admin user", :admin, :type => :request + # end + # + # RSpec.describe "The admin page", :type => :request do + # it "can be viewed by admins", :admin do + # login_with admin_user + # get "/admin" + # expect(response).to be_ok + # end + # + # it "cannot be viewed by guests" do + # login_with guest_user + # get "/admin" + # expect(response).to be_forbidden + # end + # end + # + # @note Filtered context inclusions can also be applied to + # individual examples that have matching metadata. Just like + # Ruby's object model is that every object has a singleton class + # which has only a single instance, RSpec's model is that every + # example has a singleton example group containing just the one + # example. + # + # @see #include + def include_context(shared_group_name, *filters) + shared_module = world.shared_example_group_registry.find([:main], shared_group_name) + include shared_module, *filters + end + + # Tells RSpec to extend example groups with `mod`. Methods defined in + # `mod` are exposed to example groups (not examples). Use `filters` to + # constrain the groups to extend. + # + # Similar to `include`, but behavior is added to example groups, which + # are classes, rather than the examples, which are instances of those + # classes. + # + # @example + # + # module UiHelpers + # def run_in_browser + # # ... + # end + # end + # + # module PermissionHelpers + # def define_permissions + # # ... + # end + # end + # + # RSpec.configure do |config| + # config.extend(UiHelpers, :type => :request) + # config.extend(PermissionHelpers, :with_permissions, :type => :request) + # end + # + # describe "edit profile", :with_permissions, :type => :request do + # run_in_browser + # define_permissions + # + # it "does stuff in the client" do + # # ... + # end + # end + # + # @see #include + # @see #prepend + def extend(mod, *filters) + define_mixed_in_module(mod, filters, @extend_modules, :extend) do |group| + safe_extend(mod, group) + end + end + + if RSpec::Support::RubyFeatures.module_prepends_supported? + # Tells RSpec to prepend example groups with `mod`. Methods defined in + # `mod` are exposed to examples (not example groups). Use `filters` to + # constrain the groups in which to prepend the module. + # + # Similar to `include`, but module is included before the example group's class + # in the ancestor chain. + # + # @example + # + # module OverrideMod + # def override_me + # "overridden" + # end + # end + # + # RSpec.configure do |config| + # config.prepend(OverrideMod, :method => :prepend) + # end + # + # describe "overriding example's class", :method => :prepend do + # it "finds the user" do + # self.class.class_eval do + # def override_me + # end + # end + # override_me # => "overridden" + # # ... + # end + # end + # + # @see #include + # @see #extend + def prepend(mod, *filters) + define_mixed_in_module(mod, filters, @prepend_modules, :prepend) do |group| + safe_prepend(mod, group) + end + end + end + + # @private + # + # Used internally to extend a group with modules using `include`, `prepend` and/or + # `extend`. + def configure_group(group) + group.hooks.register_globals(group, hooks) + + configure_group_with group, @include_modules, :safe_include + configure_group_with group, @extend_modules, :safe_extend + configure_group_with group, @prepend_modules, :safe_prepend + end + + # @private + # + # Used internally to extend the singleton class of a single example's + # example group instance with modules using `include` and/or `extend`. + def configure_example(example, example_hooks) + example_hooks.register_global_singleton_context_hooks(example, hooks) + singleton_group = example.example_group_instance.singleton_class + + # We replace the metadata so that SharedExampleGroupModule#included + # has access to the example's metadata[:location]. + singleton_group.with_replaced_metadata(example.metadata) do + modules = @include_modules.items_for(example.metadata) + modules.each do |mod| + safe_include(mod, example.example_group_instance.singleton_class) + end + + MemoizedHelpers.define_helpers_on(singleton_group) unless modules.empty? + end + end + + # @private + def requires=(paths) + directories = ['lib', default_path].select { |p| File.directory? p } + RSpec::Core::RubyProject.add_to_load_path(*directories) + paths.each { |path| + load_file_handling_errors(:require, path) + @requires << path + } + end + + # @private + def in_project_source_dir_regex + regexes = project_source_dirs.map do |dir| + /\A#{Regexp.escape(File.expand_path(dir))}\// + end + + Regexp.union(regexes) + end + + # @private + def configure_mock_framework + RSpec::Core::ExampleGroup.__send__(:include, mock_framework) + conditionally_disable_mocks_monkey_patching + end + + # @private + def configure_expectation_framework + expectation_frameworks.each do |framework| + RSpec::Core::ExampleGroup.__send__(:include, framework) + end + conditionally_disable_expectations_monkey_patching + end + + # @private + def load_spec_files + # Note which spec files world is already aware of. + # This is generally only needed for when the user runs + # `ruby path/to/spec.rb` (and loads `rspec/autorun`) -- + # in that case, the spec file was loaded by `ruby` and + # isn't loaded by us here so we only know about it because + # of an example group being registered in it. + world.registered_example_group_files.each do |f| + loaded_spec_files << f # the registered files are already expended absolute paths + end + + files_to_run.uniq.each do |f| + file = File.expand_path(f) + load_file_handling_errors(:load, file) + loaded_spec_files << file + end + + @spec_files_loaded = true + end + + # @private + DEFAULT_FORMATTER = lambda { |string| string } + + # Formats the docstring output using the block provided. + # + # @example + # # This will strip the descriptions of both examples and example + # # groups. + # RSpec.configure do |config| + # config.format_docstrings { |s| s.strip } + # end + def format_docstrings(&block) + @format_docstrings_block = block_given? ? block : DEFAULT_FORMATTER + end + + # @private + def format_docstrings_block + @format_docstrings_block ||= DEFAULT_FORMATTER + end + + # @private + def self.delegate_to_ordering_manager(*methods) + methods.each do |method| + define_method method do |*args, &block| + ordering_manager.__send__(method, *args, &block) + end + end + end + + # @!method seed=(value) + # + # Sets the seed value and sets the default global ordering to random. + delegate_to_ordering_manager :seed= + + # @!method seed + # Seed for random ordering (default: generated randomly each run). + # + # When you run specs with `--order random`, RSpec generates a random seed + # for the randomization and prints it to the `output_stream` (assuming + # you're using RSpec's built-in formatters). If you discover an ordering + # dependency (i.e. examples fail intermittently depending on order), set + # this (on Configuration or on the command line with `--seed`) to run + # using the same seed while you debug the issue. + # + # We recommend, actually, that you use the command line approach so you + # don't accidentally leave the seed encoded. + delegate_to_ordering_manager :seed + + # @!method order=(value) + # + # Sets the default global ordering strategy. By default this can be one + # of `:defined`, `:random`, but is customizable through the + # `register_ordering` API. If order is set to `'rand:'`, + # the seed will also be set. + # + # @see #register_ordering + delegate_to_ordering_manager :order= + + # @!method register_ordering(name) + # + # Registers a named ordering strategy that can later be + # used to order an example group's subgroups by adding + # `:order => ` metadata to the example group. + # + # @param name [Symbol] The name of the ordering. + # @yield Block that will order the given examples or example groups + # @yieldparam list [Array, + # Array] The examples or groups to order + # @yieldreturn [Array, + # Array] The re-ordered examples or groups + # + # @example + # RSpec.configure do |rspec| + # rspec.register_ordering :reverse do |list| + # list.reverse + # end + # end + # + # RSpec.describe 'MyClass', :order => :reverse do + # # ... + # end + # + # @note Pass the symbol `:global` to set the ordering strategy that + # will be used to order the top-level example groups and any example + # groups that do not have declared `:order` metadata. + # + # @example + # RSpec.configure do |rspec| + # rspec.register_ordering :global do |examples| + # acceptance, other = examples.partition do |example| + # example.metadata[:type] == :acceptance + # end + # other + acceptance + # end + # end + # + # RSpec.describe 'MyClass', :type => :acceptance do + # # will run last + # end + # + # RSpec.describe 'MyClass' do + # # will run first + # end + # + delegate_to_ordering_manager :register_ordering + + # @private + delegate_to_ordering_manager :seed_used?, :ordering_registry + + # Set Ruby warnings on or off. + def warnings=(value) + $VERBOSE = !!value + end + + # @return [Boolean] Whether or not ruby warnings are enabled. + def warnings? + $VERBOSE + end + + # @private + RAISE_ERROR_WARNING_NOTIFIER = lambda { |message| raise message } + + # Turns RSpec warnings into errors. This can be useful when + # you want RSpec to run in a 'strict' no warning situation. + # (Note this does not capture or raise on Ruby warnings). + # + # @example + # + # RSpec.configure do |rspec| + # rspec.raise_on_warning = true + # end + def raise_on_warning=(value) + if value + RSpec::Support.warning_notifier = RAISE_ERROR_WARNING_NOTIFIER + else + RSpec::Support.warning_notifier = RSpec::Support::DEFAULT_WARNING_NOTIFIER + end + end + + # Exposes the current running example via the named + # helper method. RSpec 2.x exposed this via `example`, + # but in RSpec 3.0, the example is instead exposed via + # an arg yielded to `it`, `before`, `let`, etc. However, + # some extension gems (such as Capybara) depend on the + # RSpec 2.x's `example` method, so this config option + # can be used to maintain compatibility. + # + # @param method_name [Symbol] the name of the helper method + # + # @example + # + # RSpec.configure do |rspec| + # rspec.expose_current_running_example_as :example + # end + # + # RSpec.describe MyClass do + # before do + # # `example` can be used here because of the above config. + # do_something if example.metadata[:type] == "foo" + # end + # end + def expose_current_running_example_as(method_name) + ExposeCurrentExample.module_exec do + extend RSpec::SharedContext + let(method_name) { |ex| ex } + end + + include ExposeCurrentExample + end + + # @private + module ExposeCurrentExample; end + + # Turns deprecation warnings into errors, in order to surface + # the full backtrace of the call site. This can be useful when + # you need more context to address a deprecation than the + # single-line call site normally provided. + # + # @example + # + # RSpec.configure do |rspec| + # rspec.raise_errors_for_deprecations! + # end + def raise_errors_for_deprecations! + self.deprecation_stream = Formatters::DeprecationFormatter::RaiseErrorStream.new + end + + # Enables zero monkey patching mode for RSpec. It removes monkey + # patching of the top-level DSL methods (`describe`, + # `shared_examples_for`, etc) onto `main` and `Module`, instead + # requiring you to prefix these methods with `RSpec.`. It enables + # expect-only syntax for rspec-mocks and rspec-expectations. It + # simply disables monkey patching on whatever pieces of RSpec + # the user is using. + # + # @note It configures rspec-mocks and rspec-expectations only + # if the user is using those (either explicitly or implicitly + # by not setting `mock_with` or `expect_with` to anything else). + # + # @note If the user uses this options with `mock_with :mocha` + # (or similar) they will still have monkey patching active + # in their test environment from mocha. + # + # @example + # + # # It disables all monkey patching. + # RSpec.configure do |config| + # config.disable_monkey_patching! + # end + # + # # Is an equivalent to + # RSpec.configure do |config| + # config.expose_dsl_globally = false + # + # config.mock_with :rspec do |mocks| + # mocks.syntax = :expect + # mocks.patch_marshal_to_support_partial_doubles = false + # end + # + # config.expect_with :rspec do |expectations| + # expectations.syntax = :expect + # end + # end + def disable_monkey_patching! + self.expose_dsl_globally = false + self.disable_monkey_patching = true + conditionally_disable_mocks_monkey_patching + conditionally_disable_expectations_monkey_patching + end + + # @private + attr_accessor :disable_monkey_patching + + # Defines a callback that can assign derived metadata values. + # + # @param filters [Array, Hash] metadata filters that determine + # which example or group metadata hashes the callback will be triggered + # for. If none are given, the callback will be run against the metadata + # hashes of all groups and examples. + # @yieldparam metadata [Hash] original metadata hash from an example or + # group. Mutate this in your block as needed. + # + # @example + # RSpec.configure do |config| + # # Tag all groups and examples in the spec/unit directory with + # # :type => :unit + # config.define_derived_metadata(:file_path => %r{/spec/unit/}) do |metadata| + # metadata[:type] = :unit + # end + # end + def define_derived_metadata(*filters, &block) + meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering) + @derived_metadata_blocks.append(block, meta) + end + + # Defines a callback that runs after the first example with matching + # metadata is defined. If no examples are defined with matching metadata, + # it will not get called at all. + # + # This can be used to ensure some setup is performed (such as bootstrapping + # a DB or loading a specific file that adds significantly to the boot time) + # if needed (as indicated by the presence of an example with matching metadata) + # but avoided otherwise. + # + # @example + # RSpec.configure do |config| + # config.when_first_matching_example_defined(:db) do + # # Load a support file that does some heavyweight setup, + # # including bootstrapping the DB, but only if we have loaded + # # any examples tagged with `:db`. + # require 'support/db' + # end + # end + def when_first_matching_example_defined(*filters) + specified_meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering) + + callback = lambda do |example_or_group_meta| + # Example groups do not have `:example_group` metadata + # (instead they have `:parent_example_group` metadata). + return unless example_or_group_meta.key?(:example_group) + + # Ensure the callback only fires once. + @derived_metadata_blocks.delete(callback, specified_meta) + + yield + end + + @derived_metadata_blocks.append(callback, specified_meta) + end + + # @private + def apply_derived_metadata_to(metadata) + already_run_blocks = Set.new + + # We loop and attempt to re-apply metadata blocks to support cascades + # (e.g. where a derived bit of metadata triggers the application of + # another piece of derived metadata, etc) + # + # We limit our looping to 200 times as a way to detect infinitely recursing derived metadata blocks. + # It's hard to imagine a valid use case for a derived metadata cascade greater than 200 iterations. + 200.times do + return if @derived_metadata_blocks.items_for(metadata).all? do |block| + already_run_blocks.include?(block).tap do |skip_block| + block.call(metadata) unless skip_block + already_run_blocks << block + end + end + end + + # If we got here, then `@derived_metadata_blocks.items_for(metadata).all?` never returned + # `true` above and we treat this as an attempt to recurse infinitely. It's better to fail + # with a clear # error than hang indefinitely, which is what would happen if we didn't limit + # the looping above. + raise SystemStackError, "Attempted to recursively derive metadata indefinitely." + end + + # Defines a `before` hook. See {Hooks#before} for full docs. + # + # This method differs from {Hooks#before} in only one way: it supports + # the `:suite` scope. Hooks with the `:suite` scope will be run once before + # the first example of the entire suite is executed. Conditions passed along + # with `:suite` are effectively ignored. + # + # @see #prepend_before + # @see #after + # @see #append_after + def before(scope=nil, *meta, &block) + handle_suite_hook(scope, meta) do + @before_suite_hooks << Hooks::BeforeHook.new(block, {}) + end || begin + # defeat Ruby 2.5 lazy proc allocation to ensure + # the methods below are passed the same proc instances + # so `Hook` equality is preserved. For more info, see: + # https://bugs.ruby-lang.org/issues/14045#note-5 + block.__id__ + + add_hook_to_existing_matching_groups(meta, scope) { |g| g.before(scope, *meta, &block) } + super(scope, *meta, &block) + end + end + alias_method :append_before, :before + + # Adds `block` to the start of the list of `before` blocks in the same + # scope (`:example`, `:context`, or `:suite`), in contrast to {#before}, + # which adds the hook to the end of the list. + # + # See {Hooks#before} for full `before` hook docs. + # + # This method differs from {Hooks#prepend_before} in only one way: it supports + # the `:suite` scope. Hooks with the `:suite` scope will be run once before + # the first example of the entire suite is executed. Conditions passed along + # with `:suite` are effectively ignored. + # + # @see #before + # @see #after + # @see #append_after + def prepend_before(scope=nil, *meta, &block) + handle_suite_hook(scope, meta) do + @before_suite_hooks.unshift Hooks::BeforeHook.new(block, {}) + end || begin + # defeat Ruby 2.5 lazy proc allocation to ensure + # the methods below are passed the same proc instances + # so `Hook` equality is preserved. For more info, see: + # https://bugs.ruby-lang.org/issues/14045#note-5 + block.__id__ + + add_hook_to_existing_matching_groups(meta, scope) { |g| g.prepend_before(scope, *meta, &block) } + super(scope, *meta, &block) + end + end + + # Defines a `after` hook. See {Hooks#after} for full docs. + # + # This method differs from {Hooks#after} in only one way: it supports + # the `:suite` scope. Hooks with the `:suite` scope will be run once after + # the last example of the entire suite is executed. Conditions passed along + # with `:suite` are effectively ignored. + # + # @see #append_after + # @see #before + # @see #prepend_before + def after(scope=nil, *meta, &block) + handle_suite_hook(scope, meta) do + @after_suite_hooks.unshift Hooks::AfterHook.new(block, {}) + end || begin + # defeat Ruby 2.5 lazy proc allocation to ensure + # the methods below are passed the same proc instances + # so `Hook` equality is preserved. For more info, see: + # https://bugs.ruby-lang.org/issues/14045#note-5 + block.__id__ + + add_hook_to_existing_matching_groups(meta, scope) { |g| g.after(scope, *meta, &block) } + super(scope, *meta, &block) + end + end + alias_method :prepend_after, :after + + # Adds `block` to the end of the list of `after` blocks in the same + # scope (`:example`, `:context`, or `:suite`), in contrast to {#after}, + # which adds the hook to the start of the list. + # + # See {Hooks#after} for full `after` hook docs. + # + # This method differs from {Hooks#append_after} in only one way: it supports + # the `:suite` scope. Hooks with the `:suite` scope will be run once after + # the last example of the entire suite is executed. Conditions passed along + # with `:suite` are effectively ignored. + # + # @see #append_after + # @see #before + # @see #prepend_before + def append_after(scope=nil, *meta, &block) + handle_suite_hook(scope, meta) do + @after_suite_hooks << Hooks::AfterHook.new(block, {}) + end || begin + # defeat Ruby 2.5 lazy proc allocation to ensure + # the methods below are passed the same proc instances + # so `Hook` equality is preserved. For more info, see: + # https://bugs.ruby-lang.org/issues/14045#note-5 + block.__id__ + + add_hook_to_existing_matching_groups(meta, scope) { |g| g.append_after(scope, *meta, &block) } + super(scope, *meta, &block) + end + end + + # Registers `block` as an `around` hook. + # + # See {Hooks#around} for full `around` hook docs. + def around(scope=nil, *meta, &block) + # defeat Ruby 2.5 lazy proc allocation to ensure + # the methods below are passed the same proc instances + # so `Hook` equality is preserved. For more info, see: + # https://bugs.ruby-lang.org/issues/14045#note-5 + block.__id__ + + add_hook_to_existing_matching_groups(meta, scope) { |g| g.around(scope, *meta, &block) } + super(scope, *meta, &block) + end + + # @private + def with_suite_hooks + return yield if dry_run? + + begin + RSpec.current_scope = :before_suite_hook + run_suite_hooks("a `before(:suite)` hook", @before_suite_hooks) + yield + ensure + RSpec.current_scope = :after_suite_hook + run_suite_hooks("an `after(:suite)` hook", @after_suite_hooks) + RSpec.current_scope = :suite + end + end + + # @private + # Holds the various registered hooks. Here we use a FilterableItemRepository + # implementation that is specifically optimized for the read/write patterns + # of the config object. + def hooks + @hooks ||= HookCollections.new(self, FilterableItemRepository::QueryOptimized) + end + + # Invokes block before defining an example group + def on_example_group_definition(&block) + on_example_group_definition_callbacks << block + end + + # @api private + # Returns an array of blocks to call before defining an example group + def on_example_group_definition_callbacks + @on_example_group_definition_callbacks ||= [] + end + + # @private + def bisect_runner_class + @bisect_runner_class ||= begin + case bisect_runner + when :fork + RSpec::Support.require_rspec_core 'bisect/fork_runner' + Bisect::ForkRunner + when :shell + RSpec::Support.require_rspec_core 'bisect/shell_runner' + Bisect::ShellRunner + else + raise "Unsupported value for `bisect_runner` (#{bisect_runner.inspect}). " \ + "Only `:fork` and `:shell` are supported." + end + end + end + + private + + def load_file_handling_errors(method, file) + __send__(method, file) + rescue LoadError => ex + relative_file = Metadata.relative_path(file) + suggestions = DidYouMean.new(relative_file).call + reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.#{suggestions}") + RSpec.world.wants_to_quit = true + rescue SyntaxError => ex + relative_file = Metadata.relative_path(file) + reporter.notify_non_example_exception( + ex, + "While loading #{relative_file} a `raise SyntaxError` occurred, RSpec will now quit." + ) + RSpec.world.rspec_is_quitting = true + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex + relative_file = Metadata.relative_path(file) + reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.") + RSpec.world.wants_to_quit = true + rescue SystemExit => ex + relative_file = Metadata.relative_path(file) + reporter.notify_non_example_exception( + ex, + "While loading #{relative_file} an `exit` / `raise SystemExit` occurred, RSpec will now quit." + ) + RSpec.world.rspec_is_quitting = true + raise ex + end + + def handle_suite_hook(scope, meta) + return nil unless scope == :suite + + unless meta.empty? + # TODO: in RSpec 4, consider raising an error here. + # We warn only for backwards compatibility. + RSpec.warn_with "WARNING: `:suite` hooks do not support metadata since " \ + "they apply to the suite as a whole rather than " \ + "any individual example or example group that has metadata. " \ + "The metadata you have provided (#{meta.inspect}) will be ignored." + end + + yield + end + + def run_suite_hooks(hook_description, hooks) + context = SuiteHookContext.new(hook_description, reporter) + + hooks.each do |hook| + begin + hook.run(context) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex + context.set_exception(ex) + + # Do not run subsequent `before` hooks if one fails. + # But for `after` hooks, we run them all so that all + # cleanup bits get a chance to complete, minimizing the + # chance that resources get left behind. + break if hooks.equal?(@before_suite_hooks) + end + end + end + + def get_files_to_run(paths) + files = FlatMap.flat_map(paths_to_check(paths)) do |path| + path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR + File.directory?(path) ? gather_directories(path) : extract_location(path) + end.uniq + + return files unless only_failures? + relative_files = files.map { |f| Metadata.relative_path(File.expand_path f) } + intersection = (relative_files & spec_files_with_failures.to_a) + intersection.empty? ? files : intersection + end + + def paths_to_check(paths) + return paths if pattern_might_load_specs_from_vendored_dirs? + paths + [Dir.getwd] + end + + def pattern_might_load_specs_from_vendored_dirs? + pattern.split(File::SEPARATOR).first.include?('**') + end + + def gather_directories(path) + include_files = get_matching_files(path, pattern) + exclude_files = get_matching_files(path, exclude_pattern) + (include_files - exclude_files).uniq + end + + def get_matching_files(path, pattern) + raw_files = Dir[file_glob_from(path, pattern)] + raw_files.map { |file| File.expand_path(file) }.sort + end + + def file_glob_from(path, pattern) + stripped = "{#{pattern.gsub(/\s*,\s*/, ',')}}" + return stripped if pattern =~ /^(\.\/)?#{Regexp.escape path}/ || absolute_pattern?(pattern) + File.join(path, stripped) + end + + if RSpec::Support::OS.windows? + # :nocov: + def absolute_pattern?(pattern) + pattern =~ /\A[A-Z]:\\/ || windows_absolute_network_path?(pattern) + end + + def windows_absolute_network_path?(pattern) + return false unless ::File::ALT_SEPARATOR + pattern.start_with?(::File::ALT_SEPARATOR + ::File::ALT_SEPARATOR) + end + # :nocov: + else + def absolute_pattern?(pattern) + pattern.start_with?(File::Separator) + end + end + + def extract_location(path) + match = /^(.*?)((?:\:\d+)+)$/.match(path) + + if match + captures = match.captures + path = captures[0] + lines = captures[1][1..-1].split(":").map(&:to_i) + filter_manager.add_location path, lines + else + path, scoped_ids = Example.parse_id(path) + filter_manager.add_ids(path, scoped_ids.split(/\s*,\s*/)) if scoped_ids + end + + return [] if path == default_path + File.expand_path(path) + end + + def command + $0.split(File::SEPARATOR).last + end + + def value_for(key) + @preferred_options.fetch(key) { yield } + end + + def define_built_in_hooks + around(:example, :aggregate_failures => true) do |procsy| + begin + aggregate_failures(nil, :hide_backtrace => true, &procsy) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => exception + procsy.example.set_aggregate_failures_exception(exception) + end + end + end + + def assert_no_example_groups_defined(config_option) + return unless world.example_groups.any? + + raise MustBeConfiguredBeforeExampleGroupsError.new( + "RSpec's #{config_option} configuration option must be configured before " \ + "any example groups are defined, but you have already defined a group." + ) + end + + def output_wrapper + @output_wrapper ||= OutputWrapper.new(output_stream) + end + + def output_to_tty?(output=output_stream) + output.respond_to?(:tty?) && output.tty? + end + + def conditionally_disable_mocks_monkey_patching + return unless disable_monkey_patching && rspec_mocks_loaded? + + RSpec::Mocks.configuration.tap do |config| + config.syntax = :expect + config.patch_marshal_to_support_partial_doubles = false + end + end + + def conditionally_disable_expectations_monkey_patching + return unless disable_monkey_patching && rspec_expectations_loaded? + + RSpec::Expectations.configuration.syntax = :expect + end + + def rspec_mocks_loaded? + defined?(RSpec::Mocks.configuration) + end + + def rspec_expectations_loaded? + defined?(RSpec::Expectations.configuration) + end + + def update_pattern_attr(name, value) + if @spec_files_loaded + RSpec.warning "Configuring `#{name}` to #{value} has no effect since " \ + "RSpec has already loaded the spec files." + end + + instance_variable_set(:"@#{name}", value) + @files_to_run = nil + end + + def clear_values_derived_from_example_status_persistence_file_path + @last_run_statuses = nil + @spec_files_with_failures = nil + end + + def configure_group_with(group, module_list, application_method) + module_list.items_for(group.metadata).each do |mod| + __send__(application_method, mod, group) + end + end + + def add_hook_to_existing_matching_groups(meta, scope, &block) + # For example hooks, we have to apply it to each of the top level + # groups, even if the groups do not match. When we apply it, we + # apply it with the metadata, so it will only apply to examples + # in the group that match the metadata. + # #2280 for background and discussion. + if scope == :example || scope == :each || scope.nil? + world.example_groups.each(&block) + else + meta = Metadata.build_hash_from(meta.dup) + on_existing_matching_groups(meta, &block) + end + end + + def on_existing_matching_groups(meta) + world.traverse_example_group_trees_until do |group| + metadata_applies_to_group?(meta, group).tap do |applies| + yield group if applies + end + end + end + + def metadata_applies_to_group?(meta, group) + meta.empty? || MetadataFilter.apply?(:any?, meta, group.metadata) + end + + if RSpec::Support::RubyFeatures.module_prepends_supported? + def safe_prepend(mod, host) + host.__send__(:prepend, mod) unless host < mod + end + end + + if RUBY_VERSION.to_f >= 1.9 + def safe_include(mod, host) + host.__send__(:include, mod) unless host < mod + end + + def safe_extend(mod, host) + host.extend(mod) unless host.singleton_class < mod + end + else # for 1.8.7 + # :nocov: + def safe_include(mod, host) + host.__send__(:include, mod) unless host.included_modules.include?(mod) + end + + def safe_extend(mod, host) + host.extend(mod) unless (class << host; self; end).included_modules.include?(mod) + end + # :nocov: + end + + def define_mixed_in_module(mod, filters, mod_list, config_method, &block) + unless Module === mod + raise TypeError, "`RSpec.configuration.#{config_method}` expects a module but got: #{mod.inspect}" + end + + meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering) + mod_list.append(mod, meta) + on_existing_matching_groups(meta, &block) + end + end + # rubocop:enable Metrics/ClassLength + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb new file mode 100644 index 0000000..fcde48f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb @@ -0,0 +1,240 @@ +require 'erb' +require 'shellwords' + +module RSpec + module Core + # Responsible for utilizing externally provided configuration options, + # whether via the command line, `.rspec`, `~/.rspec`, + # `$XDG_CONFIG_HOME/rspec/options`, `.rspec-local` or a custom options + # file. + class ConfigurationOptions + # @param args [Array] command line arguments + def initialize(args) + @args = args.dup + organize_options + end + + # Updates the provided {Configuration} instance based on the provided + # external configuration options. + # + # @param config [Configuration] the configuration instance to update + def configure(config) + process_options_into config + configure_filter_manager config.filter_manager + load_formatters_into config + end + + # @api private + # Updates the provided {FilterManager} based on the filter options. + # @param filter_manager [FilterManager] instance to update + def configure_filter_manager(filter_manager) + @filter_manager_options.each do |command, value| + filter_manager.__send__ command, value + end + end + + # @return [Hash] the final merged options, drawn from all external sources + attr_reader :options + + # @return [Array] the original command-line arguments + attr_reader :args + + private + + def organize_options + @filter_manager_options = [] + + @options = (file_options << command_line_options << env_options).each do |opts| + @filter_manager_options << [:include, opts.delete(:inclusion_filter)] if opts.key?(:inclusion_filter) + @filter_manager_options << [:exclude, opts.delete(:exclusion_filter)] if opts.key?(:exclusion_filter) + end + + @options = @options.inject(:libs => [], :requires => []) do |hash, opts| + hash.merge(opts) do |key, oldval, newval| + [:libs, :requires].include?(key) ? oldval + newval : newval + end + end + end + + UNFORCED_OPTIONS = Set.new([ + :requires, :profile, :drb, :libs, :files_or_directories_to_run, + :full_description, :full_backtrace, :tty + ]) + + UNPROCESSABLE_OPTIONS = Set.new([:formatters]) + + def force?(key) + !UNFORCED_OPTIONS.include?(key) + end + + def order(keys) + OPTIONS_ORDER.reverse_each do |key| + keys.unshift(key) if keys.delete(key) + end + keys + end + + OPTIONS_ORDER = [ + # It's important to set this before anything that might issue a + # deprecation (or otherwise access the reporter). + :deprecation_stream, + + # In order for `RSpec.configuration.dry_run?` to return `true` during + # processing the `requires` option, it must be parsed before it. + :dry_run, + + # load paths depend on nothing, but must be set before `requires` + # to support load-path-relative requires. + :libs, + + # `files_or_directories_to_run` uses `default_path` so it must be + # set before it. + :default_path, :only_failures, + + # These must be set before `requires` to support checking + # `config.files_to_run` from within `spec_helper.rb` when a + # `-rspec_helper` option is used. + :files_or_directories_to_run, :pattern, :exclude_pattern, + + # Necessary so that the `--seed` option is applied before requires, + # in case required files do something with the provided seed. + # (such as seed global randomization with it). + :order, + + # In general, we want to require the specified files as early as + # possible. The `--require` option is specifically intended to allow + # early requires. For later requires, they can just put the require in + # their spec files, but `--require` provides a unique opportunity for + # users to instruct RSpec to load an extension file early for maximum + # flexibility. + :requires + ] + + def process_options_into(config) + opts = options.reject { |k, _| UNPROCESSABLE_OPTIONS.include? k } + + order(opts.keys).each do |key| + force?(key) ? config.force(key => opts[key]) : config.__send__("#{key}=", opts[key]) + end + end + + def load_formatters_into(config) + options[:formatters].each { |pair| config.add_formatter(*pair) } if options[:formatters] + end + + def file_options + if custom_options_file + [custom_options] + else + [global_options, project_options, local_options] + end + end + + def env_options + return {} unless ENV['SPEC_OPTS'] + + parse_args_ignoring_files_or_dirs_to_run( + Shellwords.split(ENV["SPEC_OPTS"]), + "ENV['SPEC_OPTS']" + ) + end + + def command_line_options + @command_line_options ||= Parser.parse(@args) + end + + def custom_options + options_from(custom_options_file) + end + + def local_options + @local_options ||= options_from(local_options_file) + end + + def project_options + @project_options ||= options_from(project_options_file) + end + + def global_options + @global_options ||= options_from(global_options_file) + end + + def options_from(path) + args = args_from_options_file(path) + parse_args_ignoring_files_or_dirs_to_run(args, path) + end + + def parse_args_ignoring_files_or_dirs_to_run(args, source) + options = Parser.parse(args, source) + options.delete(:files_or_directories_to_run) + options + end + + def args_from_options_file(path) + return [] unless path && File.exist?(path) + config_string = options_file_as_erb_string(path) + config_lines = config_string.split(/\n+/).reject { |s| s =~ /\A\s*#/ } + FlatMap.flat_map(config_lines, &:shellsplit) + end + + # :nocov: + def options_file_as_erb_string(path) + if RUBY_VERSION >= '2.6' + ERB.new(File.read(path), :trim_mode => '-').result(binding) + else + ERB.new(File.read(path), nil, '-').result(binding) + end + end + # :nocov: + + def custom_options_file + command_line_options[:custom_options_file] + end + + def project_options_file + "./.rspec" + end + + def local_options_file + "./.rspec-local" + end + + def global_options_file + xdg_options_file_if_exists || home_options_file_path + end + + def xdg_options_file_if_exists + path = xdg_options_file_path + if path && File.exist?(path) + path + end + end + + def home_options_file_path + File.join(File.expand_path("~"), ".rspec") + rescue ArgumentError + # :nocov: + RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set" + nil + # :nocov: + end + + def xdg_options_file_path + xdg_config_home = resolve_xdg_config_home + if xdg_config_home + File.join(xdg_config_home, "rspec", "options") + end + end + + def resolve_xdg_config_home + File.expand_path(ENV.fetch("XDG_CONFIG_HOME", "~/.config")) + rescue ArgumentError + # :nocov: + # On Ruby 2.4, `File.expand("~")` works even if `ENV['HOME']` is not set. + # But on earlier versions, it fails. + nil + # :nocov: + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb new file mode 100644 index 0000000..643a869 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb @@ -0,0 +1,52 @@ +module RSpec + module Core + # @private + # Wrapper around Ruby's `DidYouMean::SpellChecker` when available to provide file name suggestions. + class DidYouMean + attr_reader :relative_file_name + + def initialize(relative_file_name) + @relative_file_name = relative_file_name + end + + if defined?(::DidYouMean::SpellChecker) + # provide probable suggestions + # :nocov: - not installed on CI + def call + checker = ::DidYouMean::SpellChecker.new(:dictionary => Dir["spec/**/*.rb"]) + probables = checker.correct(relative_file_name.sub('./', ''))[0..2] + return '' unless probables.any? + + formats probables + end + # :nocov: + else + # return a hint if API for ::DidYouMean::SpellChecker not supported + # :nocov: + def call + "\nHint: Install the `did_you_mean` gem in order to provide suggestions for similarly named files." + end + # :nocov: + end + + private + + # :nocov: + def formats(probables) + rspec_format = probables.map { |s, _| "rspec ./#{s}" } + red_font(top_and_tail rspec_format) + end + + def top_and_tail(rspec_format) + spaces = ' ' * 20 + rspec_format.insert(0, ' - Did you mean?').join("\n#{spaces}") + "\n" + end + + def red_font(mytext) + colorizer = ::RSpec::Core::Formatters::ConsoleCodes + colorizer.wrap mytext, :failure + end + # :nocov: + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb new file mode 100644 index 0000000..31bfbf6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb @@ -0,0 +1,120 @@ +require 'drb/drb' + +module RSpec + module Core + # @private + class DRbRunner + def initialize(options, configuration=RSpec.configuration) + @options = options + @configuration = configuration + end + + def drb_port + @options.options[:drb_port] || ENV['RSPEC_DRB'] || 8989 + end + + def run(err, out) + begin + DRb.start_service("druby://localhost:0") + rescue SocketError, Errno::EADDRNOTAVAIL + DRb.start_service("druby://:0") + end + spec_server = DRbObject.new_with_uri("druby://127.0.0.1:#{drb_port}") + spec_server.run(drb_argv, err, out) + end + + def drb_argv + @drb_argv ||= begin + @options.configure_filter_manager(@configuration.filter_manager) + DRbOptions.new(@options.options, @configuration.filter_manager).options + end + end + end + + # @private + class DRbOptions + def initialize(submitted_options, filter_manager) + @submitted_options = submitted_options + @filter_manager = filter_manager + end + + def options + argv = [] + argv << "--color" if @submitted_options[:color] + argv << "--force-color" if @submitted_options[:color_mode] == :on + argv << "--no-color" if @submitted_options[:color_mode] == :off + argv << "--profile" if @submitted_options[:profile_examples] + argv << "--backtrace" if @submitted_options[:full_backtrace] + argv << "--tty" if @submitted_options[:tty] + argv << "--fail-fast" if @submitted_options[:fail_fast] + argv << "--options" << @submitted_options[:custom_options_file] if @submitted_options[:custom_options_file] + argv << "--order" << @submitted_options[:order] if @submitted_options[:order] + + add_failure_exit_code(argv) + add_error_exit_code(argv) + add_full_description(argv) + add_filter(argv, :inclusion, @filter_manager.inclusions) + add_filter(argv, :exclusion, @filter_manager.exclusions) + add_formatters(argv) + add_libs(argv) + add_requires(argv) + + argv + @submitted_options[:files_or_directories_to_run] + end + + def add_failure_exit_code(argv) + return unless @submitted_options[:failure_exit_code] + + argv << "--failure-exit-code" << @submitted_options[:failure_exit_code].to_s + end + + def add_error_exit_code(argv) + return unless @submitted_options[:error_exit_code] + + argv << "--error-exit-code" << @submitted_options[:error_exit_code].to_s + end + + def add_full_description(argv) + return unless @submitted_options[:full_description] + + # The argument to --example is regexp-escaped before being stuffed + # into a regexp when received for the first time (see OptionParser). + # Hence, merely grabbing the source of this regexp will retain the + # backslashes, so we must remove them. + @submitted_options[:full_description].each do |description| + argv << "--example" << description.source.delete('\\') + end + end + + CONDITIONAL_FILTERS = [:if, :unless] + + def add_filter(argv, name, hash) + hash.each_pair do |k, v| + next if CONDITIONAL_FILTERS.include?(k) + tag = name == :inclusion ? k.to_s.dup : "~#{k}".dup + tag << ":#{v}" if v.is_a?(String) + argv << "--tag" << tag + end unless hash.empty? + end + + def add_formatters(argv) + @submitted_options[:formatters].each do |pair| + argv << "--format" << pair[0] + argv << "--out" << pair[1] if pair[1] + end if @submitted_options[:formatters] + end + + def add_libs(argv) + @submitted_options[:libs].each do |path| + argv << "-I" << path + end if @submitted_options[:libs] + end + + def add_requires(argv) + @submitted_options[:requires].each do |path| + argv << "--require" << path + end if @submitted_options[:requires] + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb new file mode 100644 index 0000000..220403e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb @@ -0,0 +1,98 @@ +module RSpec + module Core + # DSL defines methods to group examples, most notably `describe`, + # and exposes them as class methods of {RSpec}. They can also be + # exposed globally (on `main` and instances of `Module`) through + # the {Configuration} option `expose_dsl_globally`. + # + # By default the methods `describe`, `context` and `example_group` + # are exposed. These methods define a named context for one or + # more examples. The given block is evaluated in the context of + # a generated subclass of {RSpec::Core::ExampleGroup}. + # + # ## Examples: + # + # RSpec.describe "something" do + # context "when something is a certain way" do + # it "does something" do + # # example code goes here + # end + # end + # end + # + # @see ExampleGroup + # @see ExampleGroup.example_group + module DSL + # @private + def self.example_group_aliases + @example_group_aliases ||= [] + end + + # @private + def self.exposed_globally? + @exposed_globally ||= false + end + + # @private + def self.expose_example_group_alias(name) + return if example_group_aliases.include?(name) + + example_group_aliases << name + + (class << RSpec; self; end).__send__(:define_method, name) do |*args, &example_group_block| + group = RSpec::Core::ExampleGroup.__send__(name, *args, &example_group_block) + RSpec.world.record(group) + group + end + + expose_example_group_alias_globally(name) if exposed_globally? + end + + class << self + # @private + attr_accessor :top_level + end + + # Adds the describe method to Module and the top level binding. + # @api private + def self.expose_globally! + return if exposed_globally? + + example_group_aliases.each do |method_name| + expose_example_group_alias_globally(method_name) + end + + @exposed_globally = true + end + + # Removes the describe method from Module and the top level binding. + # @api private + def self.remove_globally! + return unless exposed_globally? + + example_group_aliases.each do |method_name| + change_global_dsl { undef_method method_name } + end + + @exposed_globally = false + end + + # @private + def self.expose_example_group_alias_globally(method_name) + change_global_dsl do + remove_method(method_name) if method_defined?(method_name) + define_method(method_name) { |*a, &b| ::RSpec.__send__(method_name, *a, &b) } + end + end + + # @private + def self.change_global_dsl(&changes) + (class << top_level; self; end).class_exec(&changes) + Module.class_exec(&changes) + end + end + end +end + +# Capture main without an eval. +::RSpec::Core::DSL.top_level = self diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb new file mode 100644 index 0000000..1688f51 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb @@ -0,0 +1,666 @@ +module RSpec + module Core + # Wrapper for an instance of a subclass of {ExampleGroup}. An instance of + # `RSpec::Core::Example` is returned by example definition methods + # such as {ExampleGroup.it it} and is yielded to the {ExampleGroup.it it}, + # {Hooks#before before}, {Hooks#after after}, {Hooks#around around}, + # {MemoizedHelpers::ClassMethods#let let} and + # {MemoizedHelpers::ClassMethods#subject subject} blocks. + # + # This allows us to provide rich metadata about each individual + # example without adding tons of methods directly to the ExampleGroup + # that users may inadvertently redefine. + # + # Useful for configuring logging and/or taking some action based + # on the state of an example's metadata. + # + # @example + # + # RSpec.configure do |config| + # config.before do |example| + # log example.description + # end + # + # config.after do |example| + # log example.description + # end + # + # config.around do |example| + # log example.description + # example.run + # end + # end + # + # shared_examples "auditable" do + # it "does something" do + # log "#{example.full_description}: #{auditable.inspect}" + # auditable.should do_something + # end + # end + # + # @see ExampleGroup + # @note Example blocks are evaluated in the context of an instance + # of an `ExampleGroup`, not in the context of an instance of `Example`. + class Example + # @private + # + # Used to define methods that delegate to this example's metadata. + def self.delegate_to_metadata(key) + define_method(key) { @metadata[key] } + end + + # @return [ExecutionResult] represents the result of running this example. + delegate_to_metadata :execution_result + # @return [String] the relative path to the file where this example was + # defined. + delegate_to_metadata :file_path + # @return [String] the full description (including the docstrings of + # all parent example groups). + delegate_to_metadata :full_description + # @return [String] the exact source location of this example in a form + # like `./path/to/spec.rb:17` + delegate_to_metadata :location + # @return [Boolean] flag that indicates that the example is not expected + # to pass. It will be run and will either have a pending result (if a + # failure occurs) or a failed result (if no failure occurs). + delegate_to_metadata :pending + # @return [Boolean] flag that will cause the example to not run. + # The {ExecutionResult} status will be `:pending`. + delegate_to_metadata :skip + + # Returns the string submitted to `example` or its aliases (e.g. + # `specify`, `it`, etc). If no string is submitted (e.g. + # `it { is_expected.to do_something }`) it returns the message generated + # by the matcher if there is one, otherwise returns a message including + # the location of the example. + def description + description = if metadata[:description].to_s.empty? + location_description + else + metadata[:description] + end + + RSpec.configuration.format_docstrings_block.call(description) + end + + # Returns a description of the example that always includes the location. + def inspect_output + inspect_output = "\"#{description}\"" + unless metadata[:description].to_s.empty? + inspect_output += " (#{location})" + end + inspect_output + end + + # Returns the location-based argument that can be passed to the `rspec` command to rerun this example. + def location_rerun_argument + @location_rerun_argument ||= begin + loaded_spec_files = RSpec.configuration.loaded_spec_files + + Metadata.ascending(metadata) do |meta| + break meta[:location] if loaded_spec_files.include?(meta[:absolute_file_path]) + end + end + end + + # Returns the location-based argument that can be passed to the `rspec` command to rerun this example. + # + # @deprecated Use {#location_rerun_argument} instead. + # @note If there are multiple examples identified by this location, they will use {#id} + # to rerun instead, but this method will still return the location (that's why it is deprecated!). + def rerun_argument + location_rerun_argument + end + + # @return [String] the unique id of this example. Pass + # this at the command line to re-run this exact example. + def id + @id ||= Metadata.id_from(metadata) + end + + # @private + def self.parse_id(id) + # http://rubular.com/r/OMZSAPcAfn + id.match(/\A(.*?)(?:\[([\d\s:,]+)\])?\z/).captures + end + + # Duplicates the example and overrides metadata with the provided + # hash. + # + # @param metadata_overrides [Hash] the hash to override the example metadata + # @return [Example] a duplicate of the example with modified metadata + def duplicate_with(metadata_overrides={}) + new_metadata = metadata.clone.merge(metadata_overrides) + + RSpec::Core::Metadata::RESERVED_KEYS.each do |reserved_key| + new_metadata.delete reserved_key + end + + # don't clone the example group because the new example + # must belong to the same example group (not a clone). + # + # block is nil in new_metadata so we have to get it from metadata. + Example.new(example_group, description.clone, + new_metadata, metadata[:block]) + end + + # @private + def update_inherited_metadata(updates) + metadata.update(updates) do |_key, existing_example_value, _new_inherited_value| + existing_example_value + end + end + + # @attr_reader + # + # Returns the first exception raised in the context of running this + # example (nil if no exception is raised). + attr_reader :exception + + # @attr_reader + # + # Returns the metadata object associated with this example. + attr_reader :metadata + + # @attr_reader + # @private + # + # Returns the example_group_instance that provides the context for + # running this example. + attr_reader :example_group_instance + + # @attr + # @private + attr_accessor :clock + + # Creates a new instance of Example. + # @param example_group_class [Class] the subclass of ExampleGroup in which + # this Example is declared + # @param description [String] the String passed to the `it` method (or + # alias) + # @param user_metadata [Hash] additional args passed to `it` to be used as + # metadata + # @param example_block [Proc] the block of code that represents the + # example + # @api private + def initialize(example_group_class, description, user_metadata, example_block=nil) + @example_group_class = example_group_class + @example_block = example_block + + # Register the example with the group before creating the metadata hash. + # This is necessary since creating the metadata hash triggers + # `when_first_matching_example_defined` callbacks, in which users can + # load RSpec support code which defines hooks. For that to work, the + # examples and example groups must be registered at the time the + # support code is called or be defined afterwards. + # Begin defined beforehand but registered afterwards causes hooks to + # not be applied where they should. + example_group_class.examples << self + + @metadata = Metadata::ExampleHash.create( + @example_group_class.metadata, user_metadata, + example_group_class.method(:next_runnable_index_for), + description, example_block + ) + + config = RSpec.configuration + config.apply_derived_metadata_to(@metadata) + + # This should perhaps be done in `Metadata::ExampleHash.create`, + # but the logic there has no knowledge of `RSpec.world` and we + # want to keep it that way. It's easier to just assign it here. + @metadata[:last_run_status] = config.last_run_statuses[id] + + @example_group_instance = @exception = nil + @clock = RSpec::Core::Time + @reporter = RSpec::Core::NullReporter + end + + # Provide a human-readable representation of this class + def inspect + "#<#{self.class.name} #{description.inspect}>" + end + alias to_s inspect + + # @return [RSpec::Core::Reporter] the current reporter for the example + attr_reader :reporter + + # Returns the example group class that provides the context for running + # this example. + def example_group + @example_group_class + end + + def pending? + !!pending + end + + def skipped? + !!skip + end + + # @api private + # instance_execs the block passed to the constructor in the context of + # the instance of {ExampleGroup}. + # @param example_group_instance the instance of an ExampleGroup subclass + def run(example_group_instance, reporter) + @example_group_instance = example_group_instance + @reporter = reporter + RSpec.configuration.configure_example(self, hooks) + RSpec.current_example = self + + start(reporter) + Pending.mark_pending!(self, pending) if pending? + + begin + if skipped? + Pending.mark_pending! self, skip + elsif !RSpec.configuration.dry_run? + with_around_and_singleton_context_hooks do + begin + run_before_example + RSpec.current_scope = :example + @example_group_instance.instance_exec(self, &@example_block) + + if pending? + Pending.mark_fixed! self + + raise Pending::PendingExampleFixedError, + 'Expected example to fail since it is pending, but it passed.', + [location] + end + rescue Pending::SkipDeclaredInExample => _ + # The "=> _" is normally useless but on JRuby it is a workaround + # for a bug that prevents us from getting backtraces: + # https://github.com/jruby/jruby/issues/4467 + # + # no-op, required metadata has already been set by the `skip` + # method. + rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e + set_exception(e) + ensure + RSpec.current_scope = :after_example_hook + run_after_example + end + end + end + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + set_exception(e) + ensure + @example_group_instance = nil # if you love something... let it go + end + + finish(reporter) + ensure + execution_result.ensure_timing_set(clock) + RSpec.current_example = nil + end + + if RSpec::Support::Ruby.jruby? || RUBY_VERSION.to_f < 1.9 + # :nocov: + # For some reason, rescuing `Support::AllExceptionsExceptOnesWeMustNotRescue` + # in place of `Exception` above can cause the exit status to be the wrong + # thing. I have no idea why. See: + # https://github.com/rspec/rspec-core/pull/2063#discussion_r38284978 + # @private + AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt = Exception + # :nocov: + else + # @private + AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt = Support::AllExceptionsExceptOnesWeMustNotRescue + end + + # Wraps both a `Proc` and an {Example} for use in {Hooks#around + # around} hooks. In around hooks we need to yield this special + # kind of object (rather than the raw {Example}) because when + # there are multiple `around` hooks we have to wrap them recursively. + # + # @example + # + # RSpec.configure do |c| + # c.around do |ex| # Procsy which wraps the example + # if ex.metadata[:key] == :some_value && some_global_condition + # raise "some message" + # end + # ex.run # run delegates to ex.call. + # end + # end + # + # @note This class also exposes the instance methods of {Example}, + # proxying them through to the wrapped {Example} instance. + class Procsy + # The {Example} instance. + attr_reader :example + + Example.public_instance_methods(false).each do |name| + name_sym = name.to_sym + next if name_sym == :run || name_sym == :inspect || name_sym == :to_s + + define_method(name) { |*a, &b| @example.__send__(name, *a, &b) } + end + + Proc.public_instance_methods(false).each do |name| + name_sym = name.to_sym + next if name_sym == :call || name_sym == :inspect || name_sym == :to_s || name_sym == :to_proc + + define_method(name) { |*a, &b| @proc.__send__(name, *a, &b) } + end + + # Calls the proc and notes that the example has been executed. + def call(*args, &block) + @executed = true + @proc.call(*args, &block) + end + alias run call + + # Provides a wrapped proc that will update our `executed?` state when + # executed. + def to_proc + method(:call).to_proc + end + + def initialize(example, &block) + @example = example + @proc = block + @executed = false + end + + # @private + def wrap(&block) + self.class.new(example, &block) + end + + # Indicates whether or not the around hook has executed the example. + def executed? + @executed + end + + # @private + def inspect + @example.inspect.gsub('Example', 'Example::Procsy') + end + end + + # @private + # + # The exception that will be displayed to the user -- either the failure of + # the example or the `pending_exception` if the example is pending. + def display_exception + @exception || execution_result.pending_exception + end + + # @private + # + # Assigns the exception that will be displayed to the user -- either the failure of + # the example or the `pending_exception` if the example is pending. + def display_exception=(ex) + if pending? && !(Pending::PendingExampleFixedError === ex) + @exception = nil + execution_result.pending_fixed = false + execution_result.pending_exception = ex + else + @exception = ex + end + end + + # rubocop:disable Naming/AccessorMethodName + + # @private + # + # Used internally to set an exception in an after hook, which + # captures the exception but doesn't raise it. + def set_exception(exception) + return self.display_exception = exception unless display_exception + + unless RSpec::Core::MultipleExceptionError === display_exception + self.display_exception = RSpec::Core::MultipleExceptionError.new(display_exception) + end + + display_exception.add exception + end + + # @private + # + # Used to set the exception when `aggregate_failures` fails. + def set_aggregate_failures_exception(exception) + return set_exception(exception) unless display_exception + + exception = RSpec::Core::MultipleExceptionError::InterfaceTag.for(exception) + exception.add display_exception + self.display_exception = exception + end + + # rubocop:enable Naming/AccessorMethodName + + # @private + # + # Used internally to set an exception and fail without actually executing + # the example when an exception is raised in before(:context). + def fail_with_exception(reporter, exception) + start(reporter) + set_exception(exception) + finish(reporter) + end + + # @private + # + # Used internally to skip without actually executing the example when + # skip is used in before(:context). + def skip_with_exception(reporter, exception) + start(reporter) + Pending.mark_skipped! self, exception.argument + finish(reporter) + end + + # @private + def instance_exec(*args, &block) + @example_group_instance.instance_exec(*args, &block) + end + + private + + def hooks + example_group_instance.singleton_class.hooks + end + + def with_around_example_hooks + RSpec.current_scope = :before_example_hook + hooks.run(:around, :example, self) { yield } + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + set_exception(e) + end + + def start(reporter) + reporter.example_started(self) + execution_result.started_at = clock.now + end + + def finish(reporter) + pending_message = execution_result.pending_message + + if @exception + execution_result.exception = @exception + record_finished :failed, reporter + reporter.example_failed self + false + elsif pending_message + execution_result.pending_message = pending_message + record_finished :pending, reporter + reporter.example_pending self + true + else + record_finished :passed, reporter + reporter.example_passed self + true + end + end + + def record_finished(status, reporter) + execution_result.record_finished(status, clock.now) + reporter.example_finished(self) + end + + def run_before_example + @example_group_instance.setup_mocks_for_rspec + hooks.run(:before, :example, self) + end + + def with_around_and_singleton_context_hooks + singleton_context_hooks_host = example_group_instance.singleton_class + singleton_context_hooks_host.run_before_context_hooks(example_group_instance) + with_around_example_hooks { yield } + ensure + singleton_context_hooks_host.run_after_context_hooks(example_group_instance) + end + + def run_after_example + assign_generated_description if defined?(::RSpec::Matchers) + hooks.run(:after, :example, self) + verify_mocks + ensure + @example_group_instance.teardown_mocks_for_rspec + end + + def verify_mocks + @example_group_instance.verify_mocks_for_rspec if mocks_need_verification? + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + set_exception(e) + end + + def mocks_need_verification? + exception.nil? || execution_result.pending_fixed? + end + + def assign_generated_description + if metadata[:description].empty? && (description = generate_description) + metadata[:description] = description + metadata[:full_description] += description + end + ensure + RSpec::Matchers.clear_generated_description + end + + def generate_description + RSpec::Matchers.generated_description + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + location_description + " (Got an error when generating description " \ + "from matcher: #{e.class}: #{e.message} -- #{e.backtrace.first})" + end + + def location_description + "example at #{location}" + end + + # Represents the result of executing an example. + # Behaves like a hash for backwards compatibility. + class ExecutionResult + include HashImitatable + + # @return [Symbol] `:passed`, `:failed` or `:pending`. + attr_accessor :status + + # @return [Exception, nil] The failure, if there was one. + attr_accessor :exception + + # @return [Time] When the example started. + attr_accessor :started_at + + # @return [Time] When the example finished. + attr_accessor :finished_at + + # @return [Float] How long the example took in seconds. + attr_accessor :run_time + + # @return [String, nil] The reason the example was pending, + # or nil if the example was not pending. + attr_accessor :pending_message + + # @return [Exception, nil] The exception triggered while + # executing the pending example. If no exception was triggered + # it would no longer get a status of `:pending` unless it was + # tagged with `:skip`. + attr_accessor :pending_exception + + # @return [Boolean] For examples tagged with `:pending`, + # this indicates whether or not it now passes. + attr_accessor :pending_fixed + + def pending_fixed? + !!pending_fixed + end + + # @return [Boolean] Indicates if the example was completely skipped + # (typically done via `:skip` metadata or the `skip` method). Skipped examples + # will have a `:pending` result. A `:pending` result can also come from examples + # that were marked as `:pending`, which causes them to be run, and produces a + # `:failed` result if the example passes. + def example_skipped? + status == :pending && !pending_exception + end + + # @api private + # Records the finished status of the example. + def record_finished(status, finished_at) + self.status = status + calculate_run_time(finished_at) + end + + # @api private + # Populates finished_at and run_time if it has not yet been set + def ensure_timing_set(clock) + calculate_run_time(clock.now) unless finished_at + end + + private + + def calculate_run_time(finished_at) + self.finished_at = finished_at + self.run_time = (finished_at - started_at).to_f + end + + # For backwards compatibility we present `status` as a string + # when presenting the legacy hash interface. + def hash_for_delegation + super.tap do |hash| + hash[:status] &&= status.to_s + end + end + + def set_value(name, value) + value &&= value.to_sym if name == :status + super(name, value) + end + + def get_value(name) + if name == :status + status.to_s if status + else + super + end + end + + def issue_deprecation(_method_name, *_args) + RSpec.deprecate("Treating `metadata[:execution_result]` as a hash", + :replacement => "the attributes methods to access the data") + end + end + end + + # @private + # Provides an execution context for before/after :suite hooks. + class SuiteHookContext < Example + def initialize(hook_description, reporter) + super(AnonymousExampleGroup, hook_description, {}) + @example_group_instance = AnonymousExampleGroup.new + @reporter = reporter + end + + # rubocop:disable Naming/AccessorMethodName + def set_exception(exception) + reporter.notify_non_example_exception(exception, "An error occurred in #{description}.") + RSpec.world.wants_to_quit = true + end + # rubocop:enable Naming/AccessorMethodName + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb new file mode 100644 index 0000000..64fd497 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb @@ -0,0 +1,912 @@ +RSpec::Support.require_rspec_support 'recursive_const_methods' + +module RSpec + module Core + # rubocop:disable Metrics/ClassLength + + # ExampleGroup and {Example} are the main structural elements of + # rspec-core. Consider this example: + # + # RSpec.describe Thing do + # it "does something" do + # end + # end + # + # The object returned by `describe Thing` is a subclass of ExampleGroup. + # The object returned by `it "does something"` is an instance of Example, + # which serves as a wrapper for an instance of the ExampleGroup in which it + # is declared. + # + # Example group bodies (e.g. `describe` or `context` blocks) are evaluated + # in the context of a new subclass of ExampleGroup. Individual examples are + # evaluated in the context of an instance of the specific ExampleGroup + # subclass to which they belong. + # + # Besides the class methods defined here, there are other interesting macros + # defined in {Hooks}, {MemoizedHelpers::ClassMethods} and + # {SharedExampleGroup}. There are additional instance methods available to + # your examples defined in {MemoizedHelpers} and {Pending}. + class ExampleGroup + extend Hooks + + include MemoizedHelpers + extend MemoizedHelpers::ClassMethods + include Pending + extend SharedExampleGroup + + # Define a singleton method for the singleton class (remove the method if + # it's already been defined). + # @private + def self.idempotently_define_singleton_method(name, &definition) + (class << self; self; end).module_exec do + remove_method(name) if method_defined?(name) && instance_method(name).owner == self + define_method(name, &definition) + end + end + + # @!group Metadata + + # The [Metadata](Metadata) object associated with this group. + # @see Metadata + def self.metadata + @metadata ||= nil + end + + # Temporarily replace the provided metadata. + # Intended primarily to allow an example group's singleton class + # to return the metadata of the example that it exists for. This + # is necessary for shared example group inclusion to work properly + # with singleton example groups. + # @private + def self.with_replaced_metadata(meta) + orig_metadata = metadata + @metadata = meta + yield + ensure + @metadata = orig_metadata + end + + # @private + # @return [Metadata] belonging to the parent of a nested {ExampleGroup} + def self.superclass_metadata + @superclass_metadata ||= superclass.respond_to?(:metadata) ? superclass.metadata : nil + end + + # @private + def self.delegate_to_metadata(*names) + names.each do |name| + idempotently_define_singleton_method(name) { metadata.fetch(name) } + end + end + + delegate_to_metadata :described_class, :file_path, :location + + # @return [String] the current example group description + def self.description + description = metadata[:description] + RSpec.configuration.format_docstrings_block.call(description) + end + + # Returns the class or module passed to the `describe` method (or alias). + # Returns nil if the subject is not a class or module. + # @example + # RSpec.describe Thing do + # it "does something" do + # described_class == Thing + # end + # end + # + def described_class + self.class.described_class + end + + # @!endgroup + + # @!group Defining Examples + + # @private + # @macro [attach] define_example_method + # @!scope class + # @method $1 + # @overload $1 + # @overload $1(&example_implementation) + # @param example_implementation [Block] The implementation of the example. + # @overload $1(doc_string, *metadata) + # @param doc_string [String] The example's doc string. + # @param metadata [Array, Hash] Metadata for the example. + # Symbols will be transformed into hash entries with `true` values. + # @overload $1(doc_string, *metadata, &example_implementation) + # @param doc_string [String] The example's doc string. + # @param metadata [Array, Hash] Metadata for the example. + # Symbols will be transformed into hash entries with `true` values. + # @param example_implementation [Block] The implementation of the example. + # @yield [Example] the example object + # @example + # $1 do + # end + # + # $1 "does something" do + # end + # + # $1 "does something", :slow, :uses_js do + # end + # + # $1 "does something", :with => 'additional metadata' do + # end + # + # $1 "does something" do |ex| + # # ex is the Example object that contains metadata about the example + # end + # + # @example + # $1 "does something", :slow, :load_factor => 100 do + # end + # + def self.define_example_method(name, extra_options={}) + idempotently_define_singleton_method(name) do |*all_args, &block| + desc, *args = *all_args + + options = Metadata.build_hash_from(args) + options.update(:skip => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block + options.update(extra_options) + + RSpec::Core::Example.new(self, desc, options, block) + end + end + + # Defines an example within a group. + define_example_method :example + # Defines an example within a group. + # This is the primary API to define a code example. + define_example_method :it + # Defines an example within a group. + # Useful for when your docstring does not read well off of `it`. + # @example + # RSpec.describe MyClass do + # specify "#do_something is deprecated" do + # # ... + # end + # end + define_example_method :specify + + # Shortcut to define an example with `:focus => true`. + # @see example + define_example_method :focus, :focus => true + # Shortcut to define an example with `:focus => true`. + # @see example + define_example_method :fexample, :focus => true + # Shortcut to define an example with `:focus => true`. + # @see example + define_example_method :fit, :focus => true + # Shortcut to define an example with `:focus => true`. + # @see example + define_example_method :fspecify, :focus => true + # Shortcut to define an example with `:skip => 'Temporarily skipped with xexample'`. + # @see example + define_example_method :xexample, :skip => 'Temporarily skipped with xexample' + # Shortcut to define an example with `:skip => 'Temporarily skipped with xit'`. + # @see example + define_example_method :xit, :skip => 'Temporarily skipped with xit' + # Shortcut to define an example with `:skip => 'Temporarily skipped with xspecify'`. + # @see example + define_example_method :xspecify, :skip => 'Temporarily skipped with xspecify' + # Shortcut to define an example with `:skip => true` + # @see example + define_example_method :skip, :skip => true + # Shortcut to define an example with `:pending => true` + # @see example + define_example_method :pending, :pending => true + + # @!endgroup + + # @!group Defining Example Groups + + # @private + # @macro [attach] define_example_group_method + # @!scope class + # @method $1 + # @overload $1 + # @overload $1(&example_group_definition) + # @param example_group_definition [Block] The definition of the example group. + # @overload $1(doc_string, *metadata, &example_implementation) + # @param doc_string [String] The group's doc string. + # @param metadata [Array, Hash] Metadata for the group. + # Symbols will be transformed into hash entries with `true` values. + # @param example_group_definition [Block] The definition of the example group. + # @return [RSpec::Core::ExampleGroup] + # + # Generates a subclass of this example group which inherits + # everything except the examples themselves. + # + # @example + # + # RSpec.describe "something" do # << This describe method is defined in + # # << RSpec::Core::DSL, included in the + # # << global namespace (optional) + # before do + # do_something_before + # end + # + # before(:example, :clean_env) do + # env.clear! + # end + # + # let(:thing) { Thing.new } + # + # $1 "attribute (of something)" do + # # examples in the group get the before hook + # # declared above, and can access `thing` + # end + # + # $1 "needs additional setup", :clean_env, :implementation => JSON do + # # specifies that hooks with matching metadata + # # should be be run additionally + # end + # end + # + # @see DSL#describe + def self.define_example_group_method(name, metadata={}) + idempotently_define_singleton_method(name) do |*args, &example_group_block| + thread_data = RSpec::Support.thread_local_data + top_level = self == ExampleGroup + + registration_collection = + if top_level + if thread_data[:in_example_group] + raise "Creating an isolated context from within a context is " \ + "not allowed. Change `RSpec.#{name}` to `#{name}` or " \ + "move this to a top-level scope." + end + + thread_data[:in_example_group] = true + RSpec.world.example_groups + else + children + end + + begin + description = args.shift + combined_metadata = metadata.dup + combined_metadata.merge!(args.pop) if args.last.is_a? Hash + args << combined_metadata + + subclass(self, description, args, registration_collection, &example_group_block) + ensure + thread_data.delete(:in_example_group) if top_level + end + end + + RSpec::Core::DSL.expose_example_group_alias(name) + end + + define_example_group_method :example_group + + # An alias of `example_group`. Generally used when grouping examples by a + # thing you are describing (e.g. an object, class or method). + # @see example_group + define_example_group_method :describe + + # An alias of `example_group`. Generally used when grouping examples + # contextually (e.g. "with xyz", "when xyz" or "if xyz"). + # @see example_group + define_example_group_method :context + + # Shortcut to temporarily make an example group skipped. + # @see example_group + define_example_group_method :xdescribe, :skip => "Temporarily skipped with xdescribe" + + # Shortcut to temporarily make an example group skipped. + # @see example_group + define_example_group_method :xcontext, :skip => "Temporarily skipped with xcontext" + + # Shortcut to define an example group with `:focus => true`. + # @see example_group + define_example_group_method :fdescribe, :focus => true + + # Shortcut to define an example group with `:focus => true`. + # @see example_group + define_example_group_method :fcontext, :focus => true + + # @!endgroup + + # @!group Including Shared Example Groups + + # @private + # @macro [attach] define_nested_shared_group_method + # @!scope class + # @method $1(name, *args, &block) + # @param name [String, Symbol] The name of the shared group to include. + # @param args [Array] Pass parameters to a shared example group + # @param block [Block] Additional context to pass to the shared group. + # @return [RSpec::Core::ExampleGroup] + # + # @see SharedExampleGroup + def self.define_nested_shared_group_method(new_name, report_label="it should behave like") + idempotently_define_singleton_method(new_name) do |name, *args, &customization_block| + # Pass :caller so the :location metadata is set properly. + # Otherwise, it'll be set to the next line because that's + # the block's source_location. + group = example_group("#{report_label} #{name}", :caller => (the_caller = caller)) do + find_and_eval_shared("examples", name, the_caller.first, *args, &customization_block) + end + group.metadata[:shared_group_name] = name + group + end + end + + # Generates a nested example group and includes the shared content + # mapped to `name` in the nested group. + define_nested_shared_group_method :it_behaves_like, "behaves like" + # Generates a nested example group and includes the shared content + # mapped to `name` in the nested group. + define_nested_shared_group_method :it_should_behave_like + + # Includes shared content mapped to `name` directly in the group in which + # it is declared, as opposed to `it_behaves_like`, which creates a nested + # group. If given a block, that block is also eval'd in the current + # context. + # + # @see SharedExampleGroup + def self.include_context(name, *args, &block) + find_and_eval_shared("context", name, caller.first, *args, &block) + end + + # Includes shared content mapped to `name` directly in the group in which + # it is declared, as opposed to `it_behaves_like`, which creates a nested + # group. If given a block, that block is also eval'd in the current + # context. + # + # @see SharedExampleGroup + def self.include_examples(name, *args, &block) + find_and_eval_shared("examples", name, caller.first, *args, &block) + end + + # Clear memoized values when adding/removing examples + # @private + def self.reset_memoized + @descendant_filtered_examples = nil + @_descendants = nil + @parent_groups = nil + @declaration_locations = nil + end + + # Adds an example to the example group + def self.add_example(example) + reset_memoized + examples << example + end + + # Removes an example from the example group + def self.remove_example(example) + reset_memoized + examples.delete example + end + + # @private + def self.find_and_eval_shared(label, name, inclusion_location, *args, &customization_block) + shared_module = RSpec.world.shared_example_group_registry.find(parent_groups, name) + + unless shared_module + raise ArgumentError, "Could not find shared #{label} #{name.inspect}" + end + + shared_module.include_in( + self, Metadata.relative_path(inclusion_location), + args, customization_block + ) + end + + # @!endgroup + + # @private + def self.subclass(parent, description, args, registration_collection, &example_group_block) + subclass = Class.new(parent) + subclass.set_it_up(description, args, registration_collection, &example_group_block) + subclass.module_exec(&example_group_block) if example_group_block + + # The LetDefinitions module must be included _after_ other modules + # to ensure that it takes precedence when there are name collisions. + # Thus, we delay including it until after the example group block + # has been eval'd. + MemoizedHelpers.define_helpers_on(subclass) + + subclass + end + + # @private + def self.set_it_up(description, args, registration_collection, &example_group_block) + # Ruby 1.9 has a bug that can lead to infinite recursion and a + # SystemStackError if you include a module in a superclass after + # including it in a subclass: https://gist.github.com/845896 + # To prevent this, we must include any modules in + # RSpec::Core::ExampleGroup before users create example groups and have + # a chance to include the same module in a subclass of + # RSpec::Core::ExampleGroup. So we need to configure example groups + # here. + ensure_example_groups_are_configured + + # Register the example with the group before creating the metadata hash. + # This is necessary since creating the metadata hash triggers + # `when_first_matching_example_defined` callbacks, in which users can + # load RSpec support code which defines hooks. For that to work, the + # examples and example groups must be registered at the time the + # support code is called or be defined afterwards. + # Begin defined beforehand but registered afterwards causes hooks to + # not be applied where they should. + registration_collection << self + + @user_metadata = Metadata.build_hash_from(args) + + @metadata = Metadata::ExampleGroupHash.create( + superclass_metadata, @user_metadata, + superclass.method(:next_runnable_index_for), + description, *args, &example_group_block + ) + + config = RSpec.configuration + config.apply_derived_metadata_to(@metadata) + + ExampleGroups.assign_const(self) + + @currently_executing_a_context_hook = false + + config.configure_group(self) + end + + # @private + def self.examples + @examples ||= [] + end + + # @private + def self.filtered_examples + RSpec.world.filtered_examples[self] + end + + # @private + def self.descendant_filtered_examples + @descendant_filtered_examples ||= filtered_examples + + FlatMap.flat_map(children, &:descendant_filtered_examples) + end + + # @private + def self.children + @children ||= [] + end + + # @private + # Traverses the tree of groups, starting with `self`, then the children, recursively. + # Halts the traversal of a branch of the tree as soon as the passed block returns true. + # Note that siblings groups and their sub-trees will continue to be explored. + # This is intended to make it easy to find the top-most group that satisfies some + # condition. + def self.traverse_tree_until(&block) + return if yield self + + children.each do |child| + child.traverse_tree_until(&block) + end + end + + # @private + def self.next_runnable_index_for(file) + if self == ExampleGroup + # We add 1 so the ids start at 1 instead of 0. This is + # necessary for this branch (but not for the other one) + # because we register examples and groups with the + # `children` and `examples` collection BEFORE this + # method is called as part of metadata hash creation, + # but the example group is recorded with + # `RSpec.world.example_group_counts_by_spec_file` AFTER + # the metadata hash is created and the group is returned + # to the caller. + RSpec.world.num_example_groups_defined_in(file) + 1 + else + children.count + examples.count + end + end + + # @private + def self.descendants + @_descendants ||= [self] + FlatMap.flat_map(children, &:descendants) + end + + ## @private + def self.parent_groups + @parent_groups ||= ancestors.select { |a| a < RSpec::Core::ExampleGroup } + end + + # @private + def self.top_level? + superclass == ExampleGroup + end + + # @private + def self.ensure_example_groups_are_configured + unless defined?(@@example_groups_configured) + RSpec.configuration.configure_mock_framework + RSpec.configuration.configure_expectation_framework + # rubocop:disable Style/ClassVars + @@example_groups_configured = true + # rubocop:enable Style/ClassVars + end + end + + # @private + def self.before_context_ivars + @before_context_ivars ||= {} + end + + # @private + def self.store_before_context_ivars(example_group_instance) + each_instance_variable_for_example(example_group_instance) do |ivar| + before_context_ivars[ivar] = example_group_instance.instance_variable_get(ivar) + end + end + + # Returns true if a `before(:context)` or `after(:context)` + # hook is currently executing. + def self.currently_executing_a_context_hook? + @currently_executing_a_context_hook + end + + # @private + def self.run_before_context_hooks(example_group_instance) + set_ivars(example_group_instance, superclass_before_context_ivars) + + @currently_executing_a_context_hook = true + + ContextHookMemoized::Before.isolate_for_context_hook(example_group_instance) do + hooks.run(:before, :context, example_group_instance) + end + ensure + store_before_context_ivars(example_group_instance) + @currently_executing_a_context_hook = false + end + + if RUBY_VERSION.to_f >= 1.9 + # @private + def self.superclass_before_context_ivars + superclass.before_context_ivars + end + else # 1.8.7 + # :nocov: + # @private + def self.superclass_before_context_ivars + if superclass.respond_to?(:before_context_ivars) + superclass.before_context_ivars + else + # `self` must be the singleton class of an ExampleGroup instance. + # On 1.8.7, the superclass of a singleton class of an instance of A + # is A's singleton class. On 1.9+, it's A. On 1.8.7, the first ancestor + # is A, so we can mirror 1.8.7's behavior here. Note that we have to + # search for the first that responds to `before_context_ivars` + # in case a module has been included in the singleton class. + ancestors.find { |a| a.respond_to?(:before_context_ivars) }.before_context_ivars + end + end + # :nocov: + end + + # @private + def self.run_after_context_hooks(example_group_instance) + set_ivars(example_group_instance, before_context_ivars) + + @currently_executing_a_context_hook = true + + ContextHookMemoized::After.isolate_for_context_hook(example_group_instance) do + hooks.run(:after, :context, example_group_instance) + end + ensure + before_context_ivars.clear + @currently_executing_a_context_hook = false + end + + # Runs all the examples in this group. + def self.run(reporter=RSpec::Core::NullReporter) + return if RSpec.world.wants_to_quit + reporter.example_group_started(self) + + should_run_context_hooks = descendant_filtered_examples.any? + begin + RSpec.current_scope = :before_context_hook + run_before_context_hooks(new('before(:context) hook')) if should_run_context_hooks + result_for_this_group = run_examples(reporter) + results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all? + result_for_this_group && results_for_descendants + rescue Pending::SkipDeclaredInExample => ex + for_filtered_examples(reporter) { |example| example.skip_with_exception(reporter, ex) } + true + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex + for_filtered_examples(reporter) { |example| example.fail_with_exception(reporter, ex) } + RSpec.world.wants_to_quit = true if reporter.fail_fast_limit_met? + false + ensure + RSpec.current_scope = :after_context_hook + run_after_context_hooks(new('after(:context) hook')) if should_run_context_hooks + reporter.example_group_finished(self) + end + end + + # @private + def self.ordering_strategy + order = metadata.fetch(:order, :global) + registry = RSpec.configuration.ordering_registry + + registry.fetch(order) do + warn <<-WARNING.gsub(/^ +\|/, '') + |WARNING: Ignoring unknown ordering specified using `:order => #{order.inspect}` metadata. + | Falling back to configured global ordering. + | Unrecognized ordering specified at: #{location} + WARNING + + registry.fetch(:global) + end + end + + # @private + def self.run_examples(reporter) + ordering_strategy.order(filtered_examples).map do |example| + next if RSpec.world.wants_to_quit + instance = new(example.inspect_output) + set_ivars(instance, before_context_ivars) + succeeded = example.run(instance, reporter) + if !succeeded && reporter.fail_fast_limit_met? + RSpec.world.wants_to_quit = true + end + succeeded + end.all? + end + + # @private + def self.for_filtered_examples(reporter, &block) + filtered_examples.each(&block) + + children.each do |child| + reporter.example_group_started(child) + child.for_filtered_examples(reporter, &block) + reporter.example_group_finished(child) + end + false + end + + # @private + def self.declaration_locations + @declaration_locations ||= [Metadata.location_tuple_from(metadata)] + + examples.map { |e| Metadata.location_tuple_from(e.metadata) } + + FlatMap.flat_map(children, &:declaration_locations) + end + + # @return [String] the unique id of this example group. Pass + # this at the command line to re-run this exact example group. + def self.id + Metadata.id_from(metadata) + end + + # @private + def self.top_level_description + parent_groups.last.description + end + + # @private + def self.set_ivars(instance, ivars) + ivars.each { |name, value| instance.instance_variable_set(name, value) } + end + + if RUBY_VERSION.to_f < 1.9 + # :nocov: + # @private + INSTANCE_VARIABLE_TO_IGNORE = '@__inspect_output'.freeze + # :nocov: + else + # @private + INSTANCE_VARIABLE_TO_IGNORE = :@__inspect_output + end + + # @private + def self.each_instance_variable_for_example(group) + group.instance_variables.each do |ivar| + yield ivar unless ivar == INSTANCE_VARIABLE_TO_IGNORE + end + end + + # @private + def initialize(inspect_output=nil) + @__inspect_output = inspect_output || '(no description provided)' + super() # no args get passed + end + + # @private + def inspect + "#<#{self.class} #{@__inspect_output}>" + end + + unless method_defined?(:singleton_class) # for 1.8.7 + # :nocov: + # @private + def singleton_class + class << self; self; end + end + # :nocov: + end + + # @private + def self.update_inherited_metadata(updates) + metadata.update(updates) do |key, existing_group_value, new_inherited_value| + @user_metadata.key?(key) ? existing_group_value : new_inherited_value + end + + RSpec.configuration.configure_group(self) + examples.each { |ex| ex.update_inherited_metadata(updates) } + children.each { |group| group.update_inherited_metadata(updates) } + end + + # Raised when an RSpec API is called in the wrong scope, such as `before` + # being called from within an example rather than from within an example + # group block. + WrongScopeError = Class.new(NoMethodError) + + def self.method_missing(name, *args) + if method_defined?(name) + raise WrongScopeError, + "`#{name}` is not available on an example group (e.g. a " \ + "`describe` or `context` block). It is only available from " \ + "within individual examples (e.g. `it` blocks) or from " \ + "constructs that run in the scope of an example (e.g. " \ + "`before`, `let`, etc)." + end + + super + end + private_class_method :method_missing + + private + + def method_missing(name, *args) + if self.class.respond_to?(name) + raise WrongScopeError, + "`#{name}` is not available from within an example (e.g. an " \ + "`it` block) or from constructs that run in the scope of an " \ + "example (e.g. `before`, `let`, etc). It is only available " \ + "on an example group (e.g. a `describe` or `context` block)." + end + + super(name, *args) + end + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) + end + # rubocop:enable Metrics/ClassLength + + # @private + # Unnamed example group used by `SuiteHookContext`. + class AnonymousExampleGroup < ExampleGroup + def self.metadata + {} + end + end + + # Contains information about the inclusion site of a shared example group. + class SharedExampleGroupInclusionStackFrame + # @return [String] the name of the shared example group + attr_reader :shared_group_name + # @return [String] the location where the shared example was included + attr_reader :inclusion_location + + # @private + def initialize(shared_group_name, inclusion_location) + @shared_group_name = shared_group_name + @inclusion_location = inclusion_location + end + + # @return [String] The {#inclusion_location}, formatted for display by a formatter. + def formatted_inclusion_location + @formatted_inclusion_location ||= begin + RSpec.configuration.backtrace_formatter.backtrace_line( + inclusion_location.sub(/(:\d+):in .+$/, '\1') + ) + end + end + + # @return [String] Description of this stack frame, in the form used by + # RSpec's built-in formatters. + def description + @description ||= "Shared Example Group: #{shared_group_name.inspect} " \ + "called from #{formatted_inclusion_location}" + end + + # @private + def self.current_backtrace + shared_example_group_inclusions.reverse + end + + # @private + def self.with_frame(name, location) + current_stack = shared_example_group_inclusions + if current_stack.any? { |frame| frame.shared_group_name == name } + raise ArgumentError, "can't include shared examples recursively" + else + current_stack << new(name, location) + yield + end + ensure + current_stack.pop + end + + # @private + def self.shared_example_group_inclusions + RSpec::Support.thread_local_data[:shared_example_group_inclusions] ||= [] + end + end + end + + # @private + # + # Namespace for the example group subclasses generated by top-level + # `describe`. + module ExampleGroups + extend Support::RecursiveConstMethods + + def self.assign_const(group) + base_name = base_name_for(group) + const_scope = constant_scope_for(group) + name = disambiguate(base_name, const_scope) + + const_scope.const_set(name, group) + end + + def self.constant_scope_for(group) + const_scope = group.superclass + const_scope = self if const_scope == ::RSpec::Core::ExampleGroup + const_scope + end + + def self.remove_all_constants + constants.each do |constant| + __send__(:remove_const, constant) + end + end + + def self.base_name_for(group) + return "Anonymous".dup if group.description.empty? + + # Convert to CamelCase. + name = ' ' + group.description + name.gsub!(/[^0-9a-zA-Z]+([0-9a-zA-Z])/) do + match = ::Regexp.last_match[1] + match.upcase! + match + end + + name.lstrip! # Remove leading whitespace + name.gsub!(/\W/, ''.freeze) # JRuby, RBX and others don't like non-ascii in const names + + # Ruby requires first const letter to be A-Z. Use `Nested` + # as necessary to enforce that. + name.gsub!(/\A([^A-Z]|\z)/, 'Nested\1'.freeze) + + name + end + + if RUBY_VERSION == '1.9.2' + # :nocov: + class << self + alias _base_name_for base_name_for + def base_name_for(group) + _base_name_for(group) + '_' + end + end + private_class_method :_base_name_for + # :nocov: + end + + def self.disambiguate(name, const_scope) + return name unless const_defined_on?(const_scope, name) + + # Add a trailing number if needed to disambiguate from an existing + # constant. + name << "_2" + name.next! while const_defined_on?(const_scope, name) + name + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb new file mode 100644 index 0000000..d628b76 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb @@ -0,0 +1,235 @@ +RSpec::Support.require_rspec_support "directory_maker" + +module RSpec + module Core + # Persists example ids and their statuses so that we can filter + # to just the ones that failed the last time they ran. + # @private + class ExampleStatusPersister + def self.load_from(file_name) + return [] unless File.exist?(file_name) + ExampleStatusParser.parse(File.read(file_name)) + end + + def self.persist(examples, file_name) + new(examples, file_name).persist + end + + def initialize(examples, file_name) + @examples = examples + @file_name = file_name + end + + def persist + RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(@file_name)) + File.open(@file_name, File::RDWR | File::CREAT) do |f| + # lock the file while reading / persisting to avoid a race + # condition where parallel or unrelated spec runs race to + # update the same file + f.flock(File::LOCK_EX) + unparsed_previous_runs = f.read + f.rewind + f.write(dump_statuses(unparsed_previous_runs)) + f.flush + f.truncate(f.pos) + end + end + + private + + def dump_statuses(unparsed_previous_runs) + statuses_from_previous_runs = ExampleStatusParser.parse(unparsed_previous_runs) + merged_statuses = ExampleStatusMerger.merge(statuses_from_this_run, statuses_from_previous_runs) + ExampleStatusDumper.dump(merged_statuses) + end + + def statuses_from_this_run + @examples.map do |ex| + result = ex.execution_result + + { + :example_id => ex.id, + :status => result.status ? result.status.to_s : Configuration::UNKNOWN_STATUS, + :run_time => result.run_time ? Formatters::Helpers.format_duration(result.run_time) : "" + } + end + end + end + + # Merges together a list of example statuses from this run + # and a list from previous runs (presumably loaded from disk). + # Each example status object is expected to be a hash with + # at least an `:example_id` and a `:status` key. Examples that + # were loaded but not executed (due to filtering, `--fail-fast` + # or whatever) should have a `:status` of `UNKNOWN_STATUS`. + # + # This will produce a new list that: + # - Will be missing examples from previous runs that we know for sure + # no longer exist. + # - Will have the latest known status for any examples that either + # definitively do exist or may still exist. + # - Is sorted by file name and example definition order, so that + # the saved file is easily scannable if users want to inspect it. + # @private + class ExampleStatusMerger + def self.merge(this_run, from_previous_runs) + new(this_run, from_previous_runs).merge + end + + def initialize(this_run, from_previous_runs) + @this_run = hash_from(this_run) + @from_previous_runs = hash_from(from_previous_runs) + @file_exists_cache = Hash.new { |hash, file| hash[file] = File.exist?(file) } + end + + def merge + delete_previous_examples_that_no_longer_exist + + @this_run.merge(@from_previous_runs) do |_ex_id, new, old| + new.fetch(:status) == Configuration::UNKNOWN_STATUS ? old : new + end.values.sort_by(&method(:sort_value_from)) + end + + private + + def hash_from(example_list) + example_list.inject({}) do |hash, example| + hash[example.fetch(:example_id)] = example + hash + end + end + + def delete_previous_examples_that_no_longer_exist + @from_previous_runs.delete_if do |ex_id, _| + example_must_no_longer_exist?(ex_id) + end + end + + def example_must_no_longer_exist?(ex_id) + # Obviously, it exists if it was loaded for this spec run... + return false if @this_run.key?(ex_id) + + spec_file = spec_file_from(ex_id) + + # `this_run` includes examples that were loaded but not executed. + # Given that, if the spec file for this example was loaded, + # but the id does not still exist, it's safe to assume that + # the example must no longer exist. + return true if loaded_spec_files.include?(spec_file) + + # The example may still exist as long as the file exists... + !@file_exists_cache[spec_file] + end + + def loaded_spec_files + @loaded_spec_files ||= Set.new(@this_run.keys.map(&method(:spec_file_from))) + end + + def spec_file_from(ex_id) + ex_id.split("[").first + end + + def sort_value_from(example) + file, scoped_id = Example.parse_id(example.fetch(:example_id)) + [file, *scoped_id.split(":").map(&method(:Integer))] + end + end + + # Dumps a list of hashes in a pretty, human readable format + # for later parsing. The hashes are expected to have symbol + # keys and string values, and each hash should have the same + # set of keys. + # @private + class ExampleStatusDumper + def self.dump(examples) + new(examples).dump + end + + def initialize(examples) + @examples = examples + end + + def dump + return nil if @examples.empty? + (formatted_header_rows + formatted_value_rows).join("\n") << "\n" + end + + private + + def formatted_header_rows + @formatted_header_rows ||= begin + dividers = column_widths.map { |w| "-" * w } + [formatted_row_from(headers.map(&:to_s)), formatted_row_from(dividers)] + end + end + + def formatted_value_rows + @formatted_value_rows ||= rows.map do |row| + formatted_row_from(row) + end + end + + def rows + @rows ||= @examples.map { |ex| ex.values_at(*headers) } + end + + def formatted_row_from(row_values) + padded_values = row_values.each_with_index.map do |value, index| + value.ljust(column_widths[index]) + end + + padded_values.join(" | ") << " |" + end + + def headers + @headers ||= @examples.first.keys + end + + def column_widths + @column_widths ||= begin + value_sets = rows.transpose + + headers.each_with_index.map do |header, index| + values = value_sets[index] << header.to_s + values.map(&:length).max + end + end + end + end + + # Parses a string that has been previously dumped by ExampleStatusDumper. + # Note that this parser is a bit naive in that it does a simple split on + # "\n" and " | ", with no concern for handling escaping. For now, that's + # OK because the values we plan to persist (example id, status, and perhaps + # example duration) are highly unlikely to contain "\n" or " | " -- after + # all, who puts those in file names? + # @private + class ExampleStatusParser + def self.parse(string) + new(string).parse + end + + def initialize(string) + @header_line, _, *@row_lines = string.lines.to_a + end + + def parse + @row_lines.map { |line| parse_row(line) } + end + + private + + def parse_row(line) + Hash[headers.zip(split_line(line))] + end + + def headers + @headers ||= split_line(@header_line).grep(/\S/).map(&:to_sym) + end + + def split_line(line) + line.split(/\s+\|\s+?/, -1) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb new file mode 100644 index 0000000..8d2de0e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb @@ -0,0 +1,231 @@ +module RSpec + module Core + # @private + class FilterManager + attr_reader :exclusions, :inclusions + + def initialize + @exclusions, @inclusions = FilterRules.build + end + + # @api private + # + # @param file_path [String] + # @param line_numbers [Array] + def add_location(file_path, line_numbers) + # locations is a hash of expanded paths to arrays of line + # numbers to match against. e.g. + # { "path/to/file.rb" => [37, 42] } + add_path_to_arrays_filter(:locations, File.expand_path(file_path), line_numbers) + end + + def add_ids(rerun_path, scoped_ids) + # ids is a hash of relative paths to arrays of ids + # to match against. e.g. + # { "./path/to/file.rb" => ["1:1", "2:4"] } + rerun_path = Metadata.relative_path(File.expand_path rerun_path) + add_path_to_arrays_filter(:ids, rerun_path, scoped_ids) + end + + def empty? + inclusions.empty? && exclusions.empty? + end + + def prune(examples) + # Semantically, this is unnecessary (the filtering below will return the empty + # array unmodified), but for perf reasons it's worth exiting early here. Users + # commonly have top-level examples groups that do not have any direct examples + # and instead have nested groups with examples. In that kind of situation, + # `examples` will be empty. + return examples if examples.empty? + + examples = prune_conditionally_filtered_examples(examples) + + if inclusions.standalone? + examples.select { |e| inclusions.include_example?(e) } + else + locations, ids, non_scoped_inclusions = inclusions.split_file_scoped_rules + + examples.select do |ex| + file_scoped_include?(ex.metadata, ids, locations) do + !exclusions.include_example?(ex) && non_scoped_inclusions.include_example?(ex) + end + end + end + end + + def exclude(*args) + exclusions.add(args.last) + end + + def exclude_only(*args) + exclusions.use_only(args.last) + end + + def exclude_with_low_priority(*args) + exclusions.add_with_low_priority(args.last) + end + + def include(*args) + inclusions.add(args.last) + end + + def include_only(*args) + inclusions.use_only(args.last) + end + + def include_with_low_priority(*args) + inclusions.add_with_low_priority(args.last) + end + + private + + def add_path_to_arrays_filter(filter_key, path, values) + filter = inclusions.delete(filter_key) || Hash.new { |h, k| h[k] = [] } + filter[path].concat(values) + inclusions.add(filter_key => filter) + end + + def prune_conditionally_filtered_examples(examples) + examples.reject do |ex| + meta = ex.metadata + !meta.fetch(:if, true) || meta[:unless] + end + end + + # When a user specifies a particular spec location, that takes priority + # over any exclusion filters (such as if the spec is tagged with `:slow` + # and there is a `:slow => true` exclusion filter), but only for specs + # defined in the same file as the location filters. Excluded specs in + # other files should still be excluded. + def file_scoped_include?(ex_metadata, ids, locations) + no_id_filters = ids[ex_metadata[:rerun_file_path]].empty? + no_location_filters = locations[ + File.expand_path(ex_metadata[:rerun_file_path]) + ].empty? + + return yield if no_location_filters && no_id_filters + + MetadataFilter.filter_applies?(:ids, ids, ex_metadata) || + MetadataFilter.filter_applies?(:locations, locations, ex_metadata) + end + end + + # @private + class FilterRules + PROC_HEX_NUMBER = /0x[0-9a-f]+@?/ + PROJECT_DIR = File.expand_path('.') + + attr_accessor :opposite + attr_reader :rules + + def self.build + exclusions = ExclusionRules.new + inclusions = InclusionRules.new + exclusions.opposite = inclusions + inclusions.opposite = exclusions + [exclusions, inclusions] + end + + def initialize(rules={}) + @rules = rules + end + + def add(updated) + @rules.merge!(updated).each_key { |k| opposite.delete(k) } + end + + def add_with_low_priority(updated) + updated = updated.merge(@rules) + opposite.each_pair { |k, v| updated.delete(k) if updated[k] == v } + @rules.replace(updated) + end + + def use_only(updated) + updated.each_key { |k| opposite.delete(k) } + @rules.replace(updated) + end + + def clear + @rules.clear + end + + def delete(key) + @rules.delete(key) + end + + def fetch(*args, &block) + @rules.fetch(*args, &block) + end + + def [](key) + @rules[key] + end + + def empty? + rules.empty? + end + + def each_pair(&block) + @rules.each_pair(&block) + end + + def description + rules.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)', '') + end + + def include_example?(example) + MetadataFilter.apply?(:any?, @rules, example.metadata) + end + end + + # @private + ExclusionRules = FilterRules + + # @private + class InclusionRules < FilterRules + def add(*args) + apply_standalone_filter(*args) || super + end + + def add_with_low_priority(*args) + apply_standalone_filter(*args) || super + end + + def include_example?(example) + @rules.empty? || super + end + + def standalone? + is_standalone_filter?(@rules) + end + + def split_file_scoped_rules + rules_dup = @rules.dup + locations = rules_dup.delete(:locations) { Hash.new { [] } } + ids = rules_dup.delete(:ids) { Hash.new { [] } } + + return locations, ids, self.class.new(rules_dup) + end + + private + + def apply_standalone_filter(updated) + return true if standalone? + return nil unless is_standalone_filter?(updated) + + replace_filters(updated) + true + end + + def replace_filters(new_rules) + @rules.replace(new_rules) + opposite.clear + end + + def is_standalone_filter?(rules) + rules.key?(:full_description) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb new file mode 100644 index 0000000..0e30cce --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb @@ -0,0 +1,20 @@ +module RSpec + module Core + # @private + module FlatMap + if [].respond_to?(:flat_map) + def flat_map(array, &block) + array.flat_map(&block) + end + else # for 1.8.7 + # :nocov: + def flat_map(array, &block) + array.map(&block).flatten(1) + end + # :nocov: + end + + module_function :flat_map + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb new file mode 100644 index 0000000..f0238f8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb @@ -0,0 +1,279 @@ +RSpec::Support.require_rspec_support "directory_maker" + +# ## Built-in Formatters +# +# * progress (default) - Prints dots for passing examples, `F` for failures, `*` +# for pending. +# * documentation - Prints the docstrings passed to `describe` and `it` methods +# (and their aliases). +# * html +# * json - Useful for archiving data for subsequent analysis. +# +# The progress formatter is the default, but you can choose any one or more of +# the other formatters by passing with the `--format` (or `-f` for short) +# command-line option, e.g. +# +# rspec --format documentation +# +# You can also send the output of multiple formatters to different streams, e.g. +# +# rspec --format documentation --format html --out results.html +# +# This example sends the output of the documentation formatter to `$stdout`, and +# the output of the html formatter to results.html. +# +# ## Custom Formatters +# +# You can tell RSpec to use a custom formatter by passing its path and name to +# the `rspec` command. For example, if you define MyCustomFormatter in +# path/to/my_custom_formatter.rb, you would type this command: +# +# rspec --require path/to/my_custom_formatter.rb --format MyCustomFormatter +# +# The reporter calls every formatter with this protocol: +# +# * To start +# * `start(StartNotification)` +# * Once per example group +# * `example_group_started(GroupNotification)` +# * Once per example +# * `example_started(ExampleNotification)` +# * One of these per example, depending on outcome +# * `example_passed(ExampleNotification)` +# * `example_failed(FailedExampleNotification)` +# * `example_pending(ExampleNotification)` +# * Optionally at any time +# * `message(MessageNotification)` +# * At the end of the suite +# * `stop(ExamplesNotification)` +# * `start_dump(NullNotification)` +# * `dump_pending(ExamplesNotification)` +# * `dump_failures(ExamplesNotification)` +# * `dump_summary(SummaryNotification)` +# * `seed(SeedNotification)` +# * `close(NullNotification)` +# +# Only the notifications to which you subscribe your formatter will be called +# on your formatter. To subscribe your formatter use: +# `RSpec::Core::Formatters#register` e.g. +# +# `RSpec::Core::Formatters.register FormatterClassName, :example_passed, :example_failed` +# +# We recommend you implement the methods yourself; for simplicity we provide the +# default formatter output via our notification objects but if you prefer you +# can subclass `RSpec::Core::Formatters::BaseTextFormatter` and override the +# methods you wish to enhance. +# +# @see RSpec::Core::Formatters::BaseTextFormatter +# @see RSpec::Core::Reporter +module RSpec::Core::Formatters + autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter' + autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter' + autoload :FallbackMessageFormatter, 'rspec/core/formatters/fallback_message_formatter' + autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter' + autoload :ProfileFormatter, 'rspec/core/formatters/profile_formatter' + autoload :JsonFormatter, 'rspec/core/formatters/json_formatter' + autoload :BisectDRbFormatter, 'rspec/core/formatters/bisect_drb_formatter' + autoload :ExceptionPresenter, 'rspec/core/formatters/exception_presenter' + autoload :FailureListFormatter, 'rspec/core/formatters/failure_list_formatter' + + # Register the formatter class + # @param formatter_class [Class] formatter class to register + # @param notifications [Array] one or more notifications to be + # registered to the specified formatter + # + # @see RSpec::Core::Formatters::BaseFormatter + def self.register(formatter_class, *notifications) + Loader.formatters[formatter_class] = notifications + end + + # @api private + # + # `RSpec::Core::Formatters::Loader` is an internal class for + # managing formatters used by a particular configuration. It is + # not expected to be used directly, but only through the configuration + # interface. + class Loader + # @api private + # + # Internal formatters are stored here when loaded. + def self.formatters + @formatters ||= {} + end + + # @api private + def initialize(reporter) + @formatters = [] + @reporter = reporter + self.default_formatter = 'progress' + end + + # @return [Array] the loaded formatters + attr_reader :formatters + + # @return [Reporter] the reporter + attr_reader :reporter + + # @return [String] the default formatter to setup, defaults to `progress` + attr_accessor :default_formatter + + # @private + def prepare_default(output_stream, deprecation_stream) + reporter.prepare_default(self, output_stream, deprecation_stream) + end + + # @private + def setup_default(output_stream, deprecation_stream) + add default_formatter, output_stream if @formatters.empty? + + unless @formatters.any? { |formatter| DeprecationFormatter === formatter } + add DeprecationFormatter, deprecation_stream, output_stream + end + + unless existing_formatter_implements?(:message) + add FallbackMessageFormatter, output_stream + end + + return unless RSpec.configuration.profile_examples? + return if existing_formatter_implements?(:dump_profile) + + add RSpec::Core::Formatters::ProfileFormatter, output_stream + end + + # @private + def add(formatter_to_use, *paths) + # If a formatter instance was passed, we can register it directly, + # with no need for any of the further processing that happens below. + if Loader.formatters.key?(formatter_to_use.class) + register formatter_to_use, notifications_for(formatter_to_use.class) + return + end + + formatter_class = find_formatter(formatter_to_use) + + args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) } + + if !Loader.formatters[formatter_class].nil? + formatter = formatter_class.new(*args) + register formatter, notifications_for(formatter_class) + elsif defined?(RSpec::LegacyFormatters) + formatter = RSpec::LegacyFormatters.load_formatter formatter_class, *args + register formatter, formatter.notifications + else + call_site = "Formatter added at: #{::RSpec::CallerFilter.first_non_rspec_line}" + + RSpec.warn_deprecation <<-WARNING.gsub(/\s*\|/, ' ') + |The #{formatter_class} formatter uses the deprecated formatter + |interface not supported directly by RSpec 3. + | + |To continue to use this formatter you must install the + |`rspec-legacy_formatters` gem, which provides support + |for legacy formatters or upgrade the formatter to a + |compatible version. + | + |#{call_site} + WARNING + end + end + + private + + def find_formatter(formatter_to_use) + built_in_formatter(formatter_to_use) || + custom_formatter(formatter_to_use) || + (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - " \ + "maybe you meant 'documentation' or 'progress'?.") + end + + def register(formatter, notifications) + return if duplicate_formatter_exists?(formatter) + @reporter.register_listener formatter, *notifications + @formatters << formatter + formatter + end + + def duplicate_formatter_exists?(new_formatter) + @formatters.any? do |formatter| + formatter.class == new_formatter.class && + has_matching_output?(formatter, new_formatter) + end + end + + def has_matching_output?(formatter, new_formatter) + return true unless formatter.respond_to?(:output) && new_formatter.respond_to?(:output) + formatter.output == new_formatter.output + end + + def existing_formatter_implements?(notification) + @reporter.registered_listeners(notification).any? + end + + def built_in_formatter(key) + case key.to_s + when 'd', 'doc', 'documentation' + DocumentationFormatter + when 'h', 'html' + HtmlFormatter + when 'p', 'progress' + ProgressFormatter + when 'j', 'json' + JsonFormatter + when 'bisect-drb' + BisectDRbFormatter + when 'f', 'failures' + FailureListFormatter + end + end + + def notifications_for(formatter_class) + formatter_class.ancestors.inject(::RSpec::Core::Set.new) do |notifications, klass| + notifications.merge Loader.formatters.fetch(klass) { ::RSpec::Core::Set.new } + end + end + + def custom_formatter(formatter_ref) + if Class === formatter_ref + formatter_ref + elsif string_const?(formatter_ref) + begin + formatter_ref.gsub(/^::/, '').split('::').inject(Object) { |a, e| a.const_get e } + rescue NameError + require(path_for(formatter_ref)) ? retry : raise + end + end + end + + def string_const?(str) + str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str + end + + def path_for(const_ref) + underscore_with_fix_for_non_standard_rspec_naming(const_ref) + end + + def underscore_with_fix_for_non_standard_rspec_naming(string) + underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2') + end + + # activesupport/lib/active_support/inflector/methods.rb, line 48 + def underscore(camel_cased_word) + word = camel_cased_word.to_s.dup + word.gsub!(/::/, '/') + word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2') + word.gsub!(/([a-z\d])([A-Z])/, '\1_\2') + word.tr!("-", "_") + word.downcase! + word + end + + def open_stream(path_or_wrapper) + if RSpec::Core::OutputWrapper === path_or_wrapper + path_or_wrapper.output = open_stream(path_or_wrapper.output) + path_or_wrapper + else + RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path_or_wrapper)) + File.new(path_or_wrapper, 'w') + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb new file mode 100644 index 0000000..4159cba --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb @@ -0,0 +1,45 @@ +RSpec::Support.require_rspec_core "bisect/utilities" + +module RSpec + module Core + module Formatters + # Contains common logic for formatters used by `--bisect` to communicate results + # back to the bisect runner. + # + # Subclasses must define a `notify_results(all_example_ids, failed_example_ids)` + # method. + # @private + class BaseBisectFormatter + def self.inherited(formatter) + Formatters.register formatter, :start_dump, :example_failed, :example_finished + end + + def initialize(expected_failures) + @all_example_ids = [] + @failed_example_ids = [] + @remaining_failures = expected_failures + end + + def example_failed(notification) + @failed_example_ids << notification.example.id + end + + def example_finished(notification) + @all_example_ids << notification.example.id + return unless @remaining_failures.include?(notification.example.id) + @remaining_failures.delete(notification.example.id) + + status = notification.example.execution_result.status + return if status == :failed && !@remaining_failures.empty? + RSpec.world.wants_to_quit = true + end + + def start_dump(_notification) + # `notify_results` is defined in the subclass + notify_results(Bisect::ExampleSetDescriptor.new( + @all_example_ids, @failed_example_ids)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb new file mode 100644 index 0000000..dca4b6d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb @@ -0,0 +1,70 @@ +RSpec::Support.require_rspec_core "formatters/helpers" +require 'stringio' + +module RSpec + module Core + module Formatters + # RSpec's built-in formatters are all subclasses of + # RSpec::Core::Formatters::BaseFormatter. + # + # @see RSpec::Core::Formatters::BaseTextFormatter + # @see RSpec::Core::Reporter + # @see RSpec::Core::Formatters::Protocol + class BaseFormatter + # All formatters inheriting from this formatter will receive these + # notifications. + Formatters.register self, :start, :example_group_started, :close + attr_accessor :example_group + attr_reader :output + + # @api public + # @param output [IO] the formatter output + # @see RSpec::Core::Formatters::Protocol#initialize + def initialize(output) + @output = output || StringIO.new + @example_group = nil + end + + # @api public + # + # @param notification [StartNotification] + # @see RSpec::Core::Formatters::Protocol#start + def start(notification) + start_sync_output + @example_count = notification.count + end + + # @api public + # + # @param notification [GroupNotification] containing example_group + # subclass of `RSpec::Core::ExampleGroup` + # @see RSpec::Core::Formatters::Protocol#example_group_started + def example_group_started(notification) + @example_group = notification.group + end + + # @api public + # + # @param _notification [NullNotification] (Ignored) + # @see RSpec::Core::Formatters::Protocol#close + def close(_notification) + restore_sync_output + end + + private + + def start_sync_output + @old_sync, output.sync = output.sync, true if output_supports_sync + end + + def restore_sync_output + output.sync = @old_sync if output_supports_sync && !output.closed? + end + + def output_supports_sync + output.respond_to?(:sync=) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb new file mode 100644 index 0000000..5d9daba --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb @@ -0,0 +1,75 @@ +RSpec::Support.require_rspec_core "formatters/base_formatter" + +module RSpec + module Core + module Formatters + # Base for all of RSpec's built-in formatters. See + # RSpec::Core::Formatters::BaseFormatter to learn more about all of the + # methods called by the reporter. + # + # @see RSpec::Core::Formatters::BaseFormatter + # @see RSpec::Core::Reporter + class BaseTextFormatter < BaseFormatter + Formatters.register self, + :message, :dump_summary, :dump_failures, :dump_pending, :seed + + # @api public + # + # Used by the reporter to send messages to the output stream. + # + # @param notification [MessageNotification] containing message + def message(notification) + output.puts notification.message + end + + # @api public + # + # Dumps detailed information about each example failure. + # + # @param notification [NullNotification] + def dump_failures(notification) + return if notification.failure_notifications.empty? + output.puts notification.fully_formatted_failed_examples + end + + # @api public + # + # This method is invoked after the dumping of examples and failures. + # Each parameter is assigned to a corresponding attribute. + # + # @param summary [SummaryNotification] containing duration, + # example_count, failure_count and pending_count + def dump_summary(summary) + output.puts summary.fully_formatted + end + + # @private + def dump_pending(notification) + return if notification.pending_examples.empty? + output.puts notification.fully_formatted_pending_examples + end + + # @private + def seed(notification) + return unless notification.seed_used? + output.puts notification.fully_formatted + end + + # @api public + # + # Invoked at the end of a suite run. Allows the formatter to do any + # tidying up, but be aware that formatter output streams may be used + # elsewhere so don't actually close them. + # + # @param _notification [NullNotification] (Ignored) + def close(_notification) + return if output.closed? + + output.puts + + output.flush + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb new file mode 100644 index 0000000..9fb1299 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb @@ -0,0 +1,29 @@ +require 'drb/drb' +RSpec::Support.require_rspec_core "formatters/base_bisect_formatter" + +module RSpec + module Core + module Formatters + # Used by `--bisect`. When it shells out and runs a portion of the suite, it uses + # this formatter as a means to have the status reported back to it, via DRb. + # + # Note that since DRb calls carry considerable overhead compared to normal + # method calls, we try to minimize the number of DRb calls for perf reasons, + # opting to communicate only at the start and the end of the run, rather than + # after each example. + # @private + class BisectDRbFormatter < BaseBisectFormatter + def initialize(_output) + drb_uri = "druby://localhost:#{RSpec.configuration.drb_port}" + @bisect_server = DRbObject.new_with_uri(drb_uri) + RSpec.configuration.files_or_directories_to_run = @bisect_server.files_or_directories_to_run + super(Set.new(@bisect_server.expected_failures)) + end + + def notify_results(results) + @bisect_server.latest_run_results = results + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb new file mode 100644 index 0000000..35f01a6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb @@ -0,0 +1,157 @@ +RSpec::Support.require_rspec_core "formatters/base_text_formatter" + +module RSpec + module Core + module Formatters + # @private + # Produces progress output while bisecting. + class BisectProgressFormatter < BaseTextFormatter + def initialize(output, bisect_runner) + super(output) + @bisect_runner = bisect_runner + end + + def bisect_starting(notification) + @round_count = 0 + output.puts bisect_started_message(notification) + output.print "Running suite to find failures..." + end + + def bisect_original_run_complete(notification) + failures = Helpers.pluralize(notification.failed_example_ids.size, "failing example") + non_failures = Helpers.pluralize(notification.non_failing_example_ids.size, "non-failing example") + + output.puts " (#{Helpers.format_duration(notification.duration)})" + output.puts "Starting bisect with #{failures} and #{non_failures}." + end + + def bisect_dependency_check_started(_notification) + output.print "Checking that failure(s) are order-dependent.." + end + + def bisect_dependency_check_passed(_notification) + output.puts " failure appears to be order-dependent" + end + + def bisect_dependency_check_failed(_notification) + output.puts " failure(s) do not require any non-failures to run first" + + if @bisect_runner == :fork + output.puts + output.puts "=" * 80 + output.puts "NOTE: this bisect run used `config.bisect_runner = :fork`, which generally" + output.puts "provides significantly faster bisection runs than the old shell-based runner," + output.puts "but may inaccurately report that no non-failures are required. If this result" + output.puts "is unexpected, consider setting `config.bisect_runner = :shell` and trying again." + output.puts "=" * 80 + end + end + + def bisect_round_started(notification, include_trailing_space=true) + @round_count += 1 + range_desc = notification.candidate_range.description + + output.print "\nRound #{@round_count}: bisecting over non-failing #{range_desc}" + output.print " " if include_trailing_space + end + + def bisect_round_ignoring_ids(notification) + range_desc = notification.ignore_range.description + + output.print " ignoring #{range_desc}" + output.print " (#{Helpers.format_duration(notification.duration)})" + end + + def bisect_round_detected_multiple_culprits(notification) + output.print " multiple culprits detected - splitting candidates" + output.print " (#{Helpers.format_duration(notification.duration)})" + end + + def bisect_individual_run_complete(_) + output.print '.' + end + + def bisect_complete(notification) + output.puts "\nBisect complete! Reduced necessary non-failing examples " \ + "from #{notification.original_non_failing_count} to " \ + "#{notification.remaining_count} in " \ + "#{Helpers.format_duration(notification.duration)}." + end + + def bisect_repro_command(notification) + output.puts "\nThe minimal reproduction command is:\n #{notification.repro}" + end + + def bisect_failed(notification) + output.puts "\nBisect failed! #{notification.failure_explanation}" + end + + def bisect_aborted(notification) + output.puts "\n\nBisect aborted!" + output.puts "\nThe most minimal reproduction command discovered so far is:\n #{notification.repro}" + end + + private + + def bisect_started_message(notification) + options = notification.original_cli_args.join(' ') + "Bisect started using options: #{options.inspect}" + end + end + + # @private + # Produces detailed debug output while bisecting. Used when bisect is + # performed with `--bisect=verbose`. Designed to provide details for + # us when we need to troubleshoot bisect bugs. + class BisectDebugFormatter < BisectProgressFormatter + def bisect_original_run_complete(notification) + output.puts " (#{Helpers.format_duration(notification.duration)})" + + output.puts " - #{describe_ids 'Failing examples', notification.failed_example_ids}" + output.puts " - #{describe_ids 'Non-failing examples', notification.non_failing_example_ids}" + end + + def bisect_individual_run_start(notification) + output.print "\n - Running: #{notification.command}" + end + + def bisect_individual_run_complete(notification) + output.print " (#{Helpers.format_duration(notification.duration)})" + end + + def bisect_dependency_check_passed(_notification) + output.print "\n - Failure appears to be order-dependent" + end + + def bisect_dependency_check_failed(_notification) + output.print "\n - Failure is not order-dependent" + end + + def bisect_round_started(notification) + super(notification, false) + end + + def bisect_round_ignoring_ids(notification) + output.print "\n - #{describe_ids 'Examples we can safely ignore', notification.ids_to_ignore}" + output.print "\n - #{describe_ids 'Remaining non-failing examples', notification.remaining_ids}" + end + + def bisect_round_detected_multiple_culprits(_notification) + output.print "\n - Multiple culprits detected - splitting candidates" + end + + private + + def describe_ids(description, ids) + organized_ids = Formatters::Helpers.organize_ids(ids) + formatted_ids = organized_ids.map { |id| " - #{id}" }.join("\n") + "#{description} (#{ids.size}):\n#{formatted_ids}" + end + + def bisect_started_message(notification) + "#{super} and bisect runner: #{notification.bisect_runner.inspect}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb new file mode 100644 index 0000000..79e3062 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb @@ -0,0 +1,76 @@ +module RSpec + module Core + module Formatters + # ConsoleCodes provides helpers for formatting console output + # with ANSI codes, e.g. color's and bold. + module ConsoleCodes + # @private + VT100_CODES = + { + :black => 30, + :red => 31, + :green => 32, + :yellow => 33, + :blue => 34, + :magenta => 35, + :cyan => 36, + :white => 37, + :bold_black => '1;30', + :bold_red => '1;31', + :bold_green => '1;32', + :bold_yellow => '1;33', + :bold_blue => '1;34', + :bold_magenta => '1;35', + :bold_cyan => '1;36', + :bold_white => '1;37', + :bold => 1, + } + # @private + VT100_CODE_VALUES = VT100_CODES.invert + + module_function + + # @private + def config_colors_to_methods + @config_colors_to_methods ||= + Configuration.instance_methods.grep(/_color\z/).inject({}) do |hash, method| + hash[method.to_s.sub(/_color\z/, '').to_sym] = method + hash + end + end + + # Fetches the correct code for the supplied symbol, or checks + # that a code is valid. Defaults to white (37). + # + # @param code_or_symbol [Symbol, Fixnum] Symbol or code to check + # @return [Fixnum] a console code + def console_code_for(code_or_symbol) + if (config_method = config_colors_to_methods[code_or_symbol]) + console_code_for RSpec.configuration.__send__(config_method) + elsif VT100_CODE_VALUES.key?(code_or_symbol) + code_or_symbol + else + VT100_CODES.fetch(code_or_symbol) do + console_code_for(:white) + end + end + end + + # Wraps a piece of text in ANSI codes with the supplied code. Will + # only apply the control code if `RSpec.configuration.color_enabled?` + # returns true. + # + # @param text [String] the text to wrap + # @param code_or_symbol [Symbol, Fixnum] the desired control code + # @return [String] the wrapped text + def wrap(text, code_or_symbol) + if RSpec.configuration.color_enabled? + "\e[#{console_code_for(code_or_symbol)}m#{text}\e[0m" + else + text + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb new file mode 100644 index 0000000..110a71f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb @@ -0,0 +1,223 @@ +RSpec::Support.require_rspec_core "formatters/helpers" + +module RSpec + module Core + module Formatters + # @private + class DeprecationFormatter + Formatters.register self, :deprecation, :deprecation_summary + + attr_reader :count, :deprecation_stream, :summary_stream + + def initialize(deprecation_stream, summary_stream) + @deprecation_stream = deprecation_stream + @summary_stream = summary_stream + @seen_deprecations = Set.new + @count = 0 + end + alias :output :deprecation_stream + + def printer + @printer ||= case deprecation_stream + when File + ImmediatePrinter.new(FileStream.new(deprecation_stream), + summary_stream, self) + when RaiseErrorStream + ImmediatePrinter.new(deprecation_stream, summary_stream, self) + else + DelayedPrinter.new(deprecation_stream, summary_stream, self) + end + end + + def deprecation(notification) + return if @seen_deprecations.include? notification + + @count += 1 + printer.print_deprecation_message notification + @seen_deprecations << notification + end + + def deprecation_summary(_notification) + printer.deprecation_summary + end + + def deprecation_message_for(data) + if data.message + SpecifiedDeprecationMessage.new(data) + else + GeneratedDeprecationMessage.new(data) + end + end + + RAISE_ERROR_CONFIG_NOTICE = <<-EOS.gsub(/^\s+\|/, '') + | + |If you need more of the backtrace for any of these deprecations to + |identify where to make the necessary changes, you can configure + |`config.raise_errors_for_deprecations!`, and it will turn the + |deprecation warnings into errors, giving you the full backtrace. + EOS + + DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set " \ + "`config.deprecation_stream` to a file for full output." + TOO_MANY_WARNINGS_NOTICE = "Too many similar deprecation messages " \ + "reported, disregarding further reports. #{DEPRECATION_STREAM_NOTICE}" + + # @private + SpecifiedDeprecationMessage = Struct.new(:type) do + def initialize(data) + @message = data.message + super deprecation_type_for(data) + end + + def to_s + output_formatted @message + end + + def too_many_warnings_message + TOO_MANY_WARNINGS_NOTICE + end + + private + + def output_formatted(str) + return str unless str.lines.count > 1 + separator = '-' * 80 + "#{separator}\n#{str.chomp}\n#{separator}" + end + + def deprecation_type_for(data) + data.message.gsub(/(\w+\/)+\w+\.rb:\d+/, '') + end + end + + # @private + GeneratedDeprecationMessage = Struct.new(:type) do + def initialize(data) + @data = data + super data.deprecated + end + + def to_s + msg = String.new("#{@data.deprecated} is deprecated.") + msg << " Use #{@data.replacement} instead." if @data.replacement + msg << " Called from #{@data.call_site}." if @data.call_site + msg + end + + def too_many_warnings_message + "Too many uses of deprecated '#{type}'. #{DEPRECATION_STREAM_NOTICE}" + end + end + + # @private + class ImmediatePrinter + attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter + + def initialize(deprecation_stream, summary_stream, deprecation_formatter) + @deprecation_stream = deprecation_stream + + @summary_stream = summary_stream + @deprecation_formatter = deprecation_formatter + end + + def print_deprecation_message(data) + deprecation_message = deprecation_formatter.deprecation_message_for(data) + deprecation_stream.puts deprecation_message.to_s + end + + def deprecation_summary + return if deprecation_formatter.count.zero? + deprecation_stream.summarize(summary_stream, deprecation_formatter.count) + end + end + + # @private + class DelayedPrinter + TOO_MANY_USES_LIMIT = 4 + + attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter + + def initialize(deprecation_stream, summary_stream, deprecation_formatter) + @deprecation_stream = deprecation_stream + @summary_stream = summary_stream + @deprecation_formatter = deprecation_formatter + @seen_deprecations = Hash.new { 0 } + @deprecation_messages = Hash.new { |h, k| h[k] = [] } + end + + def print_deprecation_message(data) + deprecation_message = deprecation_formatter.deprecation_message_for(data) + @seen_deprecations[deprecation_message] += 1 + + stash_deprecation_message(deprecation_message) + end + + def stash_deprecation_message(deprecation_message) + if @seen_deprecations[deprecation_message] < TOO_MANY_USES_LIMIT + @deprecation_messages[deprecation_message] << deprecation_message.to_s + elsif @seen_deprecations[deprecation_message] == TOO_MANY_USES_LIMIT + @deprecation_messages[deprecation_message] << deprecation_message.too_many_warnings_message + end + end + + def deprecation_summary + return unless @deprecation_messages.any? + + print_deferred_deprecation_warnings + deprecation_stream.puts RAISE_ERROR_CONFIG_NOTICE + + summary_stream.puts "\n#{Helpers.pluralize(deprecation_formatter.count, 'deprecation warning')} total" + end + + def print_deferred_deprecation_warnings + deprecation_stream.puts "\nDeprecation Warnings:\n\n" + @deprecation_messages.keys.sort_by(&:type).each do |deprecation| + messages = @deprecation_messages[deprecation] + messages.each { |msg| deprecation_stream.puts msg } + deprecation_stream.puts + end + end + end + + # @private + # Not really a stream, but is usable in place of one. + class RaiseErrorStream + def puts(message) + raise DeprecationError, message + end + + def summarize(summary_stream, deprecation_count) + summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} found." + end + end + + # @private + # Wraps a File object and provides file-specific operations. + class FileStream + def initialize(file) + @file = file + + # In one of my test suites, I got lots of duplicate output in the + # deprecation file (e.g. 200 of the same deprecation, even though + # the `puts` below was only called 6 times). Setting `sync = true` + # fixes this (but we really have no idea why!). + @file.sync = true + end + + def puts(*args) + @file.puts(*args) + end + + def summarize(summary_stream, deprecation_count) + path = @file.respond_to?(:path) ? @file.path : @file.inspect + summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} logged to #{path}" + puts RAISE_ERROR_CONFIG_NOTICE + end + end + end + end + + # Deprecation Error. + DeprecationError = Class.new(StandardError) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb new file mode 100644 index 0000000..f64919c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb @@ -0,0 +1,102 @@ +RSpec::Support.require_rspec_core "formatters/base_text_formatter" +RSpec::Support.require_rspec_core "formatters/console_codes" + +module RSpec + module Core + module Formatters + # @private + class DocumentationFormatter < BaseTextFormatter + Formatters.register self, :example_started, :example_group_started, :example_group_finished, + :example_passed, :example_pending, :example_failed + + def initialize(output) + super + @group_level = 0 + + @example_running = false + @messages = [] + end + + def example_started(_notification) + @example_running = true + end + + def example_group_started(notification) + output.puts if @group_level == 0 + output.puts "#{current_indentation}#{notification.group.description.strip}" + + @group_level += 1 + end + + def example_group_finished(_notification) + @group_level -= 1 if @group_level > 0 + end + + def example_passed(passed) + output.puts passed_output(passed.example) + + flush_messages + @example_running = false + end + + def example_pending(pending) + output.puts pending_output(pending.example, + pending.example.execution_result.pending_message) + + flush_messages + @example_running = false + end + + def example_failed(failure) + output.puts failure_output(failure.example) + + flush_messages + @example_running = false + end + + def message(notification) + if @example_running + @messages << notification.message + else + output.puts "#{current_indentation}#{notification.message}" + end + end + + private + + def flush_messages + @messages.each do |message| + output.puts "#{current_indentation(1)}#{message}" + end + + @messages.clear + end + + def passed_output(example) + ConsoleCodes.wrap("#{current_indentation}#{example.description.strip}", :success) + end + + def pending_output(example, message) + ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \ + "(PENDING: #{message})", + :pending) + end + + def failure_output(example) + ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \ + "(FAILED - #{next_failure_index})", + :failure) + end + + def next_failure_index + @next_failure_index ||= 0 + @next_failure_index += 1 + end + + def current_indentation(offset=0) + ' ' * (@group_level + offset) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb new file mode 100644 index 0000000..1f9ed37 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb @@ -0,0 +1,553 @@ +# encoding: utf-8 +RSpec::Support.require_rspec_core "formatters/console_codes" +RSpec::Support.require_rspec_core "formatters/snippet_extractor" +RSpec::Support.require_rspec_core 'formatters/syntax_highlighter' +RSpec::Support.require_rspec_support "encoded_string" + +module RSpec + module Core + module Formatters + # @private + class ExceptionPresenter + attr_reader :exception, :example, :description, :message_color, + :detail_formatter, :extra_detail_formatter, :backtrace_formatter + private :message_color, :detail_formatter, :extra_detail_formatter, :backtrace_formatter + + def initialize(exception, example, options={}) + @exception = exception + @example = example + @message_color = options.fetch(:message_color) { RSpec.configuration.failure_color } + @description = options.fetch(:description) { example.full_description } + @detail_formatter = options.fetch(:detail_formatter) { Proc.new {} } + @extra_detail_formatter = options.fetch(:extra_detail_formatter) { Proc.new {} } + @backtrace_formatter = options.fetch(:backtrace_formatter) { RSpec.configuration.backtrace_formatter } + @indentation = options.fetch(:indentation, 2) + @skip_shared_group_trace = options.fetch(:skip_shared_group_trace, false) + @failure_lines = options[:failure_lines] + end + + def message_lines + add_shared_group_lines(failure_lines, Notifications::NullColorizer) + end + + def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + add_shared_group_lines(failure_lines, colorizer).map do |line| + colorizer.wrap line, message_color + end + end + + def formatted_backtrace(exception=@exception) + backtrace_formatter.format_backtrace(exception.backtrace, example.metadata) + + formatted_cause(exception) + end + + if RSpec::Support::RubyFeatures.supports_exception_cause? + def formatted_cause(exception) + last_cause = final_exception(exception, [exception]) + cause = [] + + if exception.cause + cause << '------------------' + cause << '--- Caused by: ---' + cause << "#{exception_class_name(last_cause)}:" unless exception_class_name(last_cause) =~ /RSpec/ + + encoded_string(exception_message_string(last_cause)).split("\n").each do |line| + cause << " #{line}" + end + + unless last_cause.backtrace.nil? || last_cause.backtrace.empty? + lines = backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata) + lines = [lines[0]] unless RSpec.configuration.full_cause_backtrace # rubocop:disable Metrics/BlockNesting + + lines.each do |line| + cause << (" #{line}") + end + end + end + + cause + end + else + # :nocov: + def formatted_cause(_) + [] + end + # :nocov: + end + + def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + formatted_backtrace.map do |backtrace_info| + colorizer.wrap "# #{backtrace_info}", RSpec.configuration.detail_color + end + end + + def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) + lines = fully_formatted_lines(failure_number, colorizer) + lines.join("\n") << "\n" + end + + def fully_formatted_lines(failure_number, colorizer) + lines = [ + encoded_description(description), + detail_formatter.call(example, colorizer), + formatted_message_and_backtrace(colorizer), + extra_detail_formatter.call(failure_number, colorizer), + ].compact.flatten + + lines = indent_lines(lines, failure_number) + lines.unshift("") + lines + end + + private + + def final_exception(exception, previous=[]) + cause = exception.cause + + if cause && Exception === cause && !previous.include?(cause) + previous << cause + final_exception(cause, previous) + else + exception + end + end + + if String.method_defined?(:encoding) + def encoding_of(string) + string.encoding + end + + def encoded_string(string) + RSpec::Support::EncodedString.new(string, Encoding.default_external) + end + else # for 1.8.7 + # :nocov: + def encoding_of(_string) + end + + def encoded_string(string) + RSpec::Support::EncodedString.new(string) + end + # :nocov: + end + + def indent_lines(lines, failure_number) + alignment_basis = ' ' * @indentation + alignment_basis << "#{failure_number}) " if failure_number + indentation = ' ' * alignment_basis.length + + lines.each_with_index.map do |line, index| + if index == 0 + "#{alignment_basis}#{line}" + elsif line.empty? + line + else + "#{indentation}#{line}" + end + end + end + + def exception_class_name(exception=@exception) + name = exception.class.name.to_s + name = "(anonymous error class)" if name == '' + name + end + + def failure_lines + @failure_lines ||= [].tap do |lines| + lines.concat(failure_slash_error_lines) + + sections = [failure_slash_error_lines, exception_lines] + if sections.any? { |section| section.size > 1 } && !exception_lines.first.empty? + lines << '' + end + + lines.concat(exception_lines) + lines.concat(extra_failure_lines) + end + end + + def failure_slash_error_lines + lines = read_failed_lines + if lines.count == 1 + lines[0] = "Failure/Error: #{lines[0].strip}" + else + least_indentation = SnippetExtractor.least_indentation_from(lines) + lines = lines.map { |line| line.sub(/^#{least_indentation}/, ' ') } + lines.unshift('Failure/Error:') + end + lines + end + + # rubocop:disable Lint/RescueException + # :nocov: + if SyntaxError.instance_methods.include?(:detailed_message) + def exception_message_string(exception) + case exception + when SyntaxError then exception.detailed_message.to_s + else + exception.message.to_s + end + rescue Exception => other + "A #{exception.class} for which `exception.message.to_s` raises #{other.class}." + end + else + def exception_message_string(exception) + exception.message.to_s + rescue Exception => other + "A #{exception.class} for which `exception.message.to_s` raises #{other.class}." + end + end + # :nocov: + # rubocop:enable Lint/RescueException + + def exception_lines + @exception_lines ||= begin + lines = [] + lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/ + encoded_string(exception_message_string(exception)).split("\n").each do |line| + lines << (line.empty? ? line : " #{line}") + end + lines + end + end + + def extra_failure_lines + @extra_failure_lines ||= begin + lines = Array(example.metadata[:extra_failure_lines]) + unless lines.empty? + lines.unshift('') unless lines.first == '' + lines.push('') unless lines.last == '' + end + lines + end + end + + def add_shared_group_lines(lines, colorizer) + return lines if @skip_shared_group_trace + + example.metadata[:shared_group_inclusion_backtrace].each do |frame| + lines << colorizer.wrap(frame.description, RSpec.configuration.default_color) + end + + lines + end + + def read_failed_lines + matching_line = find_failed_line + unless matching_line + return ["Unable to find matching line from backtrace"] + end + + file_and_line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/) + + unless file_and_line_number + return ["Unable to infer file and line number from backtrace"] + end + + file_path, line_number = file_and_line_number[1..2] + max_line_count = RSpec.configuration.max_displayed_failure_line_count + lines = SnippetExtractor.extract_expression_lines_at(file_path, line_number.to_i, max_line_count) + RSpec.world.syntax_highlighter.highlight(lines) + rescue SnippetExtractor::NoSuchFileError + ["Unable to find #{file_path} to read failed line"] + rescue SnippetExtractor::NoSuchLineError + ["Unable to find matching line in #{file_path}"] + rescue SecurityError + # :nocov: - SecurityError is no longer produced starting in ruby 2.7 + ["Unable to read failed line"] + # :nocov: + end + + def find_failed_line + line_regex = RSpec.configuration.in_project_source_dir_regex + loaded_spec_files = RSpec.configuration.loaded_spec_files + + reduced_backtrace = + exception_backtrace.reject do |line| + line.start_with?(" "#{@example.full_description} FIXED", + :message_color => RSpec.configuration.fixed_color, + :failure_lines => [ + "Expected pending '#{@execution_result.pending_message}' to fail. No error was raised." + ] + } + elsif @execution_result.status == :pending + options = { + :message_color => RSpec.configuration.pending_color, + :detail_formatter => PENDING_DETAIL_FORMATTER + } + if RSpec.configuration.pending_failure_output == :no_backtrace + options[:backtrace_formatter] = EmptyBacktraceFormatter + end + options + end + end + + def with_multiple_error_options_as_needed(exception, options) + return options unless multiple_exceptions_error?(exception) + + options = options.merge( + :failure_lines => [], + :extra_detail_formatter => sub_failure_list_formatter(exception, options[:message_color]), + :detail_formatter => multiple_exception_summarizer(exception, + options[:detail_formatter], + options[:message_color]) + ) + + return options unless exception.aggregation_metadata[:hide_backtrace] + options[:backtrace_formatter] = EmptyBacktraceFormatter + options + end + + def multiple_exceptions_error?(exception) + MultipleExceptionError::InterfaceTag === exception + end + + def multiple_exception_summarizer(exception, prior_detail_formatter, color) + lambda do |example, colorizer| + summary = if exception.aggregation_metadata[:hide_backtrace] + # Since the backtrace is hidden, the subfailures will come + # immediately after this, and using `:` will read well. + "Got #{exception.exception_count_description}:" + else + # The backtrace comes after this, so using a `:` doesn't make sense + # since the failures may be many lines below. + "#{exception.summary}." + end + + summary = colorizer.wrap(summary, color || RSpec.configuration.failure_color) + return summary unless prior_detail_formatter + [ + prior_detail_formatter.call(example, colorizer), + summary + ] + end + end + + def sub_failure_list_formatter(exception, message_color) + common_backtrace_truncater = CommonBacktraceTruncater.new(exception) + + lambda do |failure_number, colorizer| + FlatMap.flat_map(exception.all_exceptions.each_with_index) do |failure, index| + options = with_multiple_error_options_as_needed( + failure, + :description => nil, + :indentation => 0, + :message_color => message_color || RSpec.configuration.failure_color, + :skip_shared_group_trace => true + ) + + failure = common_backtrace_truncater.with_truncated_backtrace(failure) + presenter = ExceptionPresenter.new(failure, @example, options) + presenter.fully_formatted_lines( + "#{"#{failure_number}." if failure_number}#{index + 1}", + colorizer + ) + end + end + end + + # @private + # Used to prevent a confusing backtrace from showing up from the `aggregate_failures` + # block declared for `:aggregate_failures` metadata. + module EmptyBacktraceFormatter + def self.format_backtrace(*) + [] + end + end + + # @private + class CommonBacktraceTruncater + def initialize(parent) + @parent = parent + end + + def with_truncated_backtrace(child) + child_bt = child.backtrace + parent_bt = @parent.backtrace + return child if child_bt.nil? || child_bt.empty? || parent_bt.nil? + + index_before_first_common_frame = -1.downto(-child_bt.size).find do |index| + parent_bt[index] != child_bt[index] + end + + return child if index_before_first_common_frame.nil? + return child if index_before_first_common_frame == -1 + + child = child.dup + child.set_backtrace(child_bt[0..index_before_first_common_frame]) + child + end + end + end + + # @private + PENDING_DETAIL_FORMATTER = Proc.new do |example, colorizer| + colorizer.wrap("# #{example.execution_result.pending_message}", :detail) + end + end + end + + # Provides a single exception instance that provides access to + # multiple sub-exceptions. This is used in situations where a single + # individual spec has multiple exceptions, such as one in the `it` block + # and one in an `after` block. + class MultipleExceptionError < StandardError + # @private + # Used so there is a common module in the ancestor chain of this class + # and `RSpec::Expectations::MultipleExpectationsNotMetError`, which allows + # code to detect exceptions that are instances of either, without first + # checking to see if rspec-expectations is loaded. + module InterfaceTag + # Appends the provided exception to the list. + # @param exception [Exception] Exception to append to the list. + # @private + def add(exception) + # `PendingExampleFixedError` can be assigned to an example that initially has no + # failures, but when the `aggregate_failures` around hook completes, it notifies of + # a failure. If we do not ignore `PendingExampleFixedError` it would be surfaced to + # the user as part of a multiple exception error, which is undesirable. While it's + # pretty weird we handle this here, it's the best solution I've been able to come + # up with, and `PendingExampleFixedError` always represents the _lack_ of any exception + # so clearly when we are transitioning to a `MultipleExceptionError`, it makes sense to + # ignore it. + return if Pending::PendingExampleFixedError === exception + + return if exception == self + + all_exceptions << exception + + if exception.class.name =~ /RSpec/ + failures << exception + else + other_errors << exception + end + end + + # Provides a way to force `ex` to be something that satisfies the multiple + # exception error interface. If it already satisfies it, it will be returned; + # otherwise it will wrap it in a `MultipleExceptionError`. + # @private + def self.for(ex) + return ex if self === ex + MultipleExceptionError.new(ex) + end + end + + include InterfaceTag + + # @return [Array] The list of failures. + attr_reader :failures + + # @return [Array] The list of other errors. + attr_reader :other_errors + + # @return [Array] The list of failures and other exceptions, combined. + attr_reader :all_exceptions + + # @return [Hash] Metadata used by RSpec for formatting purposes. + attr_reader :aggregation_metadata + + # @return [nil] Provided only for interface compatibility with + # `RSpec::Expectations::MultipleExpectationsNotMetError`. + attr_reader :aggregation_block_label + + # @param exceptions [Array] The initial list of exceptions. + def initialize(*exceptions) + super() + + @failures = [] + @other_errors = [] + @all_exceptions = [] + @aggregation_metadata = { :hide_backtrace => true } + @aggregation_block_label = nil + + exceptions.each { |e| add e } + end + + # @return [String] Combines all the exception messages into a single string. + # @note RSpec does not actually use this -- instead it formats each exception + # individually. + def message + all_exceptions.map(&:message).join("\n\n") + end + + # @return [String] A summary of the failure, including the block label and a count of failures. + def summary + "Got #{exception_count_description}" + end + + # return [String] A description of the failure/error counts. + def exception_count_description + failure_count = Formatters::Helpers.pluralize(failures.size, "failure") + return failure_count if other_errors.empty? + error_count = Formatters::Helpers.pluralize(other_errors.size, "other error") + "#{failure_count} and #{error_count}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb new file mode 100644 index 0000000..a071dfe --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb @@ -0,0 +1,23 @@ +RSpec::Support.require_rspec_core "formatters/base_formatter" + +module RSpec + module Core + module Formatters + # @private + class FailureListFormatter < BaseFormatter + Formatters.register self, :example_failed, :dump_profile, :message + + def example_failed(failure) + output.puts "#{failure.example.location}:#{failure.example.description}" + end + + # Discard profile and messages + # + # These outputs are not really relevant in the context of this failure + # list formatter. + def dump_profile(_profile); end + def message(_message); end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb new file mode 100644 index 0000000..db4423f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb @@ -0,0 +1,28 @@ +module RSpec + module Core + module Formatters + # @api private + # Formatter for providing message output as a fallback when no other + # profiler implements #message + class FallbackMessageFormatter + Formatters.register self, :message + + def initialize(output) + @output = output + end + + # @private + attr_reader :output + + # @api public + # + # Used by the reporter to send messages to the output stream. + # + # @param notification [MessageNotification] containing message + def message(notification) + output.puts notification.message + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb new file mode 100644 index 0000000..f62709d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb @@ -0,0 +1,118 @@ +RSpec::Support.require_rspec_core "shell_escape" + +module RSpec + module Core + module Formatters + # Formatters helpers. + module Helpers + # @private + SUB_SECOND_PRECISION = 5 + + # @private + DEFAULT_PRECISION = 2 + + # @api private + # + # Formats seconds into a human-readable string. + # + # @param duration [Float, Fixnum] in seconds + # @return [String] human-readable time + # + # @example + # format_duration(1) #=> "1 minute 1 second" + # format_duration(135.14) #=> "2 minutes 15.14 seconds" + def self.format_duration(duration) + precision = case + when duration < 1 then SUB_SECOND_PRECISION + when duration < 120 then DEFAULT_PRECISION + when duration < 300 then 1 + else 0 + end + + if duration > 60 + minutes = (duration.round / 60).to_i + seconds = (duration - minutes * 60) + + "#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds, precision), 'second')}" + else + pluralize(format_seconds(duration, precision), 'second') + end + end + + # @api private + # + # Formats seconds to have 5 digits of precision with trailing zeros + # removed if the number is less than 1 or with 2 digits of precision if + # the number is greater than zero. + # + # @param float [Float] + # @return [String] formatted float + # + # @example + # format_seconds(0.000006) #=> "0.00001" + # format_seconds(0.020000) #=> "0.02" + # format_seconds(1.00000000001) #=> "1" + # + # The precision used is set in {Helpers::SUB_SECOND_PRECISION} and + # {Helpers::DEFAULT_PRECISION}. + # + # @see #strip_trailing_zeroes + def self.format_seconds(float, precision=nil) + return '0' if float < 0 + precision ||= (float < 1) ? SUB_SECOND_PRECISION : DEFAULT_PRECISION + formatted = "%.#{precision}f" % float + strip_trailing_zeroes(formatted) + end + + # @api private + # + # Remove trailing zeros from a string. + # + # Only remove trailing zeros after a decimal place. + # see: http://rubular.com/r/ojtTydOgpn + # + # @param string [String] string with trailing zeros + # @return [String] string with trailing zeros removed + def self.strip_trailing_zeroes(string) + string.sub(/(?:(\..*[^0])0+|\.0+)$/, '\1') + end + private_class_method :strip_trailing_zeroes + + # @api private + # + # Pluralize a word based on a count. + # + # @param count [Fixnum] number of objects + # @param string [String] word to be pluralized + # @return [String] pluralized word + def self.pluralize(count, string) + pluralized_string = if count.to_f == 1 + string + elsif string.end_with?('s') # e.g. "process" + "#{string}es" # e.g. "processes" + else + "#{string}s" + end + + "#{count} #{pluralized_string}" + end + + # @api private + # Given a list of example ids, organizes them into a compact, ordered list. + def self.organize_ids(ids) + grouped = ids.inject(Hash.new { |h, k| h[k] = [] }) do |hash, id| + file, id = Example.parse_id(id) + hash[file] << id + hash + end + + grouped.sort_by(&:first).map do |file, grouped_ids| + grouped_ids = grouped_ids.sort_by { |id| id.split(':').map(&:to_i) } + id = Metadata.id_from(:rerun_file_path => file, :scoped_id => grouped_ids.join(',')) + ShellEscape.conditionally_quote(id) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb new file mode 100644 index 0000000..e7eff66 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb @@ -0,0 +1,153 @@ +RSpec::Support.require_rspec_core "formatters/base_text_formatter" +RSpec::Support.require_rspec_core "formatters/html_printer" + +module RSpec + module Core + module Formatters + # @private + class HtmlFormatter < BaseFormatter + Formatters.register self, :start, :example_group_started, :start_dump, + :example_started, :example_passed, :example_failed, + :example_pending, :dump_summary + + def initialize(output) + super(output) + @failed_examples = [] + @example_group_number = 0 + @example_number = 0 + @header_red = nil + @printer = HtmlPrinter.new(output) + end + + def start(notification) + super + @printer.print_html_start + @printer.flush + end + + def example_group_started(notification) + super + @example_group_red = false + @example_group_number += 1 + + @printer.print_example_group_end unless example_group_number == 1 + @printer.print_example_group_start(example_group_number, + notification.group.description, + notification.group.parent_groups.size) + @printer.flush + end + + def start_dump(_notification) + @printer.print_example_group_end + @printer.flush + end + + def example_started(_notification) + @example_number += 1 + end + + def example_passed(passed) + @printer.move_progress(percent_done) + @printer.print_example_passed(passed.example.description, passed.example.execution_result.run_time) + @printer.flush + end + + def example_failed(failure) + @failed_examples << failure.example + unless @header_red + @header_red = true + @printer.make_header_red + end + + unless @example_group_red + @example_group_red = true + @printer.make_example_group_header_red(example_group_number) + end + + @printer.move_progress(percent_done) + + example = failure.example + + exception = failure.exception + message_lines = failure.fully_formatted_lines(nil, RSpec::Core::Notifications::NullColorizer) + exception_details = if exception + { + # drop 2 removes the description (regardless of newlines) and leading blank line + :message => message_lines.drop(2).join("\n"), + :backtrace => failure.formatted_backtrace.join("\n"), + } + end + extra = extra_failure_content(failure) + + @printer.print_example_failed( + example.execution_result.pending_fixed, + example.description, + example.execution_result.run_time, + @failed_examples.size, + exception_details, + (extra == "") ? false : extra + ) + @printer.flush + end + + def example_pending(pending) + example = pending.example + + @printer.make_header_yellow unless @header_red + @printer.make_example_group_header_yellow(example_group_number) unless @example_group_red + @printer.move_progress(percent_done) + @printer.print_example_pending(example.description, example.execution_result.pending_message) + @printer.flush + end + + def dump_summary(summary) + @printer.print_summary( + summary.duration, + summary.example_count, + summary.failure_count, + summary.pending_count + ) + @printer.flush + end + + private + + # If these methods are declared with attr_reader Ruby will issue a + # warning because they are private. + # rubocop:disable Style/TrivialAccessors + + # The number of the currently running example_group. + def example_group_number + @example_group_number + end + + # The number of the currently running example (a global counter). + def example_number + @example_number + end + # rubocop:enable Style/TrivialAccessors + + def percent_done + result = 100.0 + if @example_count > 0 + result = (((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0).to_f + end + result + end + + # Override this method if you wish to output extra HTML for a failed + # spec. For example, you could output links to images or other files + # produced during the specs. + def extra_failure_content(failure) + RSpec::Support.require_rspec_core "formatters/html_snippet_extractor" + backtrace = (failure.exception.backtrace || []).map do |line| + RSpec.configuration.backtrace_formatter.backtrace_line(line) + end + backtrace.compact! + @snippet_extractor ||= HtmlSnippetExtractor.new + "
#{@snippet_extractor.snippet(backtrace)}
" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb new file mode 100644 index 0000000..79d27e1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb @@ -0,0 +1,412 @@ +require 'erb' + +module RSpec + module Core + module Formatters + # @private + class HtmlPrinter + include ERB::Util # For the #h method. + def initialize(output) + @output = output + end + + def print_html_start + @output.puts HTML_HEADER + @output.puts REPORT_HEADER + end + + def print_example_group_end + @output.puts " " + @output.puts "" + end + + def print_example_group_start(group_id, description, number_of_parents) + @output.puts "
" + @output.puts "
" + @output.puts "
#{h(description)}
" + end + + def print_example_passed(description, run_time) + formatted_run_time = "%.5f" % run_time + @output.puts "
" \ + "#{h(description)}" \ + "#{formatted_run_time}s
" + end + + def print_example_failed(pending_fixed, description, run_time, failure_id, + exception, extra_content) + formatted_run_time = "%.5f" % run_time + + @output.puts "
" + @output.puts " #{h(description)}" + @output.puts " #{formatted_run_time}s" + @output.puts "
" + if exception + @output.puts "
#{h(exception[:message])}
" + @output.puts "
#{h exception[:backtrace]}
" + end + @output.puts extra_content if extra_content + @output.puts "
" + @output.puts "
" + end + + def print_example_pending(description, pending_message) + @output.puts "
" \ + "#{h(description)} " \ + "(PENDING: #{h(pending_message)})
" + end + + def print_summary(duration, example_count, failure_count, pending_count) + totals = String.new( + "#{example_count} example#{'s' unless example_count == 1}, " + ) + totals << "#{failure_count} failure#{'s' unless failure_count == 1}" + totals << ", #{pending_count} pending" if pending_count > 0 + + formatted_duration = "%.5f" % duration + + @output.puts "" + @output.puts "" + @output.puts "
" + @output.puts "" + @output.puts "" + @output.puts "" + end + + def flush + @output.flush + end + + def move_progress(percent_done) + @output.puts " " + @output.flush + end + + def make_header_red + @output.puts " " + end + + def make_header_yellow + @output.puts " " + end + + def make_example_group_header_red(group_id) + @output.puts " " + @output.puts " " + end + + def make_example_group_header_yellow(group_id) + @output.puts " " + @output.puts " " + end + + private + + def indentation_style(number_of_parents) + "style=\"margin-left: #{(number_of_parents - 1) * 15}px;\"" + end + + REPORT_HEADER = <<-EOF +
+ +
+
+

RSpec Code Examples

+
+ +
+ + + +
+ +
+

 

+

 

+
+
+ + +
+EOF + + GLOBAL_SCRIPTS = <<-EOF + +function addClass(element_id, classname) { + document.getElementById(element_id).className += (" " + classname); +} + +function removeClass(element_id, classname) { + var elem = document.getElementById(element_id); + var classlist = elem.className.replace(classname,''); + elem.className = classlist; +} + +function moveProgressBar(percentDone) { + document.getElementById("rspec-header").style.width = percentDone +"%"; +} + +function makeRed(element_id) { + removeClass(element_id, 'passed'); + removeClass(element_id, 'not_implemented'); + addClass(element_id,'failed'); +} + +function makeYellow(element_id) { + var elem = document.getElementById(element_id); + if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed + if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented + removeClass(element_id, 'passed'); + addClass(element_id,'not_implemented'); + } + } +} + +function apply_filters() { + var passed_filter = document.getElementById('passed_checkbox').checked; + var failed_filter = document.getElementById('failed_checkbox').checked; + var pending_filter = document.getElementById('pending_checkbox').checked; + + assign_display_style("example passed", passed_filter); + assign_display_style("example failed", failed_filter); + assign_display_style("example not_implemented", pending_filter); + + assign_display_style_for_group("example_group passed", passed_filter); + assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter); + assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter); +} + +function get_display_style(display_flag) { + var style_mode = 'none'; + if (display_flag == true) { + style_mode = 'block'; + } + return style_mode; +} + +function assign_display_style(classname, display_flag) { + var style_mode = get_display_style(display_flag); + var elems = document.getElementsByClassName(classname) + for (var i=0; i + + + RSpec results + + + + + + + + +EOF + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb new file mode 100644 index 0000000..992704b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb @@ -0,0 +1,122 @@ +module RSpec + module Core + module Formatters + # @api private + # + # Extracts code snippets by looking at the backtrace of the passed error + # and applies synax highlighting and line numbers using html. + class HtmlSnippetExtractor + # @private + module NullConverter + def self.convert(code) + %Q(#{code}\n# Install the coderay gem to get syntax highlighting) + end + end + + # @private + module CoderayConverter + def self.convert(code) + CodeRay.scan(code, :ruby).html(:line_numbers => false) + end + end + + # rubocop:disable Style/ClassVars + # @private + @@converter = NullConverter + + begin + require 'coderay' + RSpec::Support.require_rspec_core 'formatters/syntax_highlighter' + RSpec::Core::Formatters::SyntaxHighlighter.attempt_to_add_rspec_terms_to_coderay_keywords + @@converter = CoderayConverter + # rubocop:disable Lint/HandleExceptions + rescue LoadError + # it'll fall back to the NullConverter assigned above + # rubocop:enable Lint/HandleExceptions + end + + # rubocop:enable Style/ClassVars + + # @api private + # + # Extract lines of code corresponding to a backtrace. + # + # @param backtrace [String] the backtrace from a test failure + # @return [String] highlighted code snippet indicating where the test + # failure occurred + # + # @see #post_process + def snippet(backtrace) + raw_code, line = snippet_for(backtrace[0]) + highlighted = @@converter.convert(raw_code) + post_process(highlighted, line) + end + # rubocop:enable Style/ClassVars + + # @api private + # + # Create a snippet from a line of code. + # + # @param error_line [String] file name with line number (i.e. + # 'foo_spec.rb:12') + # @return [String] lines around the target line within the file + # + # @see #lines_around + def snippet_for(error_line) + if error_line =~ /(.*):(\d+)/ + file = Regexp.last_match[1] + line = Regexp.last_match[2].to_i + [lines_around(file, line), line] + else + ["# Couldn't get snippet for #{error_line}", 1] + end + end + + # @api private + # + # Extract lines of code centered around a particular line within a + # source file. + # + # @param file [String] filename + # @param line [Fixnum] line number + # @return [String] lines around the target line within the file (2 above + # and 1 below). + def lines_around(file, line) + if File.file?(file) + lines = File.read(file).split("\n") + min = [0, line - 3].max + max = [line + 1, lines.length - 1].min + selected_lines = [] + selected_lines.join("\n") + lines[min..max].join("\n") + else + "# Couldn't get snippet for #{file}" + end + rescue SecurityError + # :nocov: - SecurityError is no longer produced starting in ruby 2.7 + "# Couldn't get snippet for #{file}" + # :nocov: + end + + # @api private + # + # Adds line numbers to all lines and highlights the line where the + # failure occurred using html `span` tags. + # + # @param highlighted [String] syntax-highlighted snippet surrounding the + # offending line of code + # @param offending_line [Fixnum] line where failure occurred + # @return [String] completed snippet + def post_process(highlighted, offending_line) + new_lines = [] + highlighted.split("\n").each_with_index do |line, i| + new_line = "#{offending_line + i - 2}#{line}" + new_line = "#{new_line}" if i == 2 + new_lines << new_line + end + new_lines.join("\n") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb new file mode 100644 index 0000000..7c6fde8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb @@ -0,0 +1,103 @@ +RSpec::Support.require_rspec_core "formatters/base_formatter" +require 'json' + +module RSpec + module Core + module Formatters + # @private + class JsonFormatter < BaseFormatter + Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :seed, :close + + attr_reader :output_hash + + def initialize(output) + super + @output_hash = { + :version => RSpec::Core::Version::STRING + } + end + + def message(notification) + (@output_hash[:messages] ||= []) << notification.message + end + + def dump_summary(summary) + @output_hash[:summary] = { + :duration => summary.duration, + :example_count => summary.example_count, + :failure_count => summary.failure_count, + :pending_count => summary.pending_count, + :errors_outside_of_examples_count => summary.errors_outside_of_examples_count + } + @output_hash[:summary_line] = summary.totals_line + end + + def stop(group_notification) + @output_hash[:examples] = group_notification.notifications.map do |notification| + format_example(notification.example).tap do |hash| + e = notification.example.exception + + if e + hash[:exception] = { + :class => e.class.name, + :message => e.message, + :backtrace => notification.formatted_backtrace, + } + end + end + end + end + + def seed(notification) + return unless notification.seed_used? + @output_hash[:seed] = notification.seed + end + + def close(_notification) + output.write @output_hash.to_json + end + + def dump_profile(profile) + @output_hash[:profile] = {} + dump_profile_slowest_examples(profile) + dump_profile_slowest_example_groups(profile) + end + + # @api private + def dump_profile_slowest_examples(profile) + @output_hash[:profile] = {} + @output_hash[:profile][:examples] = profile.slowest_examples.map do |example| + format_example(example).tap do |hash| + hash[:run_time] = example.execution_result.run_time + end + end + @output_hash[:profile][:slowest] = profile.slow_duration + @output_hash[:profile][:total] = profile.duration + end + + # @api private + def dump_profile_slowest_example_groups(profile) + @output_hash[:profile] ||= {} + @output_hash[:profile][:groups] = profile.slowest_groups.map do |loc, hash| + hash.update(:location => loc) + end + end + + private + + def format_example(example) + { + :id => example.id, + :description => example.description, + :full_description => example.full_description, + :status => example.execution_result.status.to_s, + :file_path => example.metadata[:file_path], + :line_number => example.metadata[:line_number], + :run_time => example.execution_result.run_time, + :pending_message => example.execution_result.pending_message, + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb new file mode 100644 index 0000000..4b95d93 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb @@ -0,0 +1,68 @@ +RSpec::Support.require_rspec_core "formatters/console_codes" + +module RSpec + module Core + module Formatters + # @api private + # Formatter for providing profile output. + class ProfileFormatter + Formatters.register self, :dump_profile + + def initialize(output) + @output = output + end + + # @private + attr_reader :output + + # @api public + # + # This method is invoked after the dumping the summary if profiling is + # enabled. + # + # @param profile [ProfileNotification] containing duration, + # slowest_examples and slowest_example_groups + def dump_profile(profile) + dump_profile_slowest_examples(profile) + dump_profile_slowest_example_groups(profile) + end + + private + + def dump_profile_slowest_examples(profile) + @output.puts "\nTop #{profile.slowest_examples.size} slowest " \ + "examples (#{Helpers.format_seconds(profile.slow_duration)} " \ + "seconds, #{profile.percentage}% of total time):\n" + + profile.slowest_examples.each do |example| + @output.puts " #{example.full_description}" + @output.puts " #{bold(Helpers.format_seconds(example.execution_result.run_time))} " \ + "#{bold("seconds")} #{format_caller(example.location)}" + end + end + + def dump_profile_slowest_example_groups(profile) + return if profile.slowest_groups.empty? + + @output.puts "\nTop #{profile.slowest_groups.size} slowest example groups:" + profile.slowest_groups.each do |loc, hash| + average = "#{bold(Helpers.format_seconds(hash[:average]))} #{bold("seconds")} average" + total = "#{Helpers.format_seconds(hash[:total_time])} seconds" + count = Helpers.pluralize(hash[:count], "example") + @output.puts " #{hash[:description]}" + @output.puts " #{average} (#{total} / #{count}) #{loc}" + end + end + + def format_caller(caller_info) + RSpec.configuration.backtrace_formatter.backtrace_line( + caller_info.to_s.split(':in `block').first) + end + + def bold(text) + ConsoleCodes.wrap(text, :bold) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb new file mode 100644 index 0000000..81e0beb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb @@ -0,0 +1,29 @@ +RSpec::Support.require_rspec_core "formatters/base_text_formatter" +RSpec::Support.require_rspec_core "formatters/console_codes" + +module RSpec + module Core + module Formatters + # @private + class ProgressFormatter < BaseTextFormatter + Formatters.register self, :example_passed, :example_pending, :example_failed, :start_dump + + def example_passed(_notification) + output.print ConsoleCodes.wrap('.', :success) + end + + def example_pending(_notification) + output.print ConsoleCodes.wrap('*', :pending) + end + + def example_failed(_notification) + output.print ConsoleCodes.wrap('F', :failure) + end + + def start_dump(_notification) + output.puts + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb new file mode 100644 index 0000000..12fc71f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb @@ -0,0 +1,182 @@ +module RSpec + module Core + module Formatters + # This class isn't loaded at runtime but serves to document all of the + # notifications implemented as part of the standard interface. The + # reporter will issue these during a normal test suite run, but a + # formatter will only receive those notifications it has registered + # itself to receive. To register a formatter call: + # + # `::RSpec::Core::Formatters.register class, :list, :of, :notifications` + # + # e.g. + # + # `::RSpec::Core::Formatters.register self, :start, :example_started` + # + # @see RSpec::Core::Formatters::BaseFormatter + # @see RSpec::Core::Formatters::BaseTextFormatter + # @see RSpec::Core::Reporter + class Protocol + # @method initialize(output) + # @api public + # + # @param output [IO] the formatter output + + # @method start(notification) + # @api public + # @group Suite Notifications + # + # This method is invoked before any examples are run, right after + # they have all been collected. This can be useful for special + # formatters that need to provide progress on feedback (graphical ones). + # + # This will only be invoked once, and the next one to be invoked + # is {#example_group_started}. + # + # @param notification [Notifications::StartNotification] + + # @method example_group_started(notification) + # @api public + # @group Group Notifications + # + # This method is invoked at the beginning of the execution of each + # example group. + # + # The next method to be invoked after this is {#example_passed}, + # {#example_pending}, or {#example_group_finished}. + # + # @param notification [Notifications::GroupNotification] containing example_group + # subclass of {ExampleGroup} + + # @method example_group_finished(notification) + # @api public + # @group Group Notifications + # + # Invoked at the end of the execution of each example group. + # + # @param notification [Notifications::GroupNotification] containing example_group + # subclass of {ExampleGroup} + + # @method example_started(notification) + # @api public + # @group Example Notifications + # + # Invoked at the beginning of the execution of each example. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_finished(notification) + # @api public + # @group Example Notifications + # + # Invoked at the end of the execution of each example. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_passed(notification) + # @api public + # @group Example Notifications + # + # Invoked when an example passes. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_pending(notification) + # @api public + # @group Example Notifications + # + # Invoked when an example is pending. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_failed(notification) + # @api public + # @group Example Notifications + # + # Invoked when an example fails. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method message(notification) + # @api public + # @group Suite Notifications + # + # Used by the reporter to send messages to the output stream. + # + # @param notification [Notifications::MessageNotification] containing message + + # @method stop(notification) + # @api public + # @group Suite Notifications + # + # Invoked after all examples have executed, before dumping post-run + # reports. + # + # @param notification [Notifications::NullNotification] + + # @method start_dump(notification) + # @api public + # @group Suite Notifications + # + # This method is invoked after all of the examples have executed. The + # next method to be invoked after this one is {#dump_failures} + # (BaseTextFormatter then calls {#dump_failures} once for each failed + # example). + # + # @param notification [Notifications::NullNotification] + + # @method dump_failures(notification) + # @api public + # @group Suite Notifications + # + # Dumps detailed information about each example failure. + # + # @param notification [Notifications::NullNotification] + + # @method dump_summary(summary) + # @api public + # @group Suite Notifications + # + # This method is invoked after the dumping of examples and failures. + # Each parameter is assigned to a corresponding attribute. + # + # @param summary [Notifications::SummaryNotification] containing duration, + # example_count, failure_count and pending_count + + # @method dump_profile(profile) + # @api public + # @group Suite Notifications + # + # This method is invoked after the dumping the summary if profiling is + # enabled. + # + # @param profile [Notifications::ProfileNotification] containing duration, + # slowest_examples and slowest_example_groups + + # @method dump_pending(notification) + # @api public + # @group Suite Notifications + # + # Outputs a report of pending examples. This gets invoked + # after the summary if option is set to do so. + # + # @param notification [Notifications::NullNotification] + + # @method close(notification) + # @api public + # @group Suite Notifications + # + # Invoked at the end of a suite run. Allows the formatter to do any + # tidying up, but be aware that formatter output streams may be used + # elsewhere so don't actually close them. + # + # @param notification [Notifications::NullNotification] + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb new file mode 100644 index 0000000..c585db4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb @@ -0,0 +1,134 @@ +module RSpec + module Core + module Formatters + # @private + class SnippetExtractor + NoSuchFileError = Class.new(StandardError) + NoSuchLineError = Class.new(StandardError) + + def self.extract_line_at(file_path, line_number) + source = source_from_file(file_path) + line = source.lines[line_number - 1] + raise NoSuchLineError unless line + line + end + + def self.source_from_file(path) + raise NoSuchFileError unless File.exist?(path) + RSpec.world.source_from_file(path) + end + + if RSpec::Support::RubyFeatures.ripper_supported? + NoExpressionAtLineError = Class.new(StandardError) + + attr_reader :source, :beginning_line_number, :max_line_count + + def self.extract_expression_lines_at(file_path, beginning_line_number, max_line_count=nil) + if max_line_count == 1 + [extract_line_at(file_path, beginning_line_number)] + else + source = source_from_file(file_path) + new(source, beginning_line_number, max_line_count).expression_lines + end + end + + def initialize(source, beginning_line_number, max_line_count=nil) + @source = source + @beginning_line_number = beginning_line_number + @max_line_count = max_line_count + end + + def expression_lines + line_range = line_range_of_expression + + if max_line_count && line_range.count > max_line_count + line_range = (line_range.begin)..(line_range.begin + max_line_count - 1) + end + + source.lines[(line_range.begin - 1)..(line_range.end - 1)] + rescue SyntaxError, NoExpressionAtLineError + [self.class.extract_line_at(source.path, beginning_line_number)] + end + + private + + def line_range_of_expression + @line_range_of_expression ||= begin + line_range = line_range_of_location_nodes_in_expression + initial_unclosed_tokens = unclosed_tokens_in_line_range(line_range) + unclosed_tokens = initial_unclosed_tokens + + until (initial_unclosed_tokens & unclosed_tokens).empty? + line_range = (line_range.begin)..(line_range.end + 1) + unclosed_tokens = unclosed_tokens_in_line_range(line_range) + end + + line_range + end + end + + def unclosed_tokens_in_line_range(line_range) + tokens = FlatMap.flat_map(line_range) do |line_number| + source.tokens_by_line_number[line_number] + end + + tokens.each_with_object([]) do |token, unclosed_tokens| + if token.opening? + unclosed_tokens << token + else + index = unclosed_tokens.rindex do |unclosed_token| + unclosed_token.closed_by?(token) + end + unclosed_tokens.delete_at(index) if index + end + end + end + + def line_range_of_location_nodes_in_expression + line_numbers = expression_node.each_with_object(Set.new) do |node, set| + set << node.location.line if node.location + end + + line_numbers.min..line_numbers.max + end + + def expression_node + raise NoExpressionAtLineError if location_nodes_at_beginning_line.empty? + + @expression_node ||= begin + common_ancestor_nodes = location_nodes_at_beginning_line.map do |node| + node.each_ancestor.to_a + end.reduce(:&) + + common_ancestor_nodes.find { |node| expression_outmost_node?(node) } + end + end + + def expression_outmost_node?(node) + return true unless node.parent + return false if node.type.to_s.start_with?('@') + ![node, node.parent].all? do |n| + # See `Ripper::PARSER_EVENTS` for the complete list of sexp types. + type = n.type.to_s + type.end_with?('call') || type.start_with?('method_add_') + end + end + + def location_nodes_at_beginning_line + source.nodes_by_line_number[beginning_line_number] + end + else + # :nocov: + def self.extract_expression_lines_at(file_path, beginning_line_number, *) + [extract_line_at(file_path, beginning_line_number)] + end + # :nocov: + end + + def self.least_indentation_from(lines) + lines.map { |line| line[/^[ \t]*/] }.min + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb new file mode 100644 index 0000000..e7766f6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb @@ -0,0 +1,91 @@ +module RSpec + module Core + module Formatters + # @private + # Provides terminal syntax highlighting of code snippets + # when coderay is available. + class SyntaxHighlighter + def initialize(configuration) + @configuration = configuration + end + + def highlight(lines) + implementation.highlight_syntax(lines) + end + + # rubocop:disable Lint/RescueException + # rubocop:disable Lint/HandleExceptions + def self.attempt_to_add_rspec_terms_to_coderay_keywords + CodeRay::Scanners::Ruby::Patterns::IDENT_KIND.add(%w[ + describe context + it specify + before after around + let subject + expect allow + ], :keyword) + rescue Exception + # Mutating CodeRay's contants like this is not a public API + # and might not always work. If we cannot add our keywords + # to CodeRay it is not a big deal and not worth raising an + # error over, so we ignore it. + end + # rubocop:enable Lint/HandleExceptions + # rubocop:enable Lint/RescueException + + private + + if RSpec::Support::OS.windows? + # :nocov: + def implementation + WindowsImplementation + end + # :nocov: + else + def implementation + return color_enabled_implementation if @configuration.color_enabled? + NoSyntaxHighlightingImplementation + end + end + + def color_enabled_implementation + @color_enabled_implementation ||= begin + require 'coderay' + self.class.attempt_to_add_rspec_terms_to_coderay_keywords + CodeRayImplementation + rescue LoadError + NoSyntaxHighlightingImplementation + end + end + + # @private + module CodeRayImplementation + RESET_CODE = "\e[0m" + + def self.highlight_syntax(lines) + highlighted = begin + CodeRay.encode(lines.join("\n"), :ruby, :terminal) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + return lines + end + + highlighted.split("\n").map do |line| + line.sub(/\S/) { |char| char.insert(0, RESET_CODE) } + end + end + end + + # @private + module NoSyntaxHighlightingImplementation + def self.highlight_syntax(lines) + lines + end + end + + # @private + # Not sure why, but our code above (and/or coderay itself) does not work + # on Windows, so we disable the feature on Windows. + WindowsImplementation = NoSyntaxHighlightingImplementation + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb new file mode 100644 index 0000000..2935a73 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb @@ -0,0 +1,646 @@ +module RSpec + module Core + # Provides `before`, `after` and `around` hooks as a means of + # supporting common setup and teardown. This module is extended + # onto {ExampleGroup}, making the methods available from any `describe` + # or `context` block and included in {Configuration}, making them + # available off of the configuration object to define global setup + # or teardown logic. + module Hooks + # @api public + # + # @overload before(&block) + # @overload before(scope, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` + # (defaults to `:example`) + # @overload before(scope, *conditions, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` + # (defaults to `:example`) + # @param conditions [Array, Hash] constrains this hook to + # examples matching these conditions e.g. + # `before(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. Symbols will be transformed + # into hash entries with `true` values. + # @overload before(conditions, &block) + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `before(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. + # + # @see #after + # @see #around + # @see ExampleGroup + # @see SharedContext + # @see SharedExampleGroup + # @see Configuration + # + # Declare a block of code to be run before each example (using `:example`) + # or once before any example (using `:context`). These are usually + # declared directly in the {ExampleGroup} to which they apply, but they + # can also be shared across multiple groups. + # + # You can also use `before(:suite)` to run a block of code before any + # example groups are run. This should be declared in {RSpec.configure}. + # + # Instance variables declared in `before(:example)` or `before(:context)` + # are accessible within each example. + # + # ### Order + # + # `before` hooks are stored in three scopes, which are run in order: + # `:suite`, `:context`, and `:example`. They can also be declared in + # several different places: `RSpec.configure`, a parent group, the current + # group. They are run in the following order: + # + # before(:suite) # Declared in RSpec.configure. + # before(:context) # Declared in RSpec.configure. + # before(:context) # Declared in a parent group. + # before(:context) # Declared in the current group. + # before(:example) # Declared in RSpec.configure. + # before(:example) # Declared in a parent group. + # before(:example) # Declared in the current group. + # + # If more than one `before` is declared within any one example group, they + # are run in the order in which they are declared. Any `around` hooks will + # execute after `before` context hooks but before any `before` example + # hook regardless of where they are declared. + # + # ### Conditions + # + # When you add a conditions hash to `before(:example)` or + # `before(:context)`, RSpec will only apply that hook to groups or + # examples that match the conditions. e.g. + # + # RSpec.configure do |config| + # config.before(:example, :authorized => true) do + # log_in_as :authorized_user + # end + # end + # + # RSpec.describe Something, :authorized => true do + # # The before hook will run in before each example in this group. + # end + # + # RSpec.describe SomethingElse do + # it "does something", :authorized => true do + # # The before hook will run before this example. + # end + # + # it "does something else" do + # # The hook will not run before this example. + # end + # end + # + # Note that filtered config `:context` hooks can still be applied + # to individual examples that have matching metadata. Just like + # Ruby's object model is that every object has a singleton class + # which has only a single instance, RSpec's model is that every + # example has a singleton example group containing just the one + # example. + # + # ### Warning: `before(:suite, :with => :conditions)` + # + # The conditions hash is used to match against specific examples. Since + # `before(:suite)` is not run in relation to any specific example or + # group, conditions passed along with `:suite` are effectively ignored. + # + # ### Exceptions + # + # When an exception is raised in a `before` block, RSpec skips any + # subsequent `before` blocks and the example, but runs all of the + # `after(:example)` and `after(:context)` hooks. + # + # ### Warning: implicit before blocks + # + # `before` hooks can also be declared in shared contexts which get + # included implicitly either by you or by extension libraries. Since + # RSpec runs these in the order in which they are declared within each + # scope, load order matters, and can lead to confusing results when one + # before block depends on state that is prepared in another before block + # that gets run later. + # + # ### Warning: `before(:context)` + # + # It is very tempting to use `before(:context)` to speed things up, but we + # recommend that you avoid this as there are a number of gotchas, as well + # as things that simply don't work. + # + # #### Context + # + # `before(:context)` is run in an example that is generated to provide + # group context for the block. + # + # #### Instance variables + # + # Instance variables declared in `before(:context)` are shared across all + # the examples in the group. This means that each example can change the + # state of a shared object, resulting in an ordering dependency that can + # make it difficult to reason about failures. + # + # #### Unsupported RSpec constructs + # + # RSpec has several constructs that reset state between each example + # automatically. These are not intended for use from within + # `before(:context)`: + # + # * `let` declarations + # * `subject` declarations + # * Any mocking, stubbing or test double declaration + # + # ### other frameworks + # + # Mock object frameworks and database transaction managers (like + # ActiveRecord) are typically designed around the idea of setting up + # before an example, running that one example, and then tearing down. This + # means that mocks and stubs can (sometimes) be declared in + # `before(:context)`, but get torn down before the first real example is + # ever run. + # + # You _can_ create database-backed model objects in a `before(:context)` + # in rspec-rails, but it will not be wrapped in a transaction for you, so + # you are on your own to clean up in an `after(:context)` block. + # + # @example before(:example) declared in an {ExampleGroup} + # + # RSpec.describe Thing do + # before(:example) do + # @thing = Thing.new + # end + # + # it "does something" do + # # Here you can access @thing. + # end + # end + # + # @example before(:context) declared in an {ExampleGroup} + # + # RSpec.describe Parser do + # before(:context) do + # File.open(file_to_parse, 'w') do |f| + # f.write <<-CONTENT + # stuff in the file + # CONTENT + # end + # end + # + # it "parses the file" do + # Parser.parse(file_to_parse) + # end + # + # after(:context) do + # File.delete(file_to_parse) + # end + # end + # + # @note The `:example` and `:context` scopes are also available as + # `:each` and `:all`, respectively. Use whichever you prefer. + # @note The `:suite` scope is only supported for hooks registered on + # `RSpec.configuration` since they exist independently of any + # example or example group. + def before(*args, &block) + hooks.register :append, :before, *args, &block + end + + alias_method :append_before, :before + + # Adds `block` to the front of the list of `before` blocks in the same + # scope (`:example`, `:context`, or `:suite`). + # + # See {#before} for scoping semantics. + def prepend_before(*args, &block) + hooks.register :prepend, :before, *args, &block + end + + # @api public + # @overload after(&block) + # @overload after(scope, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to + # `:example`) + # @overload after(scope, *conditions, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to + # `:example`) + # @param conditions [Array, Hash] constrains this hook to + # examples matching these conditions e.g. + # `after(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. Symbols will be transformed + # into hash entries with `true` values. + # @overload after(conditions, &block) + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `after(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. + # + # @see #before + # @see #around + # @see ExampleGroup + # @see SharedContext + # @see SharedExampleGroup + # @see Configuration + # + # Declare a block of code to be run after each example (using `:example`) + # or once after all examples n the context (using `:context`). See + # {#before} for more information about ordering. + # + # ### Exceptions + # + # `after` hooks are guaranteed to run even when there are exceptions in + # `before` hooks or examples. When an exception is raised in an after + # block, the exception is captured for later reporting, and subsequent + # `after` blocks are run. + # + # ### Order + # + # `after` hooks are stored in three scopes, which are run in order: + # `:example`, `:context`, and `:suite`. They can also be declared in + # several different places: `RSpec.configure`, a parent group, the current + # group. They are run in the following order: + # + # after(:example) # Declared in the current group. + # after(:example) # Declared in a parent group. + # after(:example) # Declared in RSpec.configure. + # after(:context) # Declared in the current group. + # after(:context) # Declared in a parent group. + # after(:context) # Declared in RSpec.configure. + # after(:suite) # Declared in RSpec.configure. + # + # This is the reverse of the order in which `before` hooks are run. + # Similarly, if more than one `after` is declared within any example + # group, they are run in reverse order of that in which they are declared. + # Also `around` hooks will run after any `after` example hooks are + # invoked but before any `after` context hooks. + # + # @note The `:example` and `:context` scopes are also available as + # `:each` and `:all`, respectively. Use whichever you prefer. + # @note The `:suite` scope is only supported for hooks registered on + # `RSpec.configuration` since they exist independently of any + # example or example group. + def after(*args, &block) + hooks.register :prepend, :after, *args, &block + end + + alias_method :prepend_after, :after + + # Adds `block` to the back of the list of `after` blocks in the same + # scope (`:example`, `:context`, or `:suite`). + # + # See {#after} for scoping semantics. + def append_after(*args, &block) + hooks.register :append, :after, *args, &block + end + + # @api public + # @overload around(&block) + # @overload around(scope, &block) + # @param scope [Symbol] `:example` (defaults to `:example`) + # present for syntax parity with `before` and `after`, but + # `:example`/`:each` is the only supported value. + # @overload around(scope, *conditions, &block) + # @param scope [Symbol] `:example` (defaults to `:example`) + # present for syntax parity with `before` and `after`, but + # `:example`/`:each` is the only supported value. + # @param conditions [Array, Hash] constrains this hook to + # examples matching these conditions e.g. + # `around(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. Symbols will be transformed + # into hash entries with `true` values. + # @overload around(conditions, &block) + # @param conditions [Hash] constrains this hook to examples matching + # these conditions e.g. `around(:example, :ui => true) { ... }` will + # only run with examples or groups declared with `:ui => true`. + # + # @yield [Example] the example to run + # + # @note the syntax of `around` is similar to that of `before` and `after` + # but the semantics are quite different. `before` and `after` hooks are + # run in the context of the examples with which they are associated, + # whereas `around` hooks are actually responsible for running the + # examples. Consequently, `around` hooks do not have direct access to + # resources that are made available within the examples and their + # associated `before` and `after` hooks. + # + # @note `:example`/`:each` is the only supported scope. + # + # Declare a block of code, parts of which will be run before and parts + # after the example. It is your responsibility to run the example: + # + # around(:example) do |ex| + # # Do some stuff before. + # ex.run + # # Do some stuff after. + # end + # + # The yielded example aliases `run` with `call`, which lets you treat it + # like a `Proc`. This is especially handy when working with libraries + # that manage their own setup and teardown using a block or proc syntax, + # e.g. + # + # around(:example) {|ex| Database.transaction(&ex)} + # around(:example) {|ex| FakeFS(&ex)} + # + # ### Order + # + # The `around` hooks execute surrounding an example and its hooks. + # + # This means after any `before` context hooks, but before any `before` + # example hooks, and similarly after any `after` example hooks but before + # any `after` context hooks. + # + # They are not a synonym for `before`/`after`. + def around(*args, &block) + hooks.register :prepend, :around, *args, &block + end + + # @private + # Holds the various registered hooks. + def hooks + @hooks ||= HookCollections.new(self, FilterableItemRepository::UpdateOptimized) + end + + # @private + Hook = Struct.new(:block, :options) + + # @private + class BeforeHook < Hook + def run(example) + example.instance_exec(example, &block) + end + end + + # @private + class AfterHook < Hook + def run(example) + example.instance_exec(example, &block) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex + example.set_exception(ex) + end + end + + # @private + class AfterContextHook < Hook + def run(example) + example.instance_exec(example, &block) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + RSpec.configuration.reporter.notify_non_example_exception(e, "An error occurred in an `after(:context)` hook.") + end + end + + # @private + class AroundHook < Hook + def execute_with(example, procsy) + example.instance_exec(procsy, &block) + return if procsy.executed? + Pending.mark_skipped!(example, + "#{hook_description} did not execute the example") + end + + if Proc.method_defined?(:source_location) + def hook_description + "around hook at #{Metadata.relative_path(block.source_location.join(':'))}" + end + else # for 1.8.7 + # :nocov: + def hook_description + "around hook" + end + # :nocov: + end + end + + # @private + # + # This provides the primary API used by other parts of rspec-core. By hiding all + # implementation details behind this facade, it's allowed us to heavily optimize + # this, so that, for example, hook collection objects are only instantiated when + # a hook is added. This allows us to avoid many object allocations for the common + # case of a group having no hooks. + # + # This is only possible because this interface provides a "tell, don't ask"-style + # API, so that callers _tell_ this class what to do with the hooks, rather than + # asking this class for a list of hooks, and then doing something with them. + class HookCollections + def initialize(owner, filterable_item_repo_class) + @owner = owner + @filterable_item_repo_class = filterable_item_repo_class + @before_example_hooks = nil + @after_example_hooks = nil + @before_context_hooks = nil + @after_context_hooks = nil + @around_example_hooks = nil + end + + def register_globals(host, globals) + parent_groups = host.parent_groups + + process(host, parent_groups, globals, :before, :example, &:options) + process(host, parent_groups, globals, :after, :example, &:options) + process(host, parent_groups, globals, :around, :example, &:options) + + process(host, parent_groups, globals, :before, :context, &:options) + process(host, parent_groups, globals, :after, :context, &:options) + end + + def register_global_singleton_context_hooks(example, globals) + parent_groups = example.example_group.parent_groups + + process(example, parent_groups, globals, :before, :context) { {} } + process(example, parent_groups, globals, :after, :context) { {} } + end + + def register(prepend_or_append, position, *args, &block) + scope, options = scope_and_options_from(*args) + + if scope == :suite + # TODO: consider making this an error in RSpec 4. For SemVer reasons, + # we are only warning in RSpec 3. + RSpec.warn_with "WARNING: `#{position}(:suite)` hooks are only supported on " \ + "the RSpec configuration object. This " \ + "`#{position}(:suite)` hook, registered on an example " \ + "group, will be ignored." + return + elsif scope == :context && position == :around + # TODO: consider making this an error in RSpec 4. For SemVer reasons, + # we are only warning in RSpec 3. + RSpec.warn_with "WARNING: `around(:context)` hooks are not supported and " \ + "behave like `around(:example)`." + end + + hook = HOOK_TYPES[position][scope].new(block, options) + ensure_hooks_initialized_for(position, scope).__send__(prepend_or_append, hook, options) + end + + # @private + # + # Runs all of the blocks stored with the hook in the context of the + # example. If no example is provided, just calls the hook directly. + def run(position, scope, example_or_group) + return if RSpec.configuration.dry_run? + + if scope == :context + unless example_or_group.class.metadata[:skip] + run_owned_hooks_for(position, :context, example_or_group) + end + else + case position + when :before then run_example_hooks_for(example_or_group, :before, :reverse_each) + when :after then run_example_hooks_for(example_or_group, :after, :each) + when :around then run_around_example_hooks_for(example_or_group) { yield } + end + end + end + + SCOPES = [:example, :context] + + SCOPE_ALIASES = { :each => :example, :all => :context } + + HOOK_TYPES = { + :before => Hash.new { BeforeHook }, + :after => Hash.new { AfterHook }, + :around => Hash.new { AroundHook } + } + + HOOK_TYPES[:after][:context] = AfterContextHook + + protected + + EMPTY_HOOK_ARRAY = [].freeze + + def matching_hooks_for(position, scope, example_or_group) + repository = hooks_for(position, scope) { return EMPTY_HOOK_ARRAY } + + # It would be nice to not have to switch on type here, but + # we don't want to define `ExampleGroup#metadata` because then + # `metadata` from within an individual example would return the + # group's metadata but the user would probably expect it to be + # the example's metadata. + metadata = case example_or_group + when ExampleGroup then example_or_group.class.metadata + else example_or_group.metadata + end + + repository.items_for(metadata) + end + + def all_hooks_for(position, scope) + hooks_for(position, scope) { return EMPTY_HOOK_ARRAY }.items_and_filters.map(&:first) + end + + def run_owned_hooks_for(position, scope, example_or_group) + matching_hooks_for(position, scope, example_or_group).each do |hook| + hook.run(example_or_group) + end + end + + def processable_hooks_for(position, scope, host) + if scope == :example + all_hooks_for(position, scope) + else + matching_hooks_for(position, scope, host) + end + end + + private + + def hooks_for(position, scope) + if position == :before + scope == :example ? @before_example_hooks : @before_context_hooks + elsif position == :after + scope == :example ? @after_example_hooks : @after_context_hooks + else # around + @around_example_hooks + end || yield + end + + def ensure_hooks_initialized_for(position, scope) + if position == :before + if scope == :example + @before_example_hooks ||= @filterable_item_repo_class.new(:all?) + else + @before_context_hooks ||= @filterable_item_repo_class.new(:all?) + end + elsif position == :after + if scope == :example + @after_example_hooks ||= @filterable_item_repo_class.new(:all?) + else + @after_context_hooks ||= @filterable_item_repo_class.new(:all?) + end + else # around + @around_example_hooks ||= @filterable_item_repo_class.new(:all?) + end + end + + def process(host, parent_groups, globals, position, scope) + hooks_to_process = globals.processable_hooks_for(position, scope, host) + return if hooks_to_process.empty? + + hooks_to_process -= FlatMap.flat_map(parent_groups) do |group| + group.hooks.all_hooks_for(position, scope) + end + return if hooks_to_process.empty? + + repository = ensure_hooks_initialized_for(position, scope) + hooks_to_process.each { |hook| repository.append hook, (yield hook) } + end + + def scope_and_options_from(*args) + return :suite if args.first == :suite + scope = extract_scope_from(args) + meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering) + return scope, meta + end + + def extract_scope_from(args) + if known_scope?(args.first) + normalized_scope_for(args.shift) + elsif args.any? { |a| a.is_a?(Symbol) } + error_message = "You must explicitly give a scope " \ + "(#{SCOPES.join(", ")}) or scope alias " \ + "(#{SCOPE_ALIASES.keys.join(", ")}) when using symbols as " \ + "metadata for a hook." + raise ArgumentError.new error_message + else + :example + end + end + + def known_scope?(scope) + SCOPES.include?(scope) || SCOPE_ALIASES.keys.include?(scope) + end + + def normalized_scope_for(scope) + SCOPE_ALIASES[scope] || scope + end + + def run_example_hooks_for(example, position, each_method) + owner_parent_groups.__send__(each_method) do |group| + group.hooks.run_owned_hooks_for(position, :example, example) + end + end + + def run_around_example_hooks_for(example) + hooks = FlatMap.flat_map(owner_parent_groups) do |group| + group.hooks.matching_hooks_for(:around, :example, example) + end + + return yield if hooks.empty? # exit early to avoid the extra allocation cost of `Example::Procsy` + + initial_procsy = Example::Procsy.new(example) { yield } + hooks.inject(initial_procsy) do |procsy, around_hook| + procsy.wrap { around_hook.execute_with(example, procsy) } + end.call + end + + if respond_to?(:singleton_class) && singleton_class.ancestors.include?(singleton_class) + def owner_parent_groups + @owner.parent_groups + end + else # Ruby < 2.1 (see https://bugs.ruby-lang.org/issues/8035) + # :nocov: + def owner_parent_groups + @owner_parent_groups ||= [@owner] + @owner.parent_groups + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb new file mode 100644 index 0000000..4719085 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb @@ -0,0 +1,87 @@ +module RSpec + module Core + # @private + module Invocations + # @private + class InitializeProject + def call(*_args) + RSpec::Support.require_rspec_core "project_initializer" + ProjectInitializer.new.run + 0 + end + end + + # @private + class DRbWithFallback + def call(options, err, out) + require 'rspec/core/drb' + begin + return DRbRunner.new(options).run(err, out) + rescue DRb::DRbConnError + err.puts "No DRb server is running. Running in local process instead ..." + end + RSpec::Core::Runner.new(options).run(err, out) + end + end + + # @private + class Bisect + def call(options, err, out) + RSpec::Support.require_rspec_core "bisect/coordinator" + runner = Runner.new(options).tap { |r| r.configure(err, out) } + formatter = bisect_formatter_klass_for(options.options[:bisect]).new( + out, runner.configuration.bisect_runner + ) + + success = RSpec::Core::Bisect::Coordinator.bisect_with( + runner, options.args, formatter + ) + + runner.exit_code(success) + end + + private + + def bisect_formatter_klass_for(argument) + return Formatters::BisectDebugFormatter if argument == "verbose" + Formatters::BisectProgressFormatter + end + end + + # @private + class PrintVersion + def call(_options, _err, out) + overall_version = RSpec::Core::Version::STRING + unless overall_version =~ /[a-zA-Z]+/ + overall_version = overall_version.split('.').first(2).join('.') + end + + out.puts "RSpec #{overall_version}" + + [:Core, :Expectations, :Mocks, :Rails, :Support].each do |const_name| + lib_name = const_name.to_s.downcase + begin + require "rspec/#{lib_name}/version" + rescue LoadError + # Not worth mentioning libs that are not installed + nil + else + out.puts " - rspec-#{lib_name} #{RSpec.const_get(const_name)::Version::STRING}" + end + end + + 0 + end + end + + # @private + PrintHelp = Struct.new(:parser, :hidden_options) do + def call(_options, _err, out) + # Removing the hidden options from the output. + out.puts parser.to_s.gsub(/^\s+(#{hidden_options.join('|')})\b.*$\n/, '') + 0 + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb new file mode 100644 index 0000000..adcfce7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb @@ -0,0 +1,580 @@ +RSpec::Support.require_rspec_support 'reentrant_mutex' + +module RSpec + module Core + # This module is included in {ExampleGroup}, making the methods + # available to be called from within example blocks. + # + # @see ClassMethods + module MemoizedHelpers + # @note `subject` was contributed by Joe Ferris to support the one-liner + # syntax embraced by shoulda matchers: + # + # RSpec.describe Widget do + # it { is_expected.to validate_presence_of(:name) } + # # or + # it { should validate_presence_of(:name) } + # end + # + # While the examples below demonstrate how to use `subject` + # explicitly in examples, we recommend that you define a method with + # an intention revealing name instead. + # + # @example + # + # # Explicit declaration of subject. + # RSpec.describe Person do + # subject { Person.new(:birthdate => 19.years.ago) } + # it "should be eligible to vote" do + # subject.should be_eligible_to_vote + # # ^ ^ explicit reference to subject not recommended + # end + # end + # + # # Implicit subject => { Person.new }. + # RSpec.describe Person do + # it "should be eligible to vote" do + # subject.should be_eligible_to_vote + # # ^ ^ explicit reference to subject not recommended + # end + # end + # + # # One-liner syntax - expectation is set on the subject. + # RSpec.describe Person do + # it { is_expected.to be_eligible_to_vote } + # # or + # it { should be_eligible_to_vote } + # end + # + # @note Because `subject` is designed to create state that is reset + # between each example, and `before(:context)` is designed to setup + # state that is shared across _all_ examples in an example group, + # `subject` is _not_ intended to be used in a `before(:context)` hook. + # + # @see #should + # @see #should_not + # @see #is_expected + def subject + __memoized.fetch_or_store(:subject) do + described = described_class || self.class.metadata.fetch(:description_args).first + Class === described ? described.new : described + end + end + + # When `should` is called with no explicit receiver, the call is + # delegated to the object returned by `subject`. Combined with an + # implicit subject this supports very concise expressions. + # + # @example + # + # RSpec.describe Person do + # it { should be_eligible_to_vote } + # end + # + # @see #subject + # @see #is_expected + # + # @note This only works if you are using rspec-expectations. + # @note If you are using RSpec's newer expect-based syntax you may + # want to use `is_expected.to` instead of `should`. + def should(matcher=nil, message=nil) + enforce_value_expectation(matcher, 'should') + RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message) + end + + # Just like `should`, `should_not` delegates to the subject (implicit or + # explicit) of the example group. + # + # @example + # + # RSpec.describe Person do + # it { should_not be_eligible_to_vote } + # end + # + # @see #subject + # @see #is_expected + # + # @note This only works if you are using rspec-expectations. + # @note If you are using RSpec's newer expect-based syntax you may + # want to use `is_expected.to_not` instead of `should_not`. + def should_not(matcher=nil, message=nil) + enforce_value_expectation(matcher, 'should_not') + RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message) + end + + # Wraps the `subject` in `expect` to make it the target of an expectation. + # Designed to read nicely for one-liners. + # + # @example + # + # describe [1, 2, 3] do + # it { is_expected.to be_an Array } + # it { is_expected.not_to include 4 } + # end + # + # @see #subject + # @see #should + # @see #should_not + # + # @note This only works if you are using rspec-expectations. + def is_expected + expect(subject) + end + + # @private + # should just be placed in private section, + # but Ruby issues warnings on private attributes. + # and expanding it to the equivalent method upsets Rubocop, + # b/c it should obviously be a reader + attr_reader :__memoized + private :__memoized + + private + + # @private + def initialize(*) + __init_memoized + super + end + + # @private + def __init_memoized + @__memoized = if RSpec.configuration.threadsafe? + ThreadsafeMemoized.new + else + NonThreadSafeMemoized.new + end + end + + # @private + def enforce_value_expectation(matcher, method_name) + return if matcher_supports_value_expectations?(matcher) + + RSpec.deprecate( + "#{method_name} #{RSpec::Support::ObjectFormatter.format(matcher)}", + :message => + "The implicit block expectation syntax is deprecated, you should pass " \ + "a block to `expect` to use the provided block expectation matcher " \ + "(#{RSpec::Support::ObjectFormatter.format(matcher)}), " \ + "or the matcher must implement `supports_value_expectations?`." + ) + end + + def matcher_supports_value_expectations?(matcher) + matcher.supports_value_expectations? + rescue + true + end + + # @private + class ThreadsafeMemoized + def initialize + @memoized = {} + @mutex = Support::ReentrantMutex.new + end + + def fetch_or_store(key) + @memoized.fetch(key) do # only first access pays for synchronization + @mutex.synchronize do + @memoized.fetch(key) { @memoized[key] = yield } + end + end + end + end + + # @private + class NonThreadSafeMemoized + def initialize + @memoized = {} + end + + def fetch_or_store(key) + @memoized.fetch(key) { @memoized[key] = yield } + end + end + + # Used internally to customize the behavior of the + # memoized hash when used in a `before(:context)` hook. + # + # @private + class ContextHookMemoized + def self.isolate_for_context_hook(example_group_instance) + exploding_memoized = self + + example_group_instance.instance_exec do + @__memoized = exploding_memoized + + begin + yield + ensure + # This is doing a reset instead of just isolating for context hook. + # Really, this should set the old @__memoized back into place. + # + # Caller is the before and after context hooks + # which are both called from self.run + # I didn't look at why it made tests fail, maybe an object was getting reused in RSpec tests, + # if so, then that probably already works, and its the tests that are wrong. + __init_memoized + end + end + end + + def self.fetch_or_store(key, &_block) + description = if key == :subject + "subject" + else + "let declaration `#{key}`" + end + + raise <<-EOS +#{description} accessed in #{article} #{hook_expression} hook at: + #{CallerFilter.first_non_rspec_line} + +`let` and `subject` declarations are not intended to be called +in #{article} #{hook_expression} hook, as they exist to define state that +is reset between each example, while #{hook_expression} exists to +#{hook_intention}. +EOS + end + + # @private + class Before < self + def self.hook_expression + "`before(:context)`" + end + + def self.article + "a" + end + + def self.hook_intention + "define state that is shared across examples in an example group" + end + end + + # @private + class After < self + def self.hook_expression + "`after(:context)`" + end + + def self.article + "an" + end + + def self.hook_intention + "cleanup state that is shared across examples in an example group" + end + end + end + + # This module is extended onto {ExampleGroup}, making the methods + # available to be called from within example group blocks. + # You can think of them as being analagous to class macros. + module ClassMethods + # Generates a method whose return value is memoized after the first + # call. Useful for reducing duplication between examples that assign + # values to the same local variable. + # + # @note `let` _can_ enhance readability when used sparingly (1,2, or + # maybe 3 declarations) in any given example group, but that can + # quickly degrade with overuse. YMMV. + # + # @note `let` can be configured to be threadsafe or not. + # If it is threadsafe, it will take longer to access the value. + # If it is not threadsafe, it may behave in surprising ways in examples + # that spawn separate threads. Specify this on `RSpec.configure` + # + # @note Because `let` is designed to create state that is reset between + # each example, and `before(:context)` is designed to setup state that + # is shared across _all_ examples in an example group, `let` is _not_ + # intended to be used in a `before(:context)` hook. + # + # @example + # + # RSpec.describe Thing do + # let(:thing) { Thing.new } + # + # it "does something" do + # # First invocation, executes block, memoizes and returns result. + # thing.do_something + # + # # Second invocation, returns the memoized value. + # thing.should be_something + # end + # end + def let(name, &block) + # We have to pass the block directly to `define_method` to + # allow it to use method constructs like `super` and `return`. + raise "#let or #subject called without a block" if block.nil? + + # A list of reserved words that can't be used as a name for a memoized helper + # Matches for both symbols and passed strings + if [:initialize, :to_s].include?(name.to_sym) + raise ArgumentError, "#let or #subject called with reserved name `#{name}`" + end + + our_module = MemoizedHelpers.module_for(self) + + # If we have a module clash in our helper module + # then we need to remove it to prevent a warning. + # + # Note we do not check ancestor modules (see: `instance_methods(false)`) + # as we can override them. + if our_module.instance_methods(false).include?(name) + our_module.__send__(:remove_method, name) + end + our_module.__send__(:define_method, name, &block) + + # If we have a module clash in the example module + # then we need to remove it to prevent a warning. + # + # Note we do not check ancestor modules (see: `instance_methods(false)`) + # as we can override them. + if instance_methods(false).include?(name) + remove_method(name) + end + + # Apply the memoization. The method has been defined in an ancestor + # module so we can use `super` here to get the value. + if block.arity == 1 + define_method(name) { __memoized.fetch_or_store(name) { super(RSpec.current_example, &nil) } } + else + define_method(name) { __memoized.fetch_or_store(name) { super(&nil) } } + end + end + + # Just like `let`, except the block is invoked by an implicit `before` + # hook. This serves a dual purpose of setting up state and providing a + # memoized reference to that state. + # + # @example + # + # class Thing + # def self.count + # @count ||= 0 + # end + # + # def self.count=(val) + # @count += val + # end + # + # def self.reset_count + # @count = 0 + # end + # + # def initialize + # self.class.count += 1 + # end + # end + # + # RSpec.describe Thing do + # after(:example) { Thing.reset_count } + # + # context "using let" do + # let(:thing) { Thing.new } + # + # it "is not invoked implicitly" do + # Thing.count.should eq(0) + # end + # + # it "can be invoked explicitly" do + # thing + # Thing.count.should eq(1) + # end + # end + # + # context "using let!" do + # let!(:thing) { Thing.new } + # + # it "is invoked implicitly" do + # Thing.count.should eq(1) + # end + # + # it "returns memoized version on first invocation" do + # thing + # Thing.count.should eq(1) + # end + # end + # end + def let!(name, &block) + let(name, &block) + before { __send__(name) } + end + + # Declares a `subject` for an example group which can then be wrapped + # with `expect` using `is_expected` to make it the target of an + # expectation in a concise, one-line example. + # + # Given a `name`, defines a method with that name which returns the + # `subject`. This lets you declare the subject once and access it + # implicitly in one-liners and explicitly using an intention revealing + # name. + # + # When given a `name`, calling `super` in the block is not supported. + # + # @note `subject` can be configured to be threadsafe or not. + # If it is threadsafe, it will take longer to access the value. + # If it is not threadsafe, it may behave in surprising ways in examples + # that spawn separate threads. Specify this on `RSpec.configure` + # + # @param name [String,Symbol] used to define an accessor with an + # intention revealing name + # @param block defines the value to be returned by `subject` in examples + # + # @example + # + # RSpec.describe CheckingAccount, "with $50" do + # subject { CheckingAccount.new(Money.new(50, :USD)) } + # it { is_expected.to have_a_balance_of(Money.new(50, :USD)) } + # it { is_expected.not_to be_overdrawn } + # end + # + # RSpec.describe CheckingAccount, "with a non-zero starting balance" do + # subject(:account) { CheckingAccount.new(Money.new(50, :USD)) } + # it { is_expected.not_to be_overdrawn } + # it "has a balance equal to the starting balance" do + # account.balance.should eq(Money.new(50, :USD)) + # end + # end + # + # @see MemoizedHelpers#should + # @see MemoizedHelpers#should_not + # @see MemoizedHelpers#is_expected + def subject(name=nil, &block) + if name + let(name, &block) + alias_method :subject, name + + self::NamedSubjectPreventSuper.__send__(:define_method, name) do + raise NotImplementedError, "`super` in named subjects is not supported" + end + else + let(:subject, &block) + end + end + + # Just like `subject`, except the block is invoked by an implicit + # `before` hook. This serves a dual purpose of setting up state and + # providing a memoized reference to that state. + # + # @example + # + # class Thing + # def self.count + # @count ||= 0 + # end + # + # def self.count=(val) + # @count += val + # end + # + # def self.reset_count + # @count = 0 + # end + # + # def initialize + # self.class.count += 1 + # end + # end + # + # RSpec.describe Thing do + # after(:example) { Thing.reset_count } + # + # context "using subject" do + # subject { Thing.new } + # + # it "is not invoked implicitly" do + # Thing.count.should eq(0) + # end + # + # it "can be invoked explicitly" do + # subject + # Thing.count.should eq(1) + # end + # end + # + # context "using subject!" do + # subject!(:thing) { Thing.new } + # + # it "is invoked implicitly" do + # Thing.count.should eq(1) + # end + # + # it "returns memoized version on first invocation" do + # subject + # Thing.count.should eq(1) + # end + # end + # end + def subject!(name=nil, &block) + subject(name, &block) + before { subject } + end + end + + # @private + # + # Gets the LetDefinitions module. The module is mixed into + # the example group and is used to hold all let definitions. + # This is done so that the block passed to `let` can be + # forwarded directly on to `define_method`, so that all method + # constructs (including `super` and `return`) can be used in + # a `let` block. + # + # The memoization is provided by a method definition on the + # example group that supers to the LetDefinitions definition + # in order to get the value to memoize. + def self.module_for(example_group) + get_constant_or_yield(example_group, :LetDefinitions) do + mod = Module.new do + include(Module.new { + example_group.const_set(:NamedSubjectPreventSuper, self) + }) + end + + example_group.const_set(:LetDefinitions, mod) + mod + end + end + + # @private + def self.define_helpers_on(example_group) + example_group.__send__(:include, module_for(example_group)) + end + + if Module.method(:const_defined?).arity == 1 # for 1.8 + # @private + # + # Gets the named constant or yields. + # On 1.8, const_defined? / const_get do not take into + # account the inheritance hierarchy. + # :nocov: + def self.get_constant_or_yield(example_group, name) + if example_group.const_defined?(name) + example_group.const_get(name) + else + yield + end + end + # :nocov: + else + # @private + # + # Gets the named constant or yields. + # On 1.9, const_defined? / const_get take into account the + # the inheritance by default, and accept an argument to + # disable this behavior. It's important that we don't + # consider inheritance here; each example group level that + # uses a `let` should get its own `LetDefinitions` module. + def self.get_constant_or_yield(example_group, name) + if example_group.const_defined?(name, (check_ancestors = false)) + example_group.const_get(name, check_ancestors) + else + yield + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb new file mode 100644 index 0000000..9034214 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb @@ -0,0 +1,498 @@ +module RSpec + module Core + # Each ExampleGroup class and Example instance owns an instance of + # Metadata, which is Hash extended to support lazy evaluation of values + # associated with keys that may or may not be used by any example or group. + # + # In addition to metadata that is used internally, this also stores + # user-supplied metadata, e.g. + # + # RSpec.describe Something, :type => :ui do + # it "does something", :slow => true do + # # ... + # end + # end + # + # `:type => :ui` is stored in the Metadata owned by the example group, and + # `:slow => true` is stored in the Metadata owned by the example. These can + # then be used to select which examples are run using the `--tag` option on + # the command line, or several methods on `Configuration` used to filter a + # run (e.g. `filter_run_including`, `filter_run_excluding`, etc). + # + # @see Example#metadata + # @see ExampleGroup.metadata + # @see FilterManager + # @see Configuration#filter_run_including + # @see Configuration#filter_run_excluding + module Metadata + # Matches strings either at the beginning of the input or prefixed with a + # whitespace, containing the current path, either postfixed with the + # separator, or at the end of the string. Match groups are the character + # before and the character after the string if any. + # + # http://rubular.com/r/fT0gmX6VJX + # http://rubular.com/r/duOrD4i3wb + # http://rubular.com/r/sbAMHFrOx1 + def self.relative_path_regex + @relative_path_regex ||= /(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/ + end + + # @api private + # + # @param line [String] current code line + # @return [String] relative path to line + def self.relative_path(line) + line = line.sub(relative_path_regex, "\\1.\\2".freeze) + line = line.sub(/\A([^:]+:\d+)$/, '\\1'.freeze) + return nil if line == '-e:1'.freeze + line + rescue SecurityError + # :nocov: - SecurityError is no longer produced starting in ruby 2.7 + nil + # :nocov: + end + + # @private + # Iteratively walks up from the given metadata through all + # example group ancestors, yielding each metadata hash along the way. + def self.ascending(metadata) + yield metadata + return unless (group_metadata = metadata.fetch(:example_group) { metadata[:parent_example_group] }) + + loop do + yield group_metadata + break unless (group_metadata = group_metadata[:parent_example_group]) + end + end + + # @private + # Returns an enumerator that iteratively walks up the given metadata through all + # example group ancestors, yielding each metadata hash along the way. + def self.ascend(metadata) + enum_for(:ascending, metadata) + end + + # @private + # Used internally to build a hash from an args array. + # Symbols are converted into hash keys with a value of `true`. + # This is done to support simple tagging using a symbol, rather + # than needing to do `:symbol => true`. + def self.build_hash_from(args, warn_about_example_group_filtering=false) + hash = args.last.is_a?(Hash) ? args.pop : {} + + hash[args.pop] = true while args.last.is_a?(Symbol) + + if warn_about_example_group_filtering && hash.key?(:example_group) + RSpec.deprecate("Filtering by an `:example_group` subhash", + :replacement => "the subhash to filter directly") + end + + hash + end + + # @private + def self.deep_hash_dup(object) + return object.dup if Array === object + return object unless Hash === object + + object.inject(object.dup) do |duplicate, (key, value)| + duplicate[key] = deep_hash_dup(value) + duplicate + end + end + + # @private + def self.id_from(metadata) + "#{metadata[:rerun_file_path]}[#{metadata[:scoped_id]}]" + end + + # @private + def self.location_tuple_from(metadata) + [metadata[:absolute_file_path], metadata[:line_number]] + end + + # @private + # Used internally to populate metadata hashes with computed keys + # managed by RSpec. + class HashPopulator + attr_reader :metadata, :user_metadata, :description_args, :block + + def initialize(metadata, user_metadata, index_provider, description_args, block) + @metadata = metadata + @user_metadata = user_metadata + @index_provider = index_provider + @description_args = description_args + @block = block + end + + def populate + ensure_valid_user_keys + + metadata[:block] = block + metadata[:description_args] = description_args + metadata[:description] = build_description_from(*metadata[:description_args]) + metadata[:full_description] = full_description + metadata[:described_class] = described_class + + populate_location_attributes + metadata.update(user_metadata) + end + + private + + def populate_location_attributes + backtrace = user_metadata.delete(:caller) + + file_path, line_number = if backtrace + file_path_and_line_number_from(backtrace) + elsif block.respond_to?(:source_location) + block.source_location + else + file_path_and_line_number_from(caller) + end + + relative_file_path = Metadata.relative_path(file_path) + absolute_file_path = File.expand_path(relative_file_path) + metadata[:file_path] = relative_file_path + metadata[:line_number] = line_number.to_i + metadata[:location] = "#{relative_file_path}:#{line_number}" + metadata[:absolute_file_path] = absolute_file_path + metadata[:rerun_file_path] ||= relative_file_path + metadata[:scoped_id] = build_scoped_id_for(absolute_file_path) + end + + def file_path_and_line_number_from(backtrace) + first_caller_from_outside_rspec = backtrace.find { |l| l !~ CallerFilter::LIB_REGEX } + first_caller_from_outside_rspec ||= backtrace.first + /(.+?):(\d+)(?:|:\d+)/.match(first_caller_from_outside_rspec).captures + end + + def description_separator(parent_part, child_part) + if parent_part.is_a?(Module) && /^(?:#|::|\.)/.match(child_part.to_s) + ''.freeze + else + ' '.freeze + end + end + + def build_description_from(parent_description=nil, my_description=nil) + return parent_description.to_s unless my_description + return my_description.to_s if parent_description.to_s == '' + separator = description_separator(parent_description, my_description) + (parent_description.to_s + separator) << my_description.to_s + end + + def build_scoped_id_for(file_path) + index = @index_provider.call(file_path).to_s + parent_scoped_id = metadata.fetch(:scoped_id) { return index } + "#{parent_scoped_id}:#{index}" + end + + def ensure_valid_user_keys + RESERVED_KEYS.each do |key| + next unless user_metadata.key?(key) + raise <<-EOM.gsub(/^\s+\|/, '') + |#{"*" * 50} + |:#{key} is not allowed + | + |RSpec reserves some hash keys for its own internal use, + |including :#{key}, which is used on: + | + | #{CallerFilter.first_non_rspec_line}. + | + |Here are all of RSpec's reserved hash keys: + | + | #{RESERVED_KEYS.join("\n ")} + |#{"*" * 50} + EOM + end + end + end + + # @private + class ExampleHash < HashPopulator + def self.create(group_metadata, user_metadata, index_provider, description, block) + example_metadata = group_metadata.dup + group_metadata = Hash.new(&ExampleGroupHash.backwards_compatibility_default_proc do |hash| + hash[:parent_example_group] + end) + group_metadata.update(example_metadata) + + example_metadata[:execution_result] = Example::ExecutionResult.new + example_metadata[:example_group] = group_metadata + example_metadata[:shared_group_inclusion_backtrace] = SharedExampleGroupInclusionStackFrame.current_backtrace + example_metadata.delete(:parent_example_group) + + description_args = description.nil? ? [] : [description] + hash = new(example_metadata, user_metadata, index_provider, description_args, block) + hash.populate + hash.metadata + end + + private + + def described_class + metadata[:example_group][:described_class] + end + + def full_description + build_description_from( + metadata[:example_group][:full_description], + metadata[:description] + ) + end + end + + # @private + class ExampleGroupHash < HashPopulator + def self.create(parent_group_metadata, user_metadata, example_group_index, *args, &block) + group_metadata = hash_with_backwards_compatibility_default_proc + + if parent_group_metadata + group_metadata.update(parent_group_metadata) + group_metadata[:parent_example_group] = parent_group_metadata + end + + hash = new(group_metadata, user_metadata, example_group_index, args, block) + hash.populate + hash.metadata + end + + def self.hash_with_backwards_compatibility_default_proc + Hash.new(&backwards_compatibility_default_proc { |hash| hash }) + end + + def self.backwards_compatibility_default_proc(&example_group_selector) + Proc.new do |hash, key| + case key + when :example_group + # We commonly get here when rspec-core is applying a previously + # configured filter rule, such as when a gem configures: + # + # RSpec.configure do |c| + # c.include MyGemHelpers, :example_group => { :file_path => /spec\/my_gem_specs/ } + # end + # + # It's confusing for a user to get a deprecation at this point in + # the code, so instead we issue a deprecation from the config APIs + # that take a metadata hash, and MetadataFilter sets this thread + # local to silence the warning here since it would be so + # confusing. + unless RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] + RSpec.deprecate("The `:example_group` key in an example group's metadata hash", + :replacement => "the example group's hash directly for the " \ + "computed keys and `:parent_example_group` to access the parent " \ + "example group metadata") + end + + group_hash = example_group_selector.call(hash) + LegacyExampleGroupHash.new(group_hash) if group_hash + when :example_group_block + RSpec.deprecate("`metadata[:example_group_block]`", + :replacement => "`metadata[:block]`") + hash[:block] + when :describes + RSpec.deprecate("`metadata[:describes]`", + :replacement => "`metadata[:described_class]`") + hash[:described_class] + end + end + end + + private + + def described_class + candidate = metadata[:description_args].first + return candidate unless NilClass === candidate || String === candidate + parent_group = metadata[:parent_example_group] + parent_group && parent_group[:described_class] + end + + def full_description + description = metadata[:description] + parent_example_group = metadata[:parent_example_group] + return description unless parent_example_group + + parent_description = parent_example_group[:full_description] + separator = description_separator(parent_example_group[:description_args].last, + metadata[:description_args].first) + + parent_description + separator + description + end + end + + # @private + RESERVED_KEYS = [ + :description, + :description_args, + :described_class, + :example_group, + :parent_example_group, + :execution_result, + :last_run_status, + :file_path, + :absolute_file_path, + :rerun_file_path, + :full_description, + :line_number, + :location, + :scoped_id, + :block, + :shared_group_inclusion_backtrace + ] + end + + # Mixin that makes the including class imitate a hash for backwards + # compatibility. The including class should use `attr_accessor` to + # declare attributes. + # @private + module HashImitatable + def self.included(klass) + klass.extend ClassMethods + end + + def to_h + hash = extra_hash_attributes.dup + + self.class.hash_attribute_names.each do |name| + hash[name] = __send__(name) + end + + hash + end + + (Hash.public_instance_methods - Object.public_instance_methods).each do |method_name| + next if [:[], :[]=, :to_h].include?(method_name.to_sym) + + define_method(method_name) do |*args, &block| + issue_deprecation(method_name, *args) + + hash = hash_for_delegation + self.class.hash_attribute_names.each do |name| + hash.delete(name) unless instance_variable_defined?(:"@#{name}") + end + + hash.__send__(method_name, *args, &block).tap do + # apply mutations back to the object + hash.each do |name, value| + if directly_supports_attribute?(name) + set_value(name, value) + else + extra_hash_attributes[name] = value + end + end + end + end + end + + def [](key) + issue_deprecation(:[], key) + + if directly_supports_attribute?(key) + get_value(key) + else + extra_hash_attributes[key] + end + end + + def []=(key, value) + issue_deprecation(:[]=, key, value) + + if directly_supports_attribute?(key) + set_value(key, value) + else + extra_hash_attributes[key] = value + end + end + + private + + def extra_hash_attributes + @extra_hash_attributes ||= {} + end + + def directly_supports_attribute?(name) + self.class.hash_attribute_names.include?(name) + end + + def get_value(name) + __send__(name) + end + + def set_value(name, value) + __send__(:"#{name}=", value) + end + + def hash_for_delegation + to_h + end + + def issue_deprecation(_method_name, *_args) + # no-op by default: subclasses can override + end + + # @private + module ClassMethods + def hash_attribute_names + @hash_attribute_names ||= [] + end + + def attr_accessor(*names) + hash_attribute_names.concat(names) + super + end + end + end + + # @private + # Together with the example group metadata hash default block, + # provides backwards compatibility for the old `:example_group` + # key. In RSpec 2.x, the computed keys of a group's metadata + # were exposed from a nested subhash keyed by `[:example_group]`, and + # then the parent group's metadata was exposed by sub-subhash + # keyed by `[:example_group][:example_group]`. + # + # In RSpec 3, we reorganized this to that the computed keys are + # exposed directly of the group metadata hash (no nesting), and + # `:parent_example_group` returns the parent group's metadata. + # + # Maintaining backwards compatibility was difficult: we wanted + # `:example_group` to return an object that: + # + # * Exposes the top-level metadata keys that used to be nested + # under `:example_group`. + # * Supports mutation (rspec-rails, for example, assigns + # `metadata[:example_group][:described_class]` when you use + # anonymous controller specs) such that changes are written + # back to the top-level metadata hash. + # * Exposes the parent group metadata as + # `[:example_group][:example_group]`. + class LegacyExampleGroupHash + include HashImitatable + + def initialize(metadata) + @metadata = metadata + parent_group_metadata = metadata.fetch(:parent_example_group) { {} }[:example_group] + self[:example_group] = parent_group_metadata if parent_group_metadata + end + + def to_h + super.merge(@metadata) + end + + private + + def directly_supports_attribute?(name) + name != :example_group + end + + def get_value(name) + @metadata[name] + end + + def set_value(name, value) + @metadata[name] = value + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb new file mode 100644 index 0000000..2e63baf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb @@ -0,0 +1,255 @@ +module RSpec + module Core + # Contains metadata filtering logic. This has been extracted from + # the metadata classes because it operates ON a metadata hash but + # does not manage any of the state in the hash. We're moving towards + # having metadata be a raw hash (not a custom subclass), so externalizing + # this filtering logic helps us move in that direction. + module MetadataFilter + class << self + # @private + def apply?(predicate, filters, metadata) + filters.__send__(predicate) { |k, v| filter_applies?(k, v, metadata) } + end + + # @private + def filter_applies?(key, filter_value, metadata) + silence_metadata_example_group_deprecations do + return location_filter_applies?(filter_value, metadata) if key == :locations + return id_filter_applies?(filter_value, metadata) if key == :ids + return filters_apply?(key, filter_value, metadata) if Hash === filter_value + + meta_value = metadata.fetch(key) { return false } + + return true if TrueClass === filter_value && meta_value + return proc_filter_applies?(key, filter_value, metadata) if Proc === filter_value + return filter_applies_to_any_value?(key, filter_value, metadata) if Array === meta_value + + filter_value === meta_value || filter_value.to_s == meta_value.to_s + end + end + + # @private + def silence_metadata_example_group_deprecations + RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] = true + yield + ensure + RSpec::Support.thread_local_data.delete(:silence_metadata_example_group_deprecations) + end + + private + + def filter_applies_to_any_value?(key, value, metadata) + metadata[key].any? { |v| filter_applies?(key, v, key => value) } + end + + def id_filter_applies?(rerun_paths_to_scoped_ids, metadata) + scoped_ids = rerun_paths_to_scoped_ids.fetch(metadata[:rerun_file_path]) { return false } + + Metadata.ascend(metadata).any? do |meta| + scoped_ids.include?(meta[:scoped_id]) + end + end + + def location_filter_applies?(locations, metadata) + Metadata.ascend(metadata).any? do |meta| + file_path = meta[:absolute_file_path] + line_num = meta[:line_number] + + locations[file_path].any? do |filter_line_num| + line_num == RSpec.world.preceding_declaration_line(file_path, filter_line_num) + end + end + end + + def proc_filter_applies?(key, proc, metadata) + case proc.arity + when 0 then proc.call + when 2 then proc.call(metadata[key], metadata) + else proc.call(metadata[key]) + end + end + + def filters_apply?(key, value, metadata) + subhash = metadata[key] + return false unless Hash === subhash || HashImitatable === subhash + value.all? { |k, v| filter_applies?(k, v, subhash) } + end + end + end + + # Tracks a collection of filterable items (e.g. modules, hooks, etc) + # and provides an optimized API to get the applicable items for the + # metadata of an example or example group. + # + # There are two implementations, optimized for different uses. + # @private + module FilterableItemRepository + # This implementation is simple, and is optimized for frequent + # updates but rare queries. `append` and `prepend` do no extra + # processing, and no internal memoization is done, since this + # is not optimized for queries. + # + # This is ideal for use by a example or example group, which may + # be updated multiple times with globally configured hooks, etc, + # but will not be queried frequently by other examples or example + # groups. + # @private + class UpdateOptimized + attr_reader :items_and_filters + + def initialize(applies_predicate) + @applies_predicate = applies_predicate + @items_and_filters = [] + end + + def append(item, metadata) + @items_and_filters << [item, metadata] + end + + def prepend(item, metadata) + @items_and_filters.unshift [item, metadata] + end + + def delete(item, metadata) + @items_and_filters.delete [item, metadata] + end + + def items_for(request_meta) + @items_and_filters.each_with_object([]) do |(item, item_meta), to_return| + to_return << item if item_meta.empty? || + MetadataFilter.apply?(@applies_predicate, item_meta, request_meta) + end + end + + unless [].respond_to?(:each_with_object) # For 1.8.7 + # :nocov: + undef items_for + def items_for(request_meta) + @items_and_filters.inject([]) do |to_return, (item, item_meta)| + to_return << item if item_meta.empty? || + MetadataFilter.apply?(@applies_predicate, item_meta, request_meta) + to_return + end + end + # :nocov: + end + end + + # This implementation is much more complex, and is optimized for + # rare (or hopefully no) updates once the queries start. Updates + # incur a cost as it has to clear the memoization and keep track + # of applicable keys. Queries will be O(N) the first time an item + # is provided with a given set of applicable metadata; subsequent + # queries with items with the same set of applicable metadata will + # be O(1) due to internal memoization. + # + # This is ideal for use by config, where filterable items (e.g. hooks) + # are typically added at the start of the process (e.g. in `spec_helper`) + # and then repeatedly queried as example groups and examples are defined. + # @private + class QueryOptimized < UpdateOptimized + alias find_items_for items_for + private :find_items_for + + def initialize(applies_predicate) + super + @applicable_keys = Set.new + @proc_keys = Set.new + @memoized_lookups = Hash.new do |hash, applicable_metadata| + hash[applicable_metadata] = find_items_for(applicable_metadata) + end + end + + def append(item, metadata) + super + handle_mutation(metadata) + end + + def prepend(item, metadata) + super + handle_mutation(metadata) + end + + def delete(item, metadata) + super + reconstruct_caches + end + + def items_for(metadata) + # The filtering of `metadata` to `applicable_metadata` is the key thing + # that makes the memoization actually useful in practice, since each + # example and example group have different metadata (e.g. location and + # description). By filtering to the metadata keys our items care about, + # we can ignore extra metadata keys that differ for each example/group. + # For example, given `config.include DBHelpers, :db`, example groups + # can be split into these two sets: those that are tagged with `:db` and those + # that are not. For each set, this method for the first group in the set is + # still an `O(N)` calculation, but all subsequent groups in the set will be + # constant time lookups when they call this method. + applicable_metadata = applicable_metadata_from(metadata) + + if applicable_metadata.any? { |k, _| @proc_keys.include?(k) } + # It's unsafe to memoize lookups involving procs (since they can + # be non-deterministic), so we skip the memoization in this case. + find_items_for(applicable_metadata) + else + @memoized_lookups[applicable_metadata] + end + end + + private + + def reconstruct_caches + @applicable_keys.clear + @proc_keys.clear + @items_and_filters.each do |_item, metadata| + handle_mutation(metadata) + end + end + + def handle_mutation(metadata) + @applicable_keys.merge(metadata.keys) + @proc_keys.merge(proc_keys_from metadata) + @memoized_lookups.clear + end + + def applicable_metadata_from(metadata) + MetadataFilter.silence_metadata_example_group_deprecations do + @applicable_keys.inject({}) do |hash, key| + # :example_group is treated special here because... + # - In RSpec 2, example groups had an `:example_group` key + # - In RSpec 3, that key is deprecated (it was confusing!). + # - The key is not technically present in an example group metadata hash + # (and thus would fail the `metadata.key?(key)` check) but a value + # is provided when accessed via the hash's `default_proc` + # - Thus, for backwards compatibility, we have to explicitly check + # for `:example_group` here if it is one of the keys being used to + # filter. + hash[key] = metadata[key] if metadata.key?(key) || key == :example_group + hash + end + end + end + + def proc_keys_from(metadata) + metadata.each_with_object([]) do |(key, value), to_return| + to_return << key if Proc === value + end + end + + unless [].respond_to?(:each_with_object) # For 1.8.7 + # :nocov: + undef proc_keys_from + def proc_keys_from(metadata) + metadata.inject([]) do |to_return, (key, value)| + to_return << key if Proc === value + to_return + end + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb new file mode 100644 index 0000000..25db751 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb @@ -0,0 +1,31 @@ +begin + # Only the minitest 5.x gem includes the minitest.rb and assertions.rb files. + require 'minitest' + require 'minitest/assertions' +rescue LoadError + # We must be using Ruby Core's MiniTest or the Minitest gem 4.x. + require 'minitest/unit' + Minitest = MiniTest +end + +module RSpec + module Core + # @private + module MinitestAssertionsAdapter + include ::Minitest::Assertions + # Need to forcefully include Pending after Minitest::Assertions + # to make sure our own #skip method beats Minitest's. + include ::RSpec::Core::Pending + + # Minitest 5.x requires this accessor to be available. See + # https://github.com/seattlerb/minitest/blob/38f0a5fcbd9c37c3f80a3eaad4ba84d3fc9947a0/lib/minitest/assertions.rb#L8 + # + # It is not required for other extension libraries, and RSpec does not + # report or make this information available to formatters. + attr_writer :assertions + def assertions + @assertions ||= 0 + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb new file mode 100644 index 0000000..91475ae --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb @@ -0,0 +1,31 @@ +# Created by Jim Weirich on 2007-04-10. +# Copyright (c) 2007. All rights reserved. + +require 'flexmock/rspec' + +module RSpec + module Core + module MockingAdapters + # @private + module Flexmock + include ::FlexMock::MockContainer + + def self.framework_name + :flexmock + end + + def setup_mocks_for_rspec + # No setup required. + end + + def verify_mocks_for_rspec + flexmock_verify + end + + def teardown_mocks_for_rspec + flexmock_close + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb new file mode 100644 index 0000000..8caf7b6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb @@ -0,0 +1,57 @@ +# In order to support all versions of mocha, we have to jump through some +# hoops here. +# +# mocha >= '0.13.0': +# require 'mocha/api' is required. +# require 'mocha/object' raises a LoadError b/c the file no longer exists. +# mocha < '0.13.0', >= '0.9.7' +# require 'mocha/api' is required. +# require 'mocha/object' is required. +# mocha < '0.9.7': +# require 'mocha/api' raises a LoadError b/c the file does not yet exist. +# require 'mocha/standalone' is required. +# require 'mocha/object' is required. +begin + require 'mocha/api' + + begin + require 'mocha/object' + rescue LoadError + # Mocha >= 0.13.0 no longer contains this file nor needs it to be loaded. + end +rescue LoadError + require 'mocha/standalone' + require 'mocha/object' +end + +module RSpec + module Core + module MockingAdapters + # @private + module Mocha + def self.framework_name + :mocha + end + + # Mocha::Standalone was deprecated as of Mocha 0.9.7. + begin + include ::Mocha::API + rescue NameError + include ::Mocha::Standalone + end + + def setup_mocks_for_rspec + mocha_setup + end + + def verify_mocks_for_rspec + mocha_verify + end + + def teardown_mocks_for_rspec + mocha_teardown + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb new file mode 100644 index 0000000..442de9a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb @@ -0,0 +1,14 @@ +module RSpec + module Core + module MockingAdapters + # @private + module Null + def setup_mocks_for_rspec; end + + def verify_mocks_for_rspec; end + + def teardown_mocks_for_rspec; end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb new file mode 100644 index 0000000..d72651a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb @@ -0,0 +1,31 @@ +require 'rr' + +RSpec.configuration.backtrace_exclusion_patterns.push(RR::Errors::BACKTRACE_IDENTIFIER) + +module RSpec + module Core + # @private + module MockingAdapters + # @private + module RR + def self.framework_name + :rr + end + + include ::RR::Extensions::InstanceMethods + + def setup_mocks_for_rspec + ::RR::Space.instance.reset + end + + def verify_mocks_for_rspec + ::RR::Space.instance.verify_doubles + end + + def teardown_mocks_for_rspec + ::RR::Space.instance.reset + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb new file mode 100644 index 0000000..bb3f0ae --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb @@ -0,0 +1,32 @@ +require 'rspec/mocks' + +module RSpec + module Core + module MockingAdapters + # @private + module RSpec + include ::RSpec::Mocks::ExampleMethods + + def self.framework_name + :rspec + end + + def self.configuration + ::RSpec::Mocks.configuration + end + + def setup_mocks_for_rspec + ::RSpec::Mocks.setup + end + + def verify_mocks_for_rspec + ::RSpec::Mocks.verify + end + + def teardown_mocks_for_rspec + ::RSpec::Mocks.teardown + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb new file mode 100644 index 0000000..72768ef --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb @@ -0,0 +1,523 @@ +RSpec::Support.require_rspec_core "formatters/console_codes" +RSpec::Support.require_rspec_core "formatters/exception_presenter" +RSpec::Support.require_rspec_core "formatters/helpers" +RSpec::Support.require_rspec_core "shell_escape" + +module RSpec::Core + # Notifications are value objects passed to formatters to provide them + # with information about a particular event of interest. + module Notifications + # @private + module NullColorizer + module_function + + def wrap(line, _code_or_symbol) + line + end + end + + # The `StartNotification` represents a notification sent by the reporter + # when the suite is started. It contains the expected amount of examples + # to be executed, and the load time of RSpec. + # + # @attr count [Fixnum] the number counted + # @attr load_time [Float] the number of seconds taken to boot RSpec + # and load the spec files + StartNotification = Struct.new(:count, :load_time) + + # The `ExampleNotification` represents notifications sent by the reporter + # which contain information about the current (or soon to be) example. + # It is used by formatters to access information about that example. + # + # @example + # def example_started(notification) + # puts "Hey I started #{notification.example.description}" + # end + # + # @attr example [RSpec::Core::Example] the current example + ExampleNotification = Struct.new(:example) + class ExampleNotification + # @private + def self.for(example) + execution_result = example.execution_result + + return SkippedExampleNotification.new(example) if execution_result.example_skipped? + return new(example) unless execution_result.status == :pending || execution_result.status == :failed + + klass = if execution_result.pending_fixed? + PendingExampleFixedNotification + elsif execution_result.status == :pending + PendingExampleFailedAsExpectedNotification + else + FailedExampleNotification + end + + klass.new(example) + end + + private_class_method :new + end + + # The `ExamplesNotification` represents notifications sent by the reporter + # which contain information about the suites examples. + # + # @example + # def stop(notification) + # puts "Hey I ran #{notification.examples.size}" + # end + # + class ExamplesNotification + def initialize(reporter) + @reporter = reporter + end + + # @return [Array] list of examples + def examples + @reporter.examples + end + + # @return [Array] list of failed examples + def failed_examples + @reporter.failed_examples + end + + # @return [Array] list of pending examples + def pending_examples + @reporter.pending_examples + end + + # @return [Array] + # returns examples as notifications + def notifications + @notifications ||= format_examples(examples) + end + + # @return [Array] + # returns failed examples as notifications + def failure_notifications + @failed_notifications ||= format_examples(failed_examples) + end + + # @return [Array] + # returns pending examples as notifications + def pending_notifications + @pending_notifications ||= format_examples(pending_examples) + end + + # @return [String] The list of failed examples, fully formatted in the way + # that RSpec's built-in formatters emit. + def fully_formatted_failed_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + formatted = "\nFailures:\n" + + failure_notifications.each_with_index do |failure, index| + formatted += failure.fully_formatted(index.next, colorizer) + end + + formatted + end + + # @return [String] The list of pending examples, fully formatted in the + # way that RSpec's built-in formatters emit. + def fully_formatted_pending_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + return if RSpec.configuration.pending_failure_output == :skip + + formatted = "\nPending: (Failures listed here are expected and do not affect your suite's status)\n".dup + + pending_notifications.each_with_index do |notification, index| + formatted << notification.fully_formatted(index.next, colorizer) + end + + formatted + end + + private + + def format_examples(examples) + examples.map do |example| + ExampleNotification.for(example) + end + end + end + + # The `FailedExampleNotification` extends `ExampleNotification` with + # things useful for examples that have failure info -- typically a + # failed or pending spec. + # + # @example + # def example_failed(notification) + # puts "Hey I failed :(" + # puts "Here's my stack trace" + # puts notification.exception.backtrace.join("\n") + # end + # + # @attr [RSpec::Core::Example] example the current example + # @see ExampleNotification + class FailedExampleNotification < ExampleNotification + public_class_method :new + + # @return [Exception] The example failure + def exception + @exception_presenter.exception + end + + # @return [String] The example description + def description + @exception_presenter.description + end + + # Returns the message generated for this failure line by line. + # + # @return [Array] The example failure message + def message_lines + @exception_presenter.message_lines + end + + # Returns the message generated for this failure colorized line by line. + # + # @param colorizer [#wrap] An object to colorize the message_lines by + # @return [Array] The example failure message colorized + def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.colorized_message_lines(colorizer) + end + + # Returns the failures formatted backtrace. + # + # @return [Array] the examples backtrace lines + def formatted_backtrace + @exception_presenter.formatted_backtrace + end + + # Returns the failures colorized formatted backtrace. + # + # @param colorizer [#wrap] An object to colorize the message_lines by + # @return [Array] the examples colorized backtrace lines + def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.colorized_formatted_backtrace(colorizer) + end + + # @return [String] The failure information fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.fully_formatted(failure_number, colorizer) + end + + # @return [Array] The failure information fully formatted in the way that + # RSpec's built-in formatters emit, split by line. + def fully_formatted_lines(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.fully_formatted_lines(failure_number, colorizer) + end + + private + + def initialize(example, exception_presenter=Formatters::ExceptionPresenter::Factory.new(example).build) + @exception_presenter = exception_presenter + super(example) + end + end + + # @deprecated Use {FailedExampleNotification} instead. + class PendingExampleFixedNotification < FailedExampleNotification; end + + # @deprecated Use {FailedExampleNotification} instead. + class PendingExampleFailedAsExpectedNotification < FailedExampleNotification; end + + # The `SkippedExampleNotification` extends `ExampleNotification` with + # things useful for specs that are skipped. + # + # @attr [RSpec::Core::Example] example the current example + # @see ExampleNotification + class SkippedExampleNotification < ExampleNotification + public_class_method :new + + # @return [String] The pending detail fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted(pending_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) + formatted_caller = RSpec.configuration.backtrace_formatter.backtrace_line(example.location) + + [ + colorizer.wrap("\n #{pending_number}) #{example.full_description}", :pending), + "\n ", + Formatters::ExceptionPresenter::PENDING_DETAIL_FORMATTER.call(example, colorizer), + "\n", + colorizer.wrap(" # #{formatted_caller}\n", :detail) + ].join("") + end + end + + # The `GroupNotification` represents notifications sent by the reporter + # which contain information about the currently running (or soon to be) + # example group. It is used by formatters to access information about that + # group. + # + # @example + # def example_group_started(notification) + # puts "Hey I started #{notification.group.description}" + # end + # @attr group [RSpec::Core::ExampleGroup] the current group + GroupNotification = Struct.new(:group) + + # The `MessageNotification` encapsulates generic messages that the reporter + # sends to formatters. + # + # @attr message [String] the message + MessageNotification = Struct.new(:message) + + # The `SeedNotification` holds the seed used to randomize examples and + # whether that seed has been used or not. + # + # @attr seed [Fixnum] the seed used to randomize ordering + # @attr used [Boolean] whether the seed has been used or not + SeedNotification = Struct.new(:seed, :used) + class SeedNotification + # @api + # @return [Boolean] has the seed been used? + def seed_used? + !!used + end + private :used + + # @return [String] The seed information fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted + "\nRandomized with seed #{seed}\n" + end + end + + # The `SummaryNotification` holds information about the results of running + # a test suite. It is used by formatters to provide information at the end + # of the test run. + # + # @attr duration [Float] the time taken (in seconds) to run the suite + # @attr examples [Array] the examples run + # @attr failed_examples [Array] the failed examples + # @attr pending_examples [Array] the pending examples + # @attr load_time [Float] the number of seconds taken to boot RSpec + # and load the spec files + # @attr errors_outside_of_examples_count [Integer] the number of errors that + # have occurred processing + # the spec suite + SummaryNotification = Struct.new(:duration, :examples, :failed_examples, + :pending_examples, :load_time, + :errors_outside_of_examples_count) + class SummaryNotification + # @api + # @return [Fixnum] the number of examples run + def example_count + @example_count ||= examples.size + end + + # @api + # @return [Fixnum] the number of failed examples + def failure_count + @failure_count ||= failed_examples.size + end + + # @api + # @return [Fixnum] the number of pending examples + def pending_count + @pending_count ||= pending_examples.size + end + + # @api + # @return [String] A line summarising the result totals of the spec run. + def totals_line + summary = Formatters::Helpers.pluralize(example_count, "example") + + ", " + Formatters::Helpers.pluralize(failure_count, "failure") + summary += ", #{pending_count} pending" if pending_count > 0 + if errors_outside_of_examples_count > 0 + summary += ( + ", " + + Formatters::Helpers.pluralize(errors_outside_of_examples_count, "error") + + " occurred outside of examples" + ) + end + summary + end + + # @api public + # + # Wraps the results line with colors based on the configured + # colors for failure, pending, and success. Defaults to red, + # yellow, green accordingly. + # + # @param colorizer [#wrap] An object which supports wrapping text with + # specific colors. + # @return [String] A colorized results line. + def colorized_totals_line(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + if failure_count > 0 || errors_outside_of_examples_count > 0 + colorizer.wrap(totals_line, RSpec.configuration.failure_color) + elsif pending_count > 0 + colorizer.wrap(totals_line, RSpec.configuration.pending_color) + else + colorizer.wrap(totals_line, RSpec.configuration.success_color) + end + end + + # @api public + # + # Formats failures into a rerunable command format. + # + # @param colorizer [#wrap] An object which supports wrapping text with + # specific colors. + # @return [String] A colorized summary line. + def colorized_rerun_commands(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + "\nFailed examples:\n\n" + + failed_examples.map do |example| + colorizer.wrap("rspec #{rerun_argument_for(example)}", RSpec.configuration.failure_color) + " " + + colorizer.wrap("# #{example.full_description}", RSpec.configuration.detail_color) + end.join("\n") + end + + # @return [String] a formatted version of the time it took to run the + # suite + def formatted_duration + Formatters::Helpers.format_duration(duration) + end + + # @return [String] a formatted version of the time it took to boot RSpec + # and load the spec files + def formatted_load_time + Formatters::Helpers.format_duration(load_time) + end + + # @return [String] The summary information fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + formatted = "\nFinished in #{formatted_duration} " \ + "(files took #{formatted_load_time} to load)\n" \ + "#{colorized_totals_line(colorizer)}\n" + + unless failed_examples.empty? + formatted += (colorized_rerun_commands(colorizer) + "\n") + end + + formatted + end + + private + + include RSpec::Core::ShellEscape + + def rerun_argument_for(example) + location = example.location_rerun_argument + return location unless duplicate_rerun_locations.include?(location) + conditionally_quote(example.id) + end + + def duplicate_rerun_locations + @duplicate_rerun_locations ||= begin + locations = RSpec.world.all_examples.map(&:location_rerun_argument) + + Set.new.tap do |s| + locations.group_by { |l| l }.each do |l, ls| + s << l if ls.count > 1 + end + end + end + end + end + + # The `ProfileNotification` holds information about the results of running a + # test suite when profiling is enabled. It is used by formatters to provide + # information at the end of the test run for profiling information. + # + # @attr duration [Float] the time taken (in seconds) to run the suite + # @attr examples [Array] the examples run + # @attr number_of_examples [Fixnum] the number of examples to profile + # @attr example_groups [Array] example groups run + class ProfileNotification + def initialize(duration, examples, number_of_examples, example_groups) + @duration = duration + @examples = examples + @number_of_examples = number_of_examples + @example_groups = example_groups + end + attr_reader :duration, :examples, :number_of_examples + + # @return [Array] the slowest examples + def slowest_examples + @slowest_examples ||= + examples.sort_by do |example| + -example.execution_result.run_time + end.first(number_of_examples) + end + + # @return [Float] the time taken (in seconds) to run the slowest examples + def slow_duration + @slow_duration ||= + slowest_examples.inject(0.0) do |i, e| + i + e.execution_result.run_time + end + end + + # @return [String] the percentage of total time taken + def percentage + @percentage ||= + begin + time_taken = slow_duration / duration + '%.1f' % ((time_taken.nan? ? 0.0 : time_taken) * 100) + end + end + + # @return [Array] the slowest example groups + def slowest_groups + @slowest_groups ||= calculate_slowest_groups + end + + private + + def calculate_slowest_groups + # stop if we've only one example group + return {} if @example_groups.keys.length <= 1 + + @example_groups.each_value do |hash| + hash[:average] = hash[:total_time].to_f / hash[:count] + end + + groups = @example_groups.sort_by { |_, hash| -hash[:average] }.first(number_of_examples) + groups.map { |group, data| [group.location, data] } + end + end + + # The `DeprecationNotification` is issued by the reporter when a deprecated + # part of RSpec is encountered. It represents information about the + # deprecated call site. + # + # @attr message [String] A custom message about the deprecation + # @attr deprecated [String] A custom message about the deprecation (alias of + # message) + # @attr replacement [String] An optional replacement for the deprecation + # @attr call_site [String] An optional call site from which the deprecation + # was issued + DeprecationNotification = Struct.new(:deprecated, :message, :replacement, :call_site) + class DeprecationNotification + private_class_method :new + + # @api + # Convenience way to initialize the notification + def self.from_hash(data) + new data[:deprecated], data[:message], data[:replacement], data[:call_site] + end + end + + # `NullNotification` represents a placeholder value for notifications that + # currently require no information, but we may wish to extend in future. + class NullNotification + end + + # `CustomNotification` is used when sending custom events to formatters / + # other registered listeners, it creates attributes based on supplied hash + # of options. + class CustomNotification < Struct + # @param options [Hash] A hash of method / value pairs to create on this notification + # @return [CustomNotification] + # + # Build a custom notification based on the supplied option key / values. + def self.for(options={}) + return NullNotification if options.keys.empty? + new(*options.keys).new(*options.values) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb new file mode 100644 index 0000000..e239e87 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb @@ -0,0 +1,325 @@ +# http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html +require 'optparse' + +module RSpec::Core + # @private + class Parser + def self.parse(args, source=nil) + new(args).parse(source) + end + + attr_reader :original_args + + def initialize(original_args) + @original_args = original_args + end + + def parse(source=nil) + return { :files_or_directories_to_run => [] } if original_args.empty? + args = original_args.dup + + options = args.delete('--tty') ? { :tty => true } : {} + begin + parser(options).parse!(args) + rescue OptionParser::InvalidOption => e + abort "#{e.message}#{" (defined in #{source})" if source}\n\n" \ + "Please use --help for a listing of valid options" + end + + options[:files_or_directories_to_run] = args + options + end + + private + + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity + def parser(options) + OptionParser.new do |parser| + parser.summary_width = 34 + + parser.banner = "Usage: rspec [options] [files or directories]\n\n" + + parser.on('-I PATH', 'Specify PATH to add to $LOAD_PATH (may be used more than once).') do |dirs| + options[:libs] ||= [] + options[:libs].concat(dirs.split(File::PATH_SEPARATOR)) + end + + parser.on('-r', '--require PATH', 'Require a file.') do |path| + options[:requires] ||= [] + options[:requires] << path + end + + parser.on('-O', '--options PATH', 'Specify the path to a custom options file.') do |path| + options[:custom_options_file] = path + end + + parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.', + ' [defined] examples and groups are run in the order they are defined', + ' [rand] randomize the order of groups and examples', + ' [random] alias for rand', + ' [random:SEED] e.g. --order random:123', + ' [recently-modified] run the most recently modified files first') do |o| + options[:order] = o + end + + parser.on('--seed SEED', Integer, 'Equivalent of --order rand:SEED.') do |seed| + options[:order] = "rand:#{seed}" + end + + parser.on('--bisect[=verbose]', 'Repeatedly runs the suite in order to isolate the failures to the ', + ' smallest reproducible case.') do |argument| + options[:bisect] = argument || true + options[:runner] = RSpec::Core::Invocations::Bisect.new + end + + parser.on('--[no-]fail-fast[=COUNT]', 'Abort the run after a certain number of failures (1 by default).') do |argument| + if argument == true + value = 1 + elsif argument == false || argument == 0 + value = false + else + begin + value = Integer(argument) + rescue ArgumentError + RSpec.warning "Expected an integer value for `--fail-fast`, got: #{argument.inspect}", :call_site => nil + end + end + set_fail_fast(options, value) + end + + parser.on('--failure-exit-code CODE', Integer, + 'Override the exit code used when there are failing specs.') do |code| + options[:failure_exit_code] = code + end + + parser.on('--error-exit-code CODE', Integer, + 'Override the exit code used when there are errors loading or running specs outside of examples.') do |code| + options[:error_exit_code] = code + end + + parser.on('-X', '--[no-]drb', 'Run examples via DRb.') do |use_drb| + options[:drb] = use_drb + options[:runner] = RSpec::Core::Invocations::DRbWithFallback.new if use_drb + end + + parser.on('--drb-port PORT', 'Port to connect to the DRb server.') do |o| + options[:drb_port] = o.to_i + end + + parser.separator("\n **** Output ****\n\n") + + parser.on('-f', '--format FORMATTER', 'Choose a formatter.', + ' [p]rogress (default - dots)', + ' [d]ocumentation (group and example names)', + ' [h]tml', + ' [j]son', + ' [f]ailures ("file:line:reason", suitable for editors integration)', + ' custom formatter class name') do |o| + options[:formatters] ||= [] + options[:formatters] << [o] + end + + parser.on('-o', '--out FILE', + 'Write output to a file instead of $stdout. This option applies', + ' to the previously specified --format, or the default format', + ' if no format is specified.' + ) do |o| + options[:formatters] ||= [['progress']] + options[:formatters].last << o + end + + parser.on('--deprecation-out FILE', 'Write deprecation warnings to a file instead of $stderr.') do |file| + options[:deprecation_stream] = file + end + + parser.on('-b', '--backtrace', 'Enable full backtrace.') do |_o| + options[:full_backtrace] = true + end + + parser.on('-c', '--color', '--colour', '') do |_o| + # flag will be excluded from `--help` output because it is deprecated + options[:color] = true + options[:color_mode] = :automatic + end + + parser.on('--force-color', '--force-colour', 'Force the output to be in color, even if the output is not a TTY') do |_o| + if options[:color_mode] == :off + abort "Please only use one of `--force-color` and `--no-color`" + end + options[:color_mode] = :on + end + + parser.on('--no-color', '--no-colour', 'Force the output to not be in color, even if the output is a TTY') do |_o| + if options[:color_mode] == :on + abort "Please only use one of --force-color and --no-color" + end + options[:color_mode] = :off + end + + parser.on('-p', '--[no-]profile [COUNT]', + 'Enable profiling of examples and list the slowest examples (default: 10).') do |argument| + options[:profile_examples] = if argument.nil? + true + elsif argument == false + false + else + begin + Integer(argument) + rescue ArgumentError + RSpec.warning "Non integer specified as profile count, separate " \ + "your path from options with -- e.g. " \ + "`rspec --profile -- #{argument}`", + :call_site => nil + true + end + end + end + + parser.on('--dry-run', 'Print the formatter output of your suite without', + ' running any examples or hooks') do |_o| + options[:dry_run] = true + end + + parser.on('-w', '--warnings', 'Enable ruby warnings') do + if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=) + # :nocov: on older Ruby without Warning + Warning[:deprecated] = true + # :nocov: + end + $VERBOSE = true + end + + parser.separator <<-FILTERING + + **** Filtering/tags **** + + In addition to the following options for selecting specific files, groups, or + examples, you can select individual examples by appending the line number(s) to + the filename: + + rspec path/to/a_spec.rb:37:87 + + You can also pass example ids enclosed in square brackets: + + rspec path/to/a_spec.rb[1:5,1:6] # run the 5th and 6th examples/groups defined in the 1st group + +FILTERING + + parser.on('--only-failures', "Filter to just the examples that failed the last time they ran.") do + configure_only_failures(options) + end + + parser.on("-n", "--next-failure", "Apply `--only-failures` and abort after one failure.", + " (Equivalent to `--only-failures --fail-fast --order defined`)") do + configure_only_failures(options) + set_fail_fast(options, 1) + options[:order] ||= 'defined' + end + + parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb").') do |o| + if options[:pattern] + options[:pattern] += ',' + o + else + options[:pattern] = o + end + end + + parser.on('--exclude-pattern PATTERN', + 'Load files except those matching pattern. Opposite effect of --pattern.') do |o| + options[:exclude_pattern] = o + end + + parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING (may be", + " used more than once)") do |o| + (options[:full_description] ||= []) << Regexp.compile(Regexp.escape(o)) + end + + parser.on('-E', '--example-matches REGEX', "Run examples whose full nested names match REGEX (may be", + " used more than once)") do |o| + (options[:full_description] ||= []) << Regexp.compile(o) + end + + parser.on('-t', '--tag TAG[:VALUE]', + 'Run examples with the specified tag, or exclude examples', + 'by adding ~ before the tag.', + ' - e.g. ~slow', + ' - TAG is always converted to a symbol') do |tag| + filter_type = tag =~ /^~/ ? :exclusion_filter : :inclusion_filter + + name, value = tag.gsub(/^(~@|~|@)/, '').split(':', 2) + name = name.to_sym + + parsed_value = case value + when nil then true # The default value for tags is true + when 'true' then true + when 'false' then false + when 'nil' then nil + when /^:/ then value[1..-1].to_sym + when /^\d+$/ then Integer(value) + when /^\d+.\d+$/ then Float(value) + else + value + end + + add_tag_filter(options, filter_type, name, parsed_value) + end + + parser.on('--default-path PATH', 'Set the default path where RSpec looks for examples (can', + ' be a path to a file or a directory).') do |path| + options[:default_path] = path + end + + parser.separator("\n **** Utility ****\n\n") + + parser.on('--init', 'Initialize your project with RSpec.') do |_cmd| + options[:runner] = RSpec::Core::Invocations::InitializeProject.new + end + + parser.on('-v', '--version', 'Display the version.') do + options[:runner] = RSpec::Core::Invocations::PrintVersion.new + end + + # These options would otherwise be confusing to users, so we forcibly + # prevent them from executing. + # + # * --I is too similar to -I. + # * -d was a shorthand for --debugger, which is removed, but now would + # trigger --default-path. + invalid_options = %w[-d --I] + + hidden_options = invalid_options + %w[-c] + + parser.on_tail('-h', '--help', "You're looking at it.") do + options[:runner] = RSpec::Core::Invocations::PrintHelp.new(parser, hidden_options) + end + + # This prevents usage of the invalid_options. + invalid_options.each do |option| + parser.on(option) do + raise OptionParser::InvalidOption.new + end + end + end + end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity + + def add_tag_filter(options, filter_type, tag_name, value=true) + (options[filter_type] ||= {})[tag_name] = value + end + + def set_fail_fast(options, value) + options[:fail_fast] = value + end + + def configure_only_failures(options) + options[:only_failures] = true + add_tag_filter(options, :inclusion_filter, :last_run_status, 'failed') + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb new file mode 100644 index 0000000..6058a2f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb @@ -0,0 +1,208 @@ +module RSpec + module Core + # @private + module Ordering + # @private + # The default global ordering (defined order). + class Identity + def order(items) + items + end + end + + # @private + # Orders items randomly. + class Random + def initialize(configuration) + @configuration = configuration + @used = false + end + + def used? + @used + end + + def order(items) + @used = true + + seed = @configuration.seed.to_s + items.sort_by { |item| jenkins_hash_digest(seed + item.id) } + end + + private + + # http://en.wikipedia.org/wiki/Jenkins_hash_function + # Jenkins provides a good distribution and is simpler than MD5. + # It's a bit slower than MD5 (primarily because `Digest::MD5` is + # implemented in C) but has the advantage of not requiring us + # to load another part of stdlib, which we try to minimize. + def jenkins_hash_digest(string) + hash = 0 + + string.each_byte do |byte| + hash += byte + hash &= MAX_32_BIT + hash += ((hash << 10) & MAX_32_BIT) + hash &= MAX_32_BIT + hash ^= hash >> 6 + end + + hash += ((hash << 3) & MAX_32_BIT) + hash &= MAX_32_BIT + hash ^= hash >> 11 + hash += ((hash << 15) & MAX_32_BIT) + hash &= MAX_32_BIT + hash + end + + MAX_32_BIT = 4_294_967_295 + end + + # @private + # Orders items by modification time (most recent modified first). + class RecentlyModified + def order(list) + list.sort_by { |item| -File.mtime(item.metadata[:absolute_file_path]).to_i } + end + end + + # @private + # Orders items based on a custom block. + class Custom + def initialize(callable) + @callable = callable + end + + def order(list) + @callable.call(list) + end + end + + # @private + # A strategy which delays looking up the ordering until needed + class Delayed + def initialize(registry, name) + @registry = registry + @name = name + end + + def order(list) + strategy.order(list) + end + + private + + def strategy + @strategy ||= lookup_strategy + end + + def lookup_strategy + raise "Undefined ordering strategy #{@name.inspect}" unless @registry.has_strategy?(@name) + @registry.fetch(@name) + end + end + + # @private + # Stores the different ordering strategies. + class Registry + def initialize(configuration) + @configuration = configuration + @strategies = {} + + register(:random, Random.new(configuration)) + register(:recently_modified, RecentlyModified.new) + + identity = Identity.new + register(:defined, identity) + + # The default global ordering is --defined. + register(:global, identity) + end + + def fetch(name, &fallback) + @strategies.fetch(name, &fallback) + end + + def has_strategy?(name) + @strategies.key?(name) + end + + def register(sym, strategy) + @strategies[sym] = strategy + end + + def used_random_seed? + @strategies[:random].used? + end + end + + # @private + # Manages ordering configuration. + # + # @note This is not intended to be used externally. Use + # the APIs provided by `RSpec::Core::Configuration` instead. + class ConfigurationManager + attr_reader :seed, :ordering_registry + + def initialize + @ordering_registry = Registry.new(self) + @seed = rand(0xFFFF) + @seed_forced = false + @order_forced = false + end + + def seed_used? + ordering_registry.used_random_seed? + end + + def seed=(seed) + return if @seed_forced + register_ordering(:global, ordering_registry.fetch(:random)) + @seed = seed.to_i + end + + def order=(type) + order, seed = type.to_s.split(':') + @seed = seed.to_i if seed + + ordering_name = if order.include?('rand') + :random + elsif order == 'defined' + :defined + elsif order == 'recently-modified' + :recently_modified + else + order.to_sym + end + + if ordering_name + strategy = + if ordering_registry.has_strategy?(ordering_name) + ordering_registry.fetch(ordering_name) + else + Delayed.new(ordering_registry, ordering_name) + end + + register_ordering(:global, strategy) + end + end + + def force(hash) + if hash.key?(:seed) + self.seed = hash[:seed] + @seed_forced = true + @order_forced = true + elsif hash.key?(:order) + self.order = hash[:order] + @order_forced = true + end + end + + def register_ordering(name, strategy=Custom.new(Proc.new { |l| yield l })) + return if @order_forced && name == :global + ordering_registry.register(name, strategy) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb new file mode 100644 index 0000000..8e07aa8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb @@ -0,0 +1,29 @@ +module RSpec + module Core + # @private + class OutputWrapper + # @private + attr_accessor :output + + # @private + def initialize(output) + @output = output + end + + def respond_to?(name, priv=false) + output.respond_to?(name, priv) + end + + def method_missing(name, *args, &block) + output.__send__(name, *args, &block) + end + + # Redirect calls for IO interface methods + IO.instance_methods(false).each do |method| + define_method(method) do |*args, &block| + output.__send__(method, *args, &block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb new file mode 100644 index 0000000..c6c59c1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb @@ -0,0 +1,157 @@ +module RSpec + module Core + # Provides methods to mark examples as pending. These methods are available + # to be called from within any example or hook. + module Pending + # Raised in the middle of an example to indicate that it should be marked + # as skipped. + class SkipDeclaredInExample < StandardError + attr_reader :argument + + def initialize(argument) + @argument = argument + end + end + + # If Test::Unit is loaded, we'll use its error as baseclass, so that + # Test::Unit will report unmet RSpec expectations as failures rather than + # errors. + begin + class PendingExampleFixedError < Test::Unit::AssertionFailedError; end + rescue + class PendingExampleFixedError < StandardError; end + end + + # @private + NO_REASON_GIVEN = 'No reason given' + + # @private + NOT_YET_IMPLEMENTED = 'Not yet implemented' + + # @overload pending() + # @overload pending(message) + # + # Marks an example as pending. The rest of the example will still be + # executed, and if it passes the example will fail to indicate that the + # pending can be removed. + # + # @param message [String] optional message to add to the summary report. + # + # @example + # describe "some behaviour" do + # # reported as "Pending: no reason given" + # it "is pending with no message" do + # pending + # raise "broken" + # end + # + # # reported as "Pending: something else getting finished" + # it "is pending with a custom message" do + # pending("something else getting finished") + # raise "broken" + # end + # end + # + # @note When using `pending` inside an example body using this method + # hooks, such as `before(:example)`, have already be run. This means that + # a failure from the code in the `before` hook will prevent the example + # from being considered pending, as the example body would not be + # executed. If you need to consider hooks as pending as well you can use + # the pending metadata as an alternative, e.g. + # `it "does something", pending: "message"`. + def pending(message=nil, &_block) + current_example = RSpec.current_example + + if block_given? + raise ArgumentError, <<-EOS.gsub(/^\s+\|/, '') + |The semantics of `RSpec::Core::Pending#pending` have changed in + |RSpec 3. In RSpec 2.x, it caused the example to be skipped. In + |RSpec 3, the rest of the example is still run but is expected to + |fail, and will be marked as a failure (rather than as pending) if + |the example passes. + | + |Passing a block within an example is now deprecated. Marking the + |example as pending provides the same behavior in RSpec 3 which was + |provided only by the block in RSpec 2.x. + | + |Move the code in the block provided to `pending` into the rest of + |the example body. + | + |Called from #{CallerFilter.first_non_rspec_line}. + | + EOS + elsif current_example + Pending.mark_pending! current_example, message + else + raise "`pending` may not be used outside of examples, such as in " \ + "before(:context). Maybe you want `skip`?" + end + end + + # @overload skip() + # @overload skip(message) + # + # Marks an example as pending and skips execution. + # + # @param message [String] optional message to add to the summary report. + # + # @example + # describe "an example" do + # # reported as "Pending: no reason given" + # it "is skipped with no message" do + # skip + # end + # + # # reported as "Pending: something else getting finished" + # it "is skipped with a custom message" do + # skip "something else getting finished" + # end + # end + def skip(message=nil) + current_example = RSpec.current_example + + Pending.mark_skipped!(current_example, message) if current_example + + raise SkipDeclaredInExample.new(message) + end + + # @private + # + # Mark example as skipped. + # + # @param example [RSpec::Core::Example] the example to mark as skipped + # @param message_or_bool [Boolean, String] the message to use, or true + def self.mark_skipped!(example, message_or_bool) + Pending.mark_pending! example, message_or_bool + example.metadata[:skip] = true + end + + # @private + # + # Mark example as pending. + # + # @param example [RSpec::Core::Example] the example to mark as pending + # @param message_or_bool [Boolean, String] the message to use, or true + def self.mark_pending!(example, message_or_bool) + message = if !message_or_bool || !(String === message_or_bool) + NO_REASON_GIVEN + else + message_or_bool + end + + example.metadata[:pending] = true + example.execution_result.pending_message = message + example.execution_result.pending_fixed = false + end + + # @private + # + # Mark example as fixed. + # + # @param example [RSpec::Core::Example] the example to mark as fixed + def self.mark_fixed!(example) + example.execution_result.pending_fixed = true + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb new file mode 100644 index 0000000..5e65279 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb @@ -0,0 +1,34 @@ +module RSpec + module Core + # @private + class Profiler + NOTIFICATIONS = [:example_group_started, :example_group_finished, :example_started] + + def initialize + @example_groups = Hash.new { |h, k| h[k] = { :count => 0 } } + end + + attr_reader :example_groups + + def example_group_started(notification) + return unless notification.group.top_level? + + @example_groups[notification.group][:start] = Time.now + @example_groups[notification.group][:description] = notification.group.top_level_description + end + + def example_group_finished(notification) + return unless notification.group.top_level? + + group = @example_groups[notification.group] + return unless group.key?(:start) + group[:total_time] = Time.now - group[:start] + end + + def example_started(notification) + group = notification.example.example_group.parent_groups.last + @example_groups[group][:count] += 1 + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb new file mode 100644 index 0000000..ca707e0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb @@ -0,0 +1,48 @@ +RSpec::Support.require_rspec_support "directory_maker" + +module RSpec + module Core + # @private + # Generates conventional files for an RSpec project. + class ProjectInitializer + attr_reader :destination, :stream, :template_path + + DOT_RSPEC_FILE = '.rspec' + SPEC_HELPER_FILE = 'spec/spec_helper.rb' + + def initialize(opts={}) + @destination = opts.fetch(:destination, Dir.getwd) + @stream = opts.fetch(:report_stream, $stdout) + @template_path = opts.fetch(:template_path) do + File.expand_path("../project_initializer", __FILE__) + end + end + + def run + copy_template DOT_RSPEC_FILE + copy_template SPEC_HELPER_FILE + end + + private + + def copy_template(file) + destination_file = File.join(destination, file) + return report_exists(file) if File.exist?(destination_file) + + report_creating(file) + RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(destination_file)) + File.open(destination_file, 'w') do |f| + f.write File.read(File.join(template_path, file)) + end + end + + def report_exists(file) + stream.puts " exist #{file}" + end + + def report_creating(file) + stream.puts " create #{file}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec new file mode 100644 index 0000000..c99d2e7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb new file mode 100644 index 0000000..c80d44b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb @@ -0,0 +1,98 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb new file mode 100644 index 0000000..1b60db0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb @@ -0,0 +1,190 @@ +require 'rake' +require 'rake/tasklib' +require 'rspec/support' + +RSpec::Support.require_rspec_support "ruby_features" + +# :nocov: +unless RSpec::Support.respond_to?(:require_rspec_core) + RSpec::Support.define_optimized_require_for_rspec(:core) { |f| require_relative "../#{f}" } +end +# :nocov: + +RSpec::Support.require_rspec_core "shell_escape" + +module RSpec + module Core + # RSpec rake task + # + # @see Rakefile + class RakeTask < ::Rake::TaskLib + include ::Rake::DSL if defined?(::Rake::DSL) + include RSpec::Core::ShellEscape + + # Default path to the RSpec executable. + DEFAULT_RSPEC_PATH = File.expand_path('../../../../exe/rspec', __FILE__) + + # Default pattern for spec files. + DEFAULT_PATTERN = 'spec/**{,/*/**}/*_spec.rb' + + # Name of task. Defaults to `:spec`. + attr_accessor :name + + # Files matching this pattern will be loaded. + # Defaults to `'spec/**{,/*/**}/*_spec.rb'`. + attr_accessor :pattern + + # Files matching this pattern will be excluded. + # Defaults to `nil`. + attr_accessor :exclude_pattern + + # Whether or not to fail Rake when an error occurs (typically when + # examples fail). Defaults to `true`. + attr_accessor :fail_on_error + + # A message to print to stderr when there are failures. + attr_accessor :failure_message + + if RUBY_VERSION < "1.9.0" || Support::Ruby.jruby? + # Run RSpec with a clean (empty) environment is not supported + # :nocov: + def with_clean_environment=(_value) + raise ArgumentError, "Running in a clean environment is not supported on Ruby versions before 1.9.0" + end + + # Run RSpec with a clean (empty) environment is not supported + def with_clean_environment + false + end + # :nocov: + else + # Run RSpec with a clean (empty) environment. + attr_accessor :with_clean_environment + end + + # Use verbose output. If this is set to true, the task will print the + # executed spec command to stdout. Defaults to `true`. + attr_accessor :verbose + + # Command line options to pass to ruby. Defaults to `nil`. + attr_accessor :ruby_opts + + # Path to RSpec. Defaults to the absolute path to the + # rspec binary from the loaded rspec-core gem. + attr_accessor :rspec_path + + # Command line options to pass to RSpec. Defaults to `nil`. + attr_accessor :rspec_opts + + def initialize(*args, &task_block) + @name = args.shift || :spec + @ruby_opts = nil + @rspec_opts = nil + @verbose = true + @fail_on_error = true + @rspec_path = DEFAULT_RSPEC_PATH + @pattern = DEFAULT_PATTERN + + define(args, &task_block) + end + + # @private + def run_task(verbose) + command = spec_command + puts command if verbose + + if with_clean_environment + return if system({}, command, :unsetenv_others => true) + else + return if system(command) + end + + puts failure_message if failure_message + + return unless fail_on_error + $stderr.puts "#{command} failed" if verbose + exit $?.exitstatus || 1 + end + + private + + # @private + def define(args, &task_block) + desc "Run RSpec code examples" unless ::Rake.application.last_description + + task name, *args do |_, task_args| + RakeFileUtils.__send__(:verbose, verbose) do + task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block + run_task verbose + end + end + end + + def file_inclusion_specification + if ENV['SPEC'] + FileList[ENV['SPEC']].sort + elsif String === pattern && !File.exist?(pattern) + return if [*rspec_opts].any? { |opt| opt =~ /--pattern/ } + "--pattern #{escape pattern}" + else + # Before RSpec 3.1, we used `FileList` to get the list of matched + # files, and then pass that along to the `rspec` command. Starting + # with 3.1, we prefer to pass along the pattern as-is to the `rspec` + # command, for 3 reasons: + # + # * It's *much* less verbose to pass one `--pattern` option than a + # long list of files. + # * It ensures `task.pattern` and `--pattern` have the same + # behavior. + # * It fixes a bug, where + # `task.pattern = pattern_that_matches_no_files` would run *all* + # files because it would cause no pattern or file args to get + # passed to `rspec`, which causes all files to get run. + # + # However, `FileList` is *far* more flexible than the `--pattern` + # option. Specifically, it supports individual files and directories, + # as well as arrays of files, directories and globs, as well as other + # `FileList` objects. + # + # For backwards compatibility, we have to fall back to using FileList + # if the user has passed a `pattern` option that will not work with + # `--pattern`. + # + # TODO: consider deprecating support for this and removing it in + # RSpec 4. + FileList[pattern].sort.map { |file| escape file } + end + end + + def file_exclusion_specification + " --exclude-pattern #{escape exclude_pattern}" if exclude_pattern + end + + def spec_command + cmd_parts = [] + cmd_parts << RUBY + cmd_parts << ruby_opts + cmd_parts << rspec_load_path + cmd_parts << escape(rspec_path) + cmd_parts << file_inclusion_specification + cmd_parts << file_exclusion_specification + cmd_parts << rspec_opts + cmd_parts.flatten.reject(&blank).join(" ") + end + + def blank + lambda { |s| s.nil? || s == "" } + end + + def rspec_load_path + @rspec_load_path ||= begin + core_and_support = $LOAD_PATH.grep( + /#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib/ + ).uniq + + "-I#{core_and_support.map { |file| escape file }.join(File::PATH_SEPARATOR)}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb new file mode 100644 index 0000000..d513f3f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb @@ -0,0 +1,266 @@ +module RSpec::Core + # A reporter will send notifications to listeners, usually formatters for the + # spec suite run. + class Reporter + # @private + RSPEC_NOTIFICATIONS = Set.new( + [ + :close, :deprecation, :deprecation_summary, :dump_failures, :dump_pending, + :dump_profile, :dump_summary, :example_failed, :example_group_finished, + :example_group_started, :example_passed, :example_pending, :example_started, + :message, :seed, :start, :start_dump, :stop, :example_finished + ]) + + def initialize(configuration) + @configuration = configuration + @listeners = Hash.new { |h, k| h[k] = Set.new } + @examples = [] + @failed_examples = [] + @pending_examples = [] + @duration = @start = @load_time = nil + @non_example_exception_count = 0 + @setup_default = lambda {} + @setup = false + @profiler = nil + end + + # @private + attr_reader :examples, :failed_examples, :pending_examples + + # Registers a listener to a list of notifications. The reporter will send + # notification of events to all registered listeners. + # + # @param listener [Object] An object that wishes to be notified of reporter + # events + # @param notifications [Array] Array of symbols represents the events a + # listener wishes to subscribe too + def register_listener(listener, *notifications) + notifications.each do |notification| + @listeners[notification.to_sym] << listener + end + true + end + + # @private + def prepare_default(loader, output_stream, deprecation_stream) + @setup_default = lambda do + loader.setup_default output_stream, deprecation_stream + end + end + + # @private + def registered_listeners(notification) + @listeners[notification].to_a + end + + # @overload report(count, &block) + # @overload report(count, &block) + # @param expected_example_count [Integer] the number of examples being run + # @yield [Block] block yields itself for further reporting. + # + # Initializes the report run and yields itself for further reporting. The + # block is required, so that the reporter can manage cleaning up after the + # run. + # + # @example + # + # reporter.report(group.examples.size) do |r| + # example_groups.map {|g| g.run(r) } + # end + # + def report(expected_example_count) + start(expected_example_count) + begin + yield self + ensure + finish + end + end + + # @param exit_code [Integer] the exit_code to be return by the reporter + # + # Reports a run that exited early without having run any examples. + # + def exit_early(exit_code) + report(0) { exit_code } + end + + # @private + def start(expected_example_count, time=RSpec::Core::Time.now) + @start = time + @load_time = (@start - @configuration.start_time).to_f + notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?) + notify :start, Notifications::StartNotification.new(expected_example_count, @load_time) + end + + # @param message [#to_s] A message object to send to formatters + # + # Send a custom message to supporting formatters. + def message(message) + notify :message, Notifications::MessageNotification.new(message) + end + + # @param event [Symbol] Name of the custom event to trigger on formatters + # @param options [Hash] Hash of arguments to provide via `CustomNotification` + # + # Publish a custom event to supporting registered formatters. + # @see RSpec::Core::Notifications::CustomNotification + def publish(event, options={}) + if RSPEC_NOTIFICATIONS.include? event + raise "RSpec::Core::Reporter#publish is intended for sending custom " \ + "events not internal RSpec ones, please rename your custom event." + end + notify event, Notifications::CustomNotification.for(options) + end + + # @private + def example_group_started(group) + notify :example_group_started, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty? + end + + # @private + def example_group_finished(group) + notify :example_group_finished, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty? + end + + # @private + def example_started(example) + @examples << example + notify :example_started, Notifications::ExampleNotification.for(example) + end + + # @private + def example_finished(example) + notify :example_finished, Notifications::ExampleNotification.for(example) + end + + # @private + def example_passed(example) + notify :example_passed, Notifications::ExampleNotification.for(example) + end + + # @private + def example_failed(example) + @failed_examples << example + notify :example_failed, Notifications::ExampleNotification.for(example) + end + + # @private + def example_pending(example) + @pending_examples << example + notify :example_pending, Notifications::ExampleNotification.for(example) + end + + # @private + def deprecation(hash) + notify :deprecation, Notifications::DeprecationNotification.from_hash(hash) + end + + # @private + # Provides a way to notify of an exception that is not tied to any + # particular example (such as an exception encountered in a :suite hook). + # Exceptions will be formatted the same way they normally are. + def notify_non_example_exception(exception, context_description) + @configuration.world.non_example_failure = true + @non_example_exception_count += 1 + + example = Example.new(AnonymousExampleGroup, context_description, {}) + presenter = Formatters::ExceptionPresenter.new(exception, example, :indentation => 0) + message presenter.fully_formatted(nil) + end + + # @private + def finish + close_after do + examples_notification = Notifications::ExamplesNotification.new(self) + stop(examples_notification) + notify :start_dump, Notifications::NullNotification + notify :dump_pending, examples_notification + notify :dump_failures, examples_notification + notify :deprecation_summary, Notifications::NullNotification + unless mute_profile_output? + notify :dump_profile, Notifications::ProfileNotification.new(@duration, @examples, + @configuration.profile_examples, + @profiler.example_groups) + end + notify :dump_summary, Notifications::SummaryNotification.new(@duration, @examples, @failed_examples, + @pending_examples, @load_time, + @non_example_exception_count) + notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?) + end + end + + # @private + def close_after + yield + ensure + close + end + + # @private + def stop(notification) + @duration = (RSpec::Core::Time.now - @start).to_f if @start + notify :stop, notification + end + + # @private + def notify(event, notification) + ensure_listeners_ready + registered_listeners(event).each do |formatter| + formatter.__send__(event, notification) + end + end + + # @private + def abort_with(msg, exit_status) + message(msg) + close + exit!(exit_status) + end + + # @private + def fail_fast_limit_met? + return false unless (fail_fast = @configuration.fail_fast) + + if fail_fast == true + @failed_examples.any? + else + fail_fast <= @failed_examples.size + end + end + + private + + def ensure_listeners_ready + return if @setup + + @setup_default.call + @profiler = Profiler.new + register_listener @profiler, *Profiler::NOTIFICATIONS + @setup = true + end + + def close + notify :close, Notifications::NullNotification + end + + def mute_profile_output? + # Don't print out profiled info if there are failures and `--fail-fast` is + # used, it just clutters the output. + !@configuration.profile_examples? || fail_fast_limit_met? + end + + def seed_used? + @configuration.seed && @configuration.seed_used? + end + end + + # @private + # # Used in place of a {Reporter} for situations where we don't want reporting output. + class NullReporter + def self.method_missing(*) + # ignore + end + private_class_method :method_missing + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb new file mode 100644 index 0000000..156f89b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb @@ -0,0 +1,53 @@ +# This is borrowed (slightly modified) from Scott Taylor's +# project_path project: +# http://github.com/smtlaissezfaire/project_path +module RSpec + module Core + # @private + module RubyProject + def add_to_load_path(*dirs) + dirs.each { |dir| add_dir_to_load_path(File.join(root, dir)) } + end + + def add_dir_to_load_path(dir) + $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) + end + + def root + @project_root ||= determine_root + end + + def determine_root + find_first_parent_containing('spec') || '.' + end + + def find_first_parent_containing(dir) + ascend_until { |path| File.exist?(File.join(path, dir)) } + end + + def ascend_until + fs = File::SEPARATOR + escaped_slash = "\\#{fs}" + special = "_RSPEC_ESCAPED_SLASH_" + project_path = File.expand_path(".") + parts = project_path.gsub(escaped_slash, special).squeeze(fs).split(fs).map do |x| + x.gsub(special, escaped_slash) + end + + until parts.empty? + path = parts.join(fs) + path = fs if path == "" + return path if yield(path) + parts.pop + end + end + + module_function :add_to_load_path + module_function :add_dir_to_load_path + module_function :root + module_function :determine_root + module_function :find_first_parent_containing + module_function :ascend_until + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb new file mode 100644 index 0000000..16d07ef --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb @@ -0,0 +1,216 @@ +module RSpec + module Core + # Provides the main entry point to run a suite of RSpec examples. + class Runner + # @attr_reader + # @private + attr_reader :options, :configuration, :world + + # Register an `at_exit` hook that runs the suite when the process exits. + # + # @note This is not generally needed. The `rspec` command takes care + # of running examples for you without involving an `at_exit` + # hook. This is only needed if you are running specs using + # the `ruby` command, and even then, the normal way to invoke + # this is by requiring `rspec/autorun`. + def self.autorun + if autorun_disabled? + RSpec.deprecate("Requiring `rspec/autorun` when running RSpec via the `rspec` command") + return + elsif installed_at_exit? || running_in_drb? + return + end + + at_exit { perform_at_exit } + @installed_at_exit = true + end + + # @private + def self.perform_at_exit + # Don't bother running any specs and just let the program terminate + # if we got here due to an unrescued exception (anything other than + # SystemExit, which is raised when somebody calls Kernel#exit). + return unless $!.nil? || $!.is_a?(SystemExit) + + # We got here because either the end of the program was reached or + # somebody called Kernel#exit. Run the specs and then override any + # existing exit status with RSpec's exit status if any specs failed. + invoke + end + + # Runs the suite of specs and exits the process with an appropriate exit + # code. + def self.invoke + disable_autorun! + status = run(ARGV, $stderr, $stdout).to_i + exit(status) if status != 0 + end + + # Run a suite of RSpec examples. Does not exit. + # + # This is used internally by RSpec to run a suite, but is available + # for use by any other automation tool. + # + # If you want to run this multiple times in the same process, and you + # want files like `spec_helper.rb` to be reloaded, be sure to load `load` + # instead of `require`. + # + # @param args [Array] command-line-supported arguments + # @param err [IO] error stream + # @param out [IO] output stream + # @return [Fixnum] exit status code. 0 if all specs passed, + # or the configured failure exit code (1 by default) if specs + # failed. + def self.run(args, err=$stderr, out=$stdout) + trap_interrupt + options = ConfigurationOptions.new(args) + + if options.options[:runner] + options.options[:runner].call(options, err, out) + else + new(options).run(err, out) + end + end + + def initialize(options, configuration=RSpec.configuration, world=RSpec.world) + @options = options + @configuration = configuration + @world = world + end + + # Configures and runs a spec suite. + # + # @param err [IO] error stream + # @param out [IO] output stream + def run(err, out) + setup(err, out) + return @configuration.reporter.exit_early(exit_code) if RSpec.world.wants_to_quit + + run_specs(@world.ordered_example_groups).tap do + persist_example_statuses + end + end + + # Wires together the various configuration objects and state holders. + # + # @param err [IO] error stream + # @param out [IO] output stream + def setup(err, out) + configure(err, out) + return if RSpec.world.wants_to_quit + + @configuration.load_spec_files + ensure + @world.announce_filters + end + + # Runs the provided example groups. + # + # @param example_groups [Array] groups to run + # @return [Fixnum] exit status code. 0 if all specs passed, + # or the configured failure exit code (1 by default) if specs + # failed. + def run_specs(example_groups) + examples_count = @world.example_count(example_groups) + examples_passed = @configuration.reporter.report(examples_count) do |reporter| + @configuration.with_suite_hooks do + if examples_count == 0 && @configuration.fail_if_no_examples + return @configuration.failure_exit_code + end + + example_groups.map { |g| g.run(reporter) }.all? + end + end + + exit_code(examples_passed) + end + + # @private + def configure(err, out) + @configuration.error_stream = err + @configuration.output_stream = out if @configuration.output_stream == $stdout + @options.configure(@configuration) + end + + # @private + def self.disable_autorun! + @autorun_disabled = true + end + + # @private + def self.autorun_disabled? + @autorun_disabled ||= false + end + + # @private + def self.installed_at_exit? + @installed_at_exit ||= false + end + + # @private + def self.running_in_drb? + return false unless defined?(DRb) + + server = begin + DRb.current_server + rescue DRb::DRbServerNotFound + return false + end + + return false unless server && server.alive? + + require 'socket' + require 'uri' + + local_ipv4 = begin + IPSocket.getaddress(Socket.gethostname) + rescue SocketError + return false + end + + ["127.0.0.1", "localhost", local_ipv4].any? { |addr| addr == URI(DRb.current_server.uri).host } + end + + # @private + def self.trap_interrupt + trap('INT') { handle_interrupt } + end + + # @private + def self.handle_interrupt + if RSpec.world.wants_to_quit + exit!(1) + else + RSpec.world.wants_to_quit = true + + $stderr.puts( + "\nRSpec is shutting down and will print the summary report... Interrupt again to force quit " \ + "(warning: at_exit hooks will be skipped if you force quit)." + ) + end + end + + # @private + def exit_code(examples_passed=false) + return @configuration.error_exit_code || @configuration.failure_exit_code if @world.non_example_failure + return @configuration.failure_exit_code unless examples_passed + + 0 + end + + private + + def persist_example_statuses + return if @configuration.dry_run + return unless (path = @configuration.example_status_persistence_file_path) + + ExampleStatusPersister.persist(@world.all_examples, path) + rescue SystemCallError => e + RSpec.warning "Could not write example statuses to #{path} (configured as " \ + "`config.example_status_persistence_file_path`) due to a " \ + "system error: #{e.inspect}. Please check that the config " \ + "option is set to an accessible, valid file path", :call_site => nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb new file mode 100644 index 0000000..e7d518c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb @@ -0,0 +1,37 @@ +module RSpec + module Core + # A sandbox isolates the enclosed code into an environment that looks 'new' + # meaning globally accessed objects are reset for the duration of the + # sandbox. + # + # @note This module is not normally available. You must require + # `rspec/core/sandbox` to load it. + module Sandbox + # Execute a provided block with RSpec global objects (configuration, + # world) reset. This is used to test RSpec with RSpec. + # + # When calling this the configuration is passed into the provided block. + # Use this to set custom configs for your sandboxed examples. + # + # ``` + # Sandbox.sandboxed do |config| + # config.before(:context) { RSpec.current_example = nil } + # end + # ``` + def self.sandboxed + orig_config = RSpec.configuration + orig_world = RSpec.world + orig_example = RSpec.current_example + + RSpec.configuration = RSpec::Core::Configuration.new + RSpec.world = RSpec::Core::World.new(RSpec.configuration) + + yield RSpec.configuration + ensure + RSpec.configuration = orig_config + RSpec.world = orig_world + RSpec.current_example = orig_example + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb new file mode 100644 index 0000000..ae97810 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb @@ -0,0 +1,54 @@ +module RSpec + module Core + # @private + # + # We use this to replace `::Set` so we can have the advantage of + # constant time key lookups for unique arrays but without the + # potential to pollute a developers environment with an extra + # piece of the stdlib. This helps to prevent false positive + # builds. + # + class Set + include Enumerable + + def initialize(array=[]) + @values = {} + merge(array) + end + + def empty? + @values.empty? + end + + def <<(key) + @values[key] = true + self + end + + def delete(key) + @values.delete(key) + end + + def each(&block) + @values.keys.each(&block) + self + end + + def include?(key) + @values.key?(key) + end + + def merge(values) + values.each do |key| + @values[key] = true + end + self + end + + def clear + @values.clear + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb new file mode 100644 index 0000000..6de7f64 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb @@ -0,0 +1,55 @@ +module RSpec + module Core + # Exposes {ExampleGroup}-level methods to a module, so you can include that + # module in an {ExampleGroup}. + # + # @example + # + # module LoggedInAsAdmin + # extend RSpec::Core::SharedContext + # before(:example) do + # log_in_as :admin + # end + # end + # + # describe "admin section" do + # include LoggedInAsAdmin + # # ... + # end + module SharedContext + # @private + def included(group) + __shared_context_recordings.each do |recording| + recording.playback_onto(group) + end + end + + # @private + def __shared_context_recordings + @__shared_context_recordings ||= [] + end + + # @private + Recording = Struct.new(:method_name, :args, :block) do + def playback_onto(group) + group.__send__(method_name, *args, &block) + end + end + + # @private + def self.record(methods) + methods.each do |meth| + define_method(meth) do |*args, &block| + __shared_context_recordings << Recording.new(meth, args, block) + end + end + end + + # @private + record [:describe, :context] + Hooks.instance_methods(false) + + MemoizedHelpers::ClassMethods.instance_methods(false) + end + end + # @private + SharedContext = Core::SharedContext +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb new file mode 100644 index 0000000..3d9efce --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb @@ -0,0 +1,271 @@ +RSpec::Support.require_rspec_support "with_keywords_when_needed" + +module RSpec + module Core + # Represents some functionality that is shared with multiple example groups. + # The functionality is defined by the provided block, which is lazily + # eval'd when the `SharedExampleGroupModule` instance is included in an example + # group. + class SharedExampleGroupModule < Module + # @private + attr_reader :definition + + def initialize(description, definition, metadata) + @description = description + @definition = definition + @metadata = metadata + end + + # Provides a human-readable representation of this module. + def inspect + "#<#{self.class.name} #{@description.inspect}>" + end + alias to_s inspect + + # Ruby callback for when a module is included in another module is class. + # Our definition evaluates the shared group block in the context of the + # including example group. + def included(klass) + inclusion_line = klass.metadata[:location] + include_in klass, inclusion_line, [], nil + end + + # @private + def include_in(klass, inclusion_line, args, customization_block) + klass.update_inherited_metadata(@metadata) unless @metadata.empty? + + SharedExampleGroupInclusionStackFrame.with_frame(@description, inclusion_line) do + RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *args, &@definition) + klass.class_exec(&customization_block) if customization_block + end + end + end + + # Shared example groups let you define common context and/or common + # examples that you wish to use in multiple example groups. + # + # When defined, the shared group block is stored for later evaluation. + # It can later be included in an example group either explicitly + # (using `include_examples`, `include_context` or `it_behaves_like`) + # or implicitly (via matching metadata). + # + # Named shared example groups are scoped based on where they are + # defined. Shared groups defined in an example group are available + # for inclusion in that example group or any child example groups, + # but not in any parent or sibling example groups. Shared example + # groups defined at the top level can be included from any example group. + module SharedExampleGroup + # @overload shared_examples(name, &block) + # @param name [String, Symbol, Module] identifer to use when looking up + # this shared group + # @param block The block to be eval'd + # @overload shared_examples(name, metadata, &block) + # @param name [String, Symbol, Module] identifer to use when looking up + # this shared group + # @param metadata [Array, Hash] metadata to attach to this + # group; any example group or example with matching metadata will + # automatically include this shared example group. + # @param block The block to be eval'd + # + # Stores the block for later use. The block will be evaluated + # in the context of an example group via `include_examples`, + # `include_context`, or `it_behaves_like`. + # + # @example + # shared_examples "auditable" do + # it "stores an audit record on save!" do + # expect { auditable.save! }.to change(Audit, :count).by(1) + # end + # end + # + # RSpec.describe Account do + # it_behaves_like "auditable" do + # let(:auditable) { Account.new } + # end + # end + # + # @see ExampleGroup.it_behaves_like + # @see ExampleGroup.include_examples + # @see ExampleGroup.include_context + def shared_examples(name, *args, &block) + top_level = self == ExampleGroup + if top_level && RSpec::Support.thread_local_data[:in_example_group] + raise "Creating isolated shared examples from within a context is " \ + "not allowed. Remove `RSpec.` prefix or move this to a " \ + "top-level scope." + end + + RSpec.world.shared_example_group_registry.add(self, name, *args, &block) + end + alias shared_context shared_examples + alias shared_examples_for shared_examples + + # @api private + # + # Shared examples top level DSL. + module TopLevelDSL + # @private + def self.definitions + proc do + def shared_examples(name, *args, &block) + RSpec.world.shared_example_group_registry.add(:main, name, *args, &block) + end + alias shared_context shared_examples + alias shared_examples_for shared_examples + end + end + + # @private + def self.exposed_globally? + @exposed_globally ||= false + end + + # @api private + # + # Adds the top level DSL methods to Module and the top level binding. + def self.expose_globally! + return if exposed_globally? + Core::DSL.change_global_dsl(&definitions) + @exposed_globally = true + end + + # @api private + # + # Removes the top level DSL methods to Module and the top level binding. + def self.remove_globally! + return unless exposed_globally? + + Core::DSL.change_global_dsl do + undef shared_examples + undef shared_context + undef shared_examples_for + end + + @exposed_globally = false + end + end + + # @private + class Registry + def add(context, name, *metadata_args, &block) + unless block + RSpec.warning "Shared example group #{name} was defined without a "\ + "block and will have no effect. Please define a "\ + "block or remove the definition." + end + + if RSpec.configuration.shared_context_metadata_behavior == :trigger_inclusion + return legacy_add(context, name, *metadata_args, &block) + end + + unless valid_name?(name) + raise ArgumentError, "Shared example group names can only be a string, " \ + "symbol or module but got: #{name.inspect}" + end + + ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line } + warn_if_key_taken context, name, block + + metadata = Metadata.build_hash_from(metadata_args) + shared_module = SharedExampleGroupModule.new(name, block, metadata) + shared_example_groups[context][name] = shared_module + end + + def find(lookup_contexts, name) + lookup_contexts.each do |context| + found = shared_example_groups[context][name] + return found if found + end + + shared_example_groups[:main][name] + end + + private + + # TODO: remove this in RSpec 4. This exists only to support + # `config.shared_context_metadata_behavior == :trigger_inclusion`, + # the legacy behavior of shared context metadata, which we do + # not want to support in RSpec 4. + def legacy_add(context, name, *metadata_args, &block) + ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line } + shared_module = SharedExampleGroupModule.new(name, block, {}) + + if valid_name?(name) + warn_if_key_taken context, name, block + shared_example_groups[context][name] = shared_module + else + metadata_args.unshift name + end + + return if metadata_args.empty? + RSpec.configuration.include shared_module, *metadata_args + end + + def shared_example_groups + @shared_example_groups ||= Hash.new { |hash, context| hash[context] = {} } + end + + def valid_name?(candidate) + case candidate + when String, Symbol, Module then true + else false + end + end + + def warn_if_key_taken(context, key, new_block) + existing_module = shared_example_groups[context][key] + return unless existing_module + + old_definition_location = formatted_location existing_module.definition + new_definition_location = formatted_location new_block + loaded_spec_files = RSpec.configuration.loaded_spec_files + + if loaded_spec_files.include?(new_definition_location) && old_definition_location == new_definition_location + RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil + |WARNING: Your shared example group, '#{key}', defined at: + | #{old_definition_location} + |was automatically loaded by RSpec because the file name + |matches the configured autoloading pattern (#{RSpec.configuration.pattern}), + |and is also being required from somewhere else. To fix this + |warning, either rename the file to not match the pattern, or + |do not explicitly require the file. + WARNING + else + RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil + |WARNING: Shared example group '#{key}' has been previously defined at: + | #{old_definition_location} + |...and you are now defining it at: + | #{new_definition_location} + |The new definition will overwrite the original one. + WARNING + end + end + + if RUBY_VERSION.to_f >= 1.9 + def formatted_location(block) + block.source_location.join(":") + end + else # 1.8.7 + # :nocov: + def formatted_location(block) + block.source_location.join(":").gsub(/:in.*$/, '') + end + # :nocov: + end + + if Proc.method_defined?(:source_location) + def ensure_block_has_source_location(_block); end + else # for 1.8.7 + # :nocov: + def ensure_block_has_source_location(block) + source_location = yield.split(':') + block.extend(Module.new { define_method(:source_location) { source_location } }) + end + # :nocov: + end + end + end + end + + instance_exec(&Core::SharedExampleGroup::TopLevelDSL.definitions) +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb new file mode 100644 index 0000000..a92feae --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb @@ -0,0 +1,49 @@ +module RSpec + module Core + # @private + # Deals with the fact that `shellwords` only works on POSIX systems. + module ShellEscape + module_function + + def quote(argument) + "'#{argument.to_s.gsub("'", "\\\\'")}'" + end + + if RSpec::Support::OS.windows? + # :nocov: + alias escape quote + # :nocov: + else + require 'shellwords' + + def escape(shell_command) + Shellwords.escape(shell_command.to_s) + end + end + + # Known shells that require quoting: zsh, csh, tcsh. + # + # Feel free to add other shells to this list that are known to + # allow `rspec ./some_spec.rb[1:1]` syntax without quoting the id. + # + # @private + SHELLS_ALLOWING_UNQUOTED_IDS = %w[ bash ksh fish ] + + def conditionally_quote(id) + return id if shell_allows_unquoted_ids? + quote(id) + end + + def shell_allows_unquoted_ids? + # Note: ENV['SHELL'] isn't necessarily the shell the user is currently running. + # According to http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html: + # "This variable shall represent a pathname of the user's preferred command language interpreter." + # + # It's the best we can easily do, though. We err on the side of safety (quoting + # the id when not actually needed) so it's not a big deal if the user is actually + # using a different shell. + SHELLS_ALLOWING_UNQUOTED_IDS.include?(ENV['SHELL'].to_s.split('/').last) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb new file mode 100644 index 0000000..d84ecb1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb @@ -0,0 +1,30 @@ +require 'test/unit/assertions' + +module RSpec + module Core + # @private + module TestUnitAssertionsAdapter + include ::Test::Unit::Assertions + + # If using test/unit from Ruby core with Ruby 1.9+, it includes + # MiniTest::Assertions by default. Note the upcasing of 'Test'. + # + # If the test/unit gem is being loaded, it will not include any minitest + # assertions. + # + # Only if Minitest 5.x is included / loaded do we need to worry about + # adding a shim for the new updates. Thus instead of checking on the + # RUBY_VERSION we need to check ancestors. + begin + # MiniTest is 4.x. + # Minitest is 5.x. + if ancestors.include?(::Minitest::Assertions) + require 'rspec/core/minitest_assertions_adapter' + include ::RSpec::Core::MinitestAssertionsAdapter + end + rescue NameError + # No-op. Minitest 5.x was not loaded. + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb new file mode 100644 index 0000000..ad4edc4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb @@ -0,0 +1,9 @@ +module RSpec + module Core + # Version information for RSpec Core. + module Version + # Current version of RSpec Core, in semantic versioning format. + STRING = '3.13.6' + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb new file mode 100644 index 0000000..b880059 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb @@ -0,0 +1,40 @@ +require "rspec/support/warnings" + +module RSpec + module Core + # @private + module Warnings + # @private + # + # Used internally to print deprecation warnings. + def deprecate(deprecated, data={}) + RSpec.configuration.reporter.deprecation( + { + :deprecated => deprecated, + :call_site => CallerFilter.first_non_rspec_line + }.merge(data) + ) + end + + # @private + # + # Used internally to print deprecation warnings. + def warn_deprecation(message, opts={}) + RSpec.configuration.reporter.deprecation opts.merge(:message => message) + end + + # @private + def warn_with(message, options={}) + if options[:use_spec_location_as_call_site] + message += "." unless message.end_with?(".") + + if RSpec.current_example + message += " Warning generated from spec at `#{RSpec.current_example.location}`." + end + end + + super(message, options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb new file mode 100644 index 0000000..20be84e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb @@ -0,0 +1,287 @@ +module RSpec + module Core + # @api private + # + # Internal container for global non-configuration data. + class World + # @private + attr_reader :example_groups, :filtered_examples, :example_group_counts_by_spec_file + + # Used internally to determine what to do when a SIGINT is received. + attr_accessor :wants_to_quit + + # Used internally to signify that a SystemExit occurred in + # `Configuration#load_file_handling_errors`, and thus examples cannot + # be counted accurately. Specifically, we cannot accurately report + # "No examples found". + # @private + attr_accessor :rspec_is_quitting + + # Used internally to signal that a failure outside of an example + # has occurred, and that therefore the exit status should indicate + # the run failed. + # @private + attr_accessor :non_example_failure + + def initialize(configuration=RSpec.configuration) + @wants_to_quit = false + @rspec_is_quitting = false + @configuration = configuration + configuration.world = self + @example_groups = [] + @example_group_counts_by_spec_file = Hash.new(0) + prepare_example_filtering + end + + # @api public + # + # Prepares filters so that they apply to example groups when they run. + # + # This is a separate method so that filters can be modified/replaced and + # examples refiltered during a process's lifetime, which can be useful for + # a custom runner. + def prepare_example_filtering + @filtered_examples = Hash.new do |hash, group| + hash[group] = filter_manager.prune(group.examples) + end + end + + # @api private + # + # Apply ordering strategy from configuration to example groups. + def ordered_example_groups + ordering_strategy = @configuration.ordering_registry.fetch(:global) + ordering_strategy.order(@example_groups) + end + + # @api private + # + # Reset world to 'scratch' before running suite. + def reset + RSpec::ExampleGroups.remove_all_constants + example_groups.clear + @sources_by_path.clear if defined?(@sources_by_path) + @syntax_highlighter = nil + @example_group_counts_by_spec_file = Hash.new(0) + end + + # @private + def filter_manager + @configuration.filter_manager + end + + # @private + def registered_example_group_files + @example_group_counts_by_spec_file.keys + end + + # @api private + # + # Records an example group. + def record(example_group) + @configuration.on_example_group_definition_callbacks.each { |block| block.call(example_group) } + @example_group_counts_by_spec_file[example_group.metadata[:absolute_file_path]] += 1 + end + + # @private + def num_example_groups_defined_in(file) + @example_group_counts_by_spec_file[file] + end + + # @private + def shared_example_group_registry + @shared_example_group_registry ||= SharedExampleGroup::Registry.new + end + + # @private + def inclusion_filter + @configuration.inclusion_filter + end + + # @private + def exclusion_filter + @configuration.exclusion_filter + end + + # @api private + # + # Get count of examples to be run. + def example_count(groups=example_groups) + FlatMap.flat_map(groups) { |g| g.descendants }. + inject(0) { |a, e| a + e.filtered_examples.size } + end + + # @private + def all_example_groups + FlatMap.flat_map(example_groups) { |g| g.descendants } + end + + # @private + def all_examples + FlatMap.flat_map(all_example_groups) { |g| g.examples } + end + + # @private + # Traverses the tree of each top level group. + # For each it yields the group, then the children, recursively. + # Halts the traversal of a branch of the tree as soon as the passed block returns true. + # Note that siblings groups and their sub-trees will continue to be explored. + # This is intended to make it easy to find the top-most group that satisfies some + # condition. + def traverse_example_group_trees_until(&block) + example_groups.each do |group| + group.traverse_tree_until(&block) + end + end + + # @api private + # + # Find line number of previous declaration. + def preceding_declaration_line(absolute_file_name, filter_line) + line_numbers = descending_declaration_line_numbers_by_file.fetch(absolute_file_name) do + return nil + end + + line_numbers.find { |num| num <= filter_line } + end + + # @private + def reporter + @configuration.reporter + end + + # @private + def source_from_file(path) + unless defined?(@sources_by_path) + RSpec::Support.require_rspec_support 'source' + @sources_by_path = {} + end + + @sources_by_path[path] ||= Support::Source.from_file(path) + end + + # @private + def syntax_highlighter + @syntax_highlighter ||= Formatters::SyntaxHighlighter.new(@configuration) + end + + # @api private + # + # Notify reporter of filters. + def announce_filters + fail_if_config_and_cli_options_invalid + filter_announcements = [] + + announce_inclusion_filter filter_announcements + announce_exclusion_filter filter_announcements + + unless filter_manager.empty? + if filter_announcements.length == 1 + report_filter_message("Run options: #{filter_announcements[0]}") + else + report_filter_message("Run options:\n #{filter_announcements.join("\n ")}") + end + end + + if @configuration.run_all_when_everything_filtered? && example_count.zero? && !@configuration.only_failures? + report_filter_message("#{everything_filtered_message}; ignoring #{inclusion_filter.description}") + filtered_examples.clear + inclusion_filter.clear + end + + return unless example_count.zero? + + example_groups.clear + unless rspec_is_quitting + if filter_manager.empty? + report_filter_message("No examples found.") + elsif exclusion_filter.empty? || inclusion_filter.empty? + report_filter_message(everything_filtered_message) + end + end + end + + # @private + def report_filter_message(message) + reporter.message(message) unless @configuration.silence_filter_announcements? + end + + # @private + def everything_filtered_message + "\nAll examples were filtered out" + end + + # @api private + # + # Add inclusion filters to announcement message. + def announce_inclusion_filter(announcements) + return if inclusion_filter.empty? + + announcements << "include #{inclusion_filter.description}" + end + + # @api private + # + # Add exclusion filters to announcement message. + def announce_exclusion_filter(announcements) + return if exclusion_filter.empty? + + announcements << "exclude #{exclusion_filter.description}" + end + + private + + def descending_declaration_line_numbers_by_file + @descending_declaration_line_numbers_by_file ||= begin + declaration_locations = FlatMap.flat_map(example_groups, &:declaration_locations) + hash_of_arrays = Hash.new { |h, k| h[k] = [] } + + # TODO: change `inject` to `each_with_object` when we drop 1.8.7 support. + line_nums_by_file = declaration_locations.inject(hash_of_arrays) do |hash, (file_name, line_number)| + hash[file_name] << line_number + hash + end + + line_nums_by_file.each_value do |list| + list.sort! + list.reverse! + end + end + end + + def fail_if_config_and_cli_options_invalid + return unless @configuration.only_failures_but_not_configured? + + reporter.abort_with( + "\nTo use `--only-failures`, you must first set " \ + "`config.example_status_persistence_file_path`.", + 1 # exit code + ) + end + + # @private + # Provides a null implementation for initial use by configuration. + module Null + def self.non_example_failure; end + def self.non_example_failure=(_); end + + def self.registered_example_group_files + [] + end + + def self.traverse_example_group_trees_until(&_block) + end + + # :nocov: + def self.example_groups + [] + end + + def self.all_example_groups + [] + end + # :nocov: + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document new file mode 100644 index 0000000..52a564f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +- +README.md +LICENSE.md +Changelog.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts new file mode 100644 index 0000000..9555b8e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts @@ -0,0 +1,6 @@ +--exclude features +--no-private +--markup markdown +- +Changelog.md +LICENSE.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md new file mode 100644 index 0000000..fc7d5f0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md @@ -0,0 +1,1366 @@ +### Development +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.4...3-13-maintenance) + +### 3.13.5 / 2025-05-27 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.4...rspec-expectations-v3.13.5) + +Bug Fixes: + +* Fix links in gemspec to point to the monorepo / homepage. + +### 3.13.4 / 2025-05-01 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.3...rspec-expectations-v3.13.4) + +Bug Fixes: + +* Prevent `match` from trying to compare strings and arrays using `Array#match`. (Joseph Haig, rspec/rspec#183) + +### 3.13.3 / 2024-09-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.2...v3.13.3) + +Bug Fixes: + +* Fix passing a regular expression to the `include` matcher without a count constraint. + (Jon Rowe, rspec/rspec-expectations#1485) + +### 3.13.2 / 2024-08-20 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.1...v3.13.2) + +Bug Fixes: + +* When using null object doubles, prevent typos triggering dynamic matchers. + (Eric Mueller, rspec/rspec-expectations#1455) +* Use `RSpec.warning` for an expectation warning rather than `Kernel.warn`. (Jon Rowe, rspec/rspec-expectations#1472) +* Prevent mismatched use of block and value matchers in compound expectations. (Phil Pirozhkov, rspec/rspec-expectations#1476) +* Raise an error when passing no arguments to the `include` matcher. (Eric Mueller, rspec/rspec-expectations#1479) + +### 3.13.1 / 2024-06-13 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.0...v3.13.1) + +Bug Fixes: + +* Fix the "false positive" warning message when using a negated `raise_error` matcher + with a `RegExp` instance. (Eric Mueller, rspec/rspec-expectations#1456) + +### 3.13.0 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.4...v3.13.0) + +Enhancements: + +* Update `eq` and `eql` matchers to better highlight difference in string encoding. + (Alan Foster, rspec/rspec-expectations#1425) + +### 3.12.4 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.3...v3.12.4) + +Bug Fixes: + +* Fix the diff for redefined `actual` and reassigned `@actual` in compound + expectations failure messages. (Phil Pirozhkov, rspec/rspec-expectations#1440) + +### 3.12.3 / 2023-04-20 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.2...v3.12.3) + +Bug Fixes: + +* Fix `include` matcher when fuzzy matching on keys with a hash-like actual which + has a non standard `key?` method which may raise. + (Jon Rowe, rspec/rspec-expectations#1416) + +### 3.12.2 / 2023-01-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.1...v3.12.2) + +Bug Fixes: + +* Prevent deprecation warning when using the `exist` matcher with `Dir`. + (Steve Dierker, rspec/rspec-expectations#1398) + +### 3.12.1 / 2022-12-16 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.0...v3.12.1) + +Bug Fixes: + +* Pass keyword arguments through to aliased (and thus negated) matchers. (Jon Rowe, rspec/rspec-expectations#1394) +* When handling failures in an aggregated_failures block (or example) prevent + the failure list leaking out. (Maciek Rząsa, rspec/rspec-expectations#1392) + +### 3.12.0 / 2022-10-26 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.1...v3.12.0) + +Enhancements: + +* Add `an_array_matching` alias for `match_array` to improve readability as an argument + matcher. (Mark Schneider, rspec/rspec-expectations#1361) + +### 3.11.1 / 2022-09-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.0...v3.11.1) + +Bug Fixes: + +* Allow the `contain_exactly` matcher to be reused by resetting its + internals on `matches?` (@bclayman-sq, rspec/rspec-expectations#1326) +* Using the exist matcher on `FileTest` no longer produces a deprecation warning. + (Ryo Nakamura, rspec/rspec-expectations#1383) + +### 3.11.0 / 2022-02-09 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.2...v3.11.0) + +Enhancements: + +* Return `true` from `aggregate_failures` when no exception occurs. (Jon Rowe, rspec/rspec-expectations#1225) + +Deprecations: + +* Print a deprecation message when using the implicit block expectation syntax. + (Phil Pirozhkov, rspec/rspec-expectations#1139) + +### 3.10.2 / 2022-01-14 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.1...v3.10.2) + +Bug Fixes: + +* Fix support for dynamic matchers for expectation target checks (Phil Pirozhkov, rspec/rspec-expectations#1294) +* Fix `expect(array).to include(hash).times`, previously this would fail due to + matching the entire array as a single hash, rather than a member of the hash. + (Slava Kardakov, rspec/rspec-expectations#1322) +* Ensure `raise_error` matches works with the `error_highlight` option from Ruby 3.1. + (Peter Goldstein, rspec/rspec-expectations#1339) + +### 3.10.1 / 2020-12-27 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.0...v3.10.1) + +Bug Fixes: + +* Allow JRuby 9.2.x.x to generate backtraces normally rather than via our + backfill workaround. (rspec/rspec-expectations#1230, Jon Rowe) + +### 3.10.0 / 2020-10-30 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.10.0) + +Enhancements: + +* Allow `include` matcher to be chained with `once`, `at_least`, etc. for simple cases. + (Marc-André Lafortune, rspec/rspec-expectations#1168) +* Add an explicit warning when `nil` is passed to `raise_error`. (Phil Pirozhkov, rspec/rspec-expectations#1143) +* Improve `include` matcher's composability. (Phil Pirozhkov, rspec/rspec-expectations#1155) +* Mocks expectations can now set a custom failure message. + (Benoit Tigeot and Nicolas Zermati, rspec/rspec-expectations#1156) +* `aggregate_failures` now shows the backtrace line for each failure. (Fabricio Bedin, rspec/rspec-expectations#1163) +* Support multiple combinations of `yield_control` modifiers like `at_least`, `at_most`. + (Jon Rowe, rspec/rspec-expectations#1169) +* Dynamic `have_` matchers now have output consistent with other dynamic matchers. + (Marc-André Lafortune, rspec/rspec-expectations#1195) +* New config option `strict_predicate_matchers` allows predicate matcher to be strict + (i.e. match for `true` or `false`) instead of the default (match truthy vs `false` or `nil`). + (Marc-André Lafortune, rspec/rspec-expectations#1196) + +### 3.9.4 / 2020-10-29 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.9.4) + +Bug Fixes: + +* Fix regression with `be_` and `have_` matchers and arguments implementing `to_hash` + were they would act like keywords and be cast to a hash. (Jon Rowe, rspec/rspec-expectations#1222) + +### 3.9.3 / 2020-10-23 + +Bug Fixes: + +* Swap the comparison of the delta vs the expected for the `be_within` matcher allowing + more complicated oobjects to be compared providing they provide `abs` and other + comparison methods. (Kelly Stannard, rspec/rspec-expectations#1182) +* Properly format expected in the description of the `be_within` matcher. (Jon Rowe, rspec/rspec-expectations#1185) +* Remove warning when using keyword arguments with `be_` and `have_` matchers on 2.7.x + (Jon Rowe, rspec/rspec-expectations#1187) +* Prevent formatting a single hash as a list of key value pairs in default failure messages + for custom matches (fixes formatting in `EnglishPhrasing#list`). (Robert Eshleman, rspec/rspec-expectations#1193) +* Prevent errors from causing false positives when using `be ` comparison, e.g. + `expect(1).not_to be < 'a'` will now correctly fail rather than pass. (Jon Rowe, rspec/rspec-expectations#1208) + + +### 3.9.2 / 2020-05-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.1...v3.9.2) + +Bug Fixes: + +* Issue a proper `ArgumentError` when invalid arguments are given to `yield_control` + modifiers such as `at_least` et al. (Marc-André Lafortune, rspec/rspec-expectations#1167) +* Prevent Ruby 2.7 keyword arguments warning from being issued by custom + matcher definitions. (Jon Rowe, rspec/rspec-expectations#1176) + +### 3.9.1 / 2020-03-13 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.0...v3.9.1) + +Bug Fixes: + +* Issue an improved warning when using `respond_to(...).with(n).arguments` and ignore + the warning when using with `have_attributes(...)`. (Jon Rowe, rspec/rspec-expectations#1164) + +### 3.9.0 / 2019-10-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.6...v3.9.0) + +Enhancements: + +* The `respond_to` matcher now uses the signature from `initialize` to validate checks + for `new` (unless `new` is non standard). (Jon Rowe, rspec/rspec-expectations#1072) +* Generated descriptions for matchers now use `is expected to` rather than `should` in + line with our preferred DSL. (Pete Johns, rspec/rspec-expectations#1080, rspec/rspec-corerspec/rspec-expectations#2572) +* Add the ability to re-raise expectation errors when matching + with `match_when_negated` blocks. (Jon Rowe, rspec/rspec-expectations#1130) +* Add a warning when an empty diff is produce due to identical inspect output. + (Benoit Tigeot, rspec/rspec-expectations#1126) + +### 3.8.6 / 2019-10-07 + +Bug Fixes: + +* Revert rspec/rspec-expectations#1125 due to the change being incompatible with our semantic versioning + policy. + +### 3.8.5 / 2019-10-02 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.4...v3.8.5) + +Bug Fixes: + +* Prevent unsupported implicit block expectation syntax from being used. + (Phil Pirozhkov, rspec/rspec-expectations#1125) + +### 3.8.4 / 2019-06-10 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.3...v3.8.4) + +Bug Fixes: + +* Prevent false negatives when checking objects for the methods required to run the + the `be_an_instance_of` and `be_kind_of` matchers. (Nazar Matus, rspec/rspec-expectations#1112) + +### 3.8.3 / 2019-04-20 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.2...v3.8.3) + +Bug Fixes: + +* Prevent composed `all` matchers from leaking into their siblings leading to duplicate + failures. (Jamie English, rspec/rspec-expectations#1086) +* Prevent objects which change their hash on comparison from failing change checks. + (Phil Pirozhkov, rspec/rspec-expectations#1100) +* Issue an `ArgumentError` rather than a `NoMethodError` when `be_an_instance_of` and + `be_kind_of` matchers encounter objects not supporting those methods. + (Taichi Ishitani, rspec/rspec-expectations#1107) + +### 3.8.2 / 2018-10-09 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.1...v3.8.2) + +Bug Fixes: + +* Change `include` matcher to rely on a `respond_to?(:include?)` check rather than a direct + Hash comparison before calling `to_hash` to convert to a hash. (Jordan Owens, rspec/rspec-expectations#1073) +* Prevent unexpected call stack jumps from causing an obscure error (`IndexError`), and + replace that error with a proper informative message. (Jon Rowe, rspec/rspec-expectations#1076) + +### 3.8.1 / 2018-08-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.0...v3.8.1) + +Bug Fixes: + +* Fix regression in `include` matcher so stopped + `expect(hash.with_indifferent_access).to include(:symbol_key)` + from working. (Eito Katagiri, rspec/rspec-expectations#1069) + +### 3.8.0 / 2018-08-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.7.0...v3.8.0) + +Enhancements: + +* Improve failure message of `change(receiver, :message)` by including the + receiver as `SomeClass#some_message`. (Tomohiro Hashidate, rspec/rspec-expectations#1005) +* Improve `change` matcher so that it can correctly detect changes in + deeply nested mutable objects (such as arrays-of-hashes-of-arrays). + The improved logic uses the before/after `hash` value to see if the + object has been mutated, rather than shallow duping the object. + (Myron Marston, rspec/rspec-expectations#1034) +* Improve `include` matcher so that pseudo-hash objects (e.g. objects + that decorate a hash using a `SimpleDelegator` or similar) are treated + as a hash, as long as they implement `to_hash`. (Pablo Brasero, rspec/rspec-expectations#1012) +* Add `max_formatted_output_length=` to configuration, allowing changing + the length at which we truncate large output strings. + (Sam Phippen rspec/rspec-expectations#951, Benoit Tigeot rspec/rspec-expectations#1056) +* Improve error message when passing a matcher that doesn't support block + expectations to a block based `expect`. (@nicktime, rspec/rspec-expectations#1066) + +### 3.7.0 / 2017-10-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0...v3.7.0) + +Enhancements: + +* Improve compatibility with `--enable-frozen-string-literal` option + on Ruby 2.3+. (Pat Allan, rspec/rspec-expectations#997) + +### 3.6.0 / 2017-05-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0.beta2...v3.6.0) + +Enhancements: + +* Treat NoMethodError as a failure for comparison matchers. (Jon Rowe, rspec/rspec-expectations#972) +* Allow for scoped aliased and negated matchers--just call + `alias_matcher` or `define_negated_matcher` from within an example + group. (Markus Reiter, rspec/rspec-expectations#974) +* Improve failure message of `change` matcher with block and `satisfy` matcher + by including the block snippet instead of just describing it as `result` or + `block` when Ripper is available. (Yuji Nakayama, rspec/rspec-expectations#987) + +Bug Fixes: + +* Fix `yield_with_args` and `yield_successive_args` matchers so that + they compare expected to actual args at the time the args are yielded + instead of at the end, in case the method that is yielding mutates the + arguments after yielding. (Alyssa Ross, rspec/rspec-expectations#965) + +### 3.6.0.beta2 / 2016-12-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0.beta1...v3.6.0.beta2) + +Bug Fixes: + +* Using the exist matcher on `File` no longer produces a deprecation warning. + (Jon Rowe, rspec/rspec-expectations#954) + +### 3.6.0.beta1 / 2016-10-09 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0...v3.6.0.beta1) + +Bug Fixes: + +* Fix `contain_exactly` to work correctly with ranges. (Myron Marston, rspec/rspec-expectations#940) +* Fix `change` to work correctly with sets. (Marcin Gajewski, rspec/rspec-expectations#939) + +### 3.5.0 / 2016-07-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta4...v3.5.0) + +Enhancements: + +* Add support for keyword arguments to the `respond_to` matcher. (Rob Smith, rspec/rspec-expectations#915). + +### 3.5.0.beta4 / 2016-06-05 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta3...v3.5.0.beta4) + +Bug Fixes: + +* Fix `include` matcher so that it provides a valid diff for hashes. (Yuji Nakayama, rspec/rspec-expectations#916) + +### 3.5.0.beta3 / 2016-04-02 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta2...v3.5.0.beta3) + +Enhancements: + +* Make `rspec/expectations/minitest_integration` work on Minitest::Spec + 5.6+. (Myron Marston, rspec/rspec-expectations#904) +* Add an alias `having_attributes` for `have_attributes` matcher. + (Yuji Nakayama, rspec/rspec-expectations#905) +* Improve `change` matcher error message when block is mis-used. + (Alex Altair, rspec/rspec-expectations#908) + +### 3.5.0.beta2 / 2016-03-10 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta1...v3.5.0.beta2) + +Enhancements: + +* Add the ability to raise an error on encountering false positives via + `RSpec::Configuration#on_potential_false_positives = :raise`. (Jon Rowe, rspec/rspec-expectations#900) +* When using the custom matcher DSL, support new + `notify_expectation_failures: true` option for the `match` method to + allow expectation failures to be raised as normal instead of being + converted into a `false` return value for `matches?`. (Jon Rowe, rspec/rspec-expectations#892) + +Bug Fixes: + +* Allow `should` deprecation check to work on `BasicObject`s. (James Coleman, rspec/rspec-expectations#898) + +### 3.5.0.beta1 / 2016-02-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.4.0...v3.5.0.beta1) + +Enhancements: + +* Make `match_when_negated` in custom matcher DSL support use of + expectations within the match logic. (Chris Arcand, rspec/rspec-expectations#789) + +Bug Fixes: + +* Return `true` as expected from passing negated expectations + (such as `expect("foo").not_to eq "bar"`), so they work + properly when used within a `match` or `match_when_negated` + block. (Chris Arcand, rspec/rspec-expectations#789) + +### 3.4.0 / 2015-11-11 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.3.1...v3.4.0) + +Enhancements: + +* Warn when `RSpec::Matchers` is included in a superclass after it has + already been included in a subclass on MRI 1.9, since that situation + can cause uses of `super` to trigger infinite recursion. (Myron Marston, rspec/rspec-expectations#816) +* Stop rescuing `NoMemoryError`, `SignalExcepetion`, `Interrupt` and + `SystemExit`. It is dangerous to interfere with these. (Myron Marston, rspec/rspec-expectations#845) +* Add `#with_captures` to the match matcher which allows a user to specify expected + captures when matching a regex against a string. (Sam Phippen, rspec/rspec-expectations#848) +* Always print compound failure messages in the multi-line form. Trying + to print it all on a single line didn't read very well. (Myron Marston, rspec/rspec-expectations#859) + +Bug Fixes: + +* Fix failure message from dynamic predicate matchers when the object + does not respond to the predicate so that it is inspected rather + than relying upon its `to_s` -- that way for `nil`, `"nil"` is + printed rather than an empty string. (Myron Marston, rspec/rspec-expectations#841) +* Fix SystemStackError raised when diffing an Enumerable object + whose `#each` includes the object itself. (Yuji Nakayama, rspec/rspec-expectations#857) + +### 3.3.1 / 2015-07-15 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.3.0...v3.3.1) + +Bug Fixes: + +* Fix `be >`, `be <`, etc so that it fails rather than allowing an + argument error to be raised when compared against an object of the + wrong type. This allows it to be used in composed matcher expressions + against heterogeneous objects. (Dennis Günnewig, rspec/rspec-expectations#809) +* Fix `respond_to` to work properly on target objects + that redefine the `method` method. (unmanbearpig, rspec/rspec-expectations#821) + +### 3.3.0 / 2015-06-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.2.1...v3.3.0) + +Enhancements: + +* Expose `RSpec::Matchers::EnglishPhrasing` to make it easier to write + nice failure messages in custom matchers. (Jared Beck, rspec/rspec-expectations#736) +* Add `RSpec::Matchers::FailMatchers`, a mixin which provides + `fail`, `fail_with` and `fail_including` matchers for use in + specifying that an expectation fails for use by + extension/plugin authors. (Charlie Rudolph, rspec/rspec-expectations#729) +* Avoid loading `tempfile` (and its dependencies) unless + it is absolutely needed. (Myron Marston, rspec/rspec-expectations#735) +* Improve failure output when attempting to use `be_true` or `be_false`. + (Tim Wade, rspec/rspec-expectations#744) +* Define `RSpec::Matchers#respond_to_missing?` so that + `RSpec::Matchers#respond_to?` and `RSpec::Matchers#method` handle + dynamic predicate matchers. (Andrei Botalov, rspec/rspec-expectations#751) +* Use custom Time/DateTime/BigDecimal formatting for all matchers + so they are consistently represented in failure messages. + (Gavin Miller, rspec/rspec-expectations#740) +* Add configuration to turn off warnings about matcher combinations that + may cause false positives. (Jon Rowe, rspec/rspec-expectations#768) +* Warn when using a bare `raise_error` matcher that you may be subject to + false positives. (Jon Rowe, rspec/rspec-expectations#768) +* Warn rather than raise when using the`raise_error` matcher in negative + expectations that may be subject to false positives. (Jon Rowe, rspec/rspec-expectations#775) +* Improve failure message for `include(a, b, c)` so that if `a` and `b` + are included the failure message only mentions `c`. (Chris Arcand, rspec/rspec-expectations#780) +* Allow `satisfy` matcher to take an optional description argument + that will be used in the `description`, `failure_message` and + `failure_message_when_negated` in place of the undescriptive + "sastify block". (Chris Arcand, rspec/rspec-expectations#783) +* Add new `aggregate_failures` API that allows multiple independent + expectations to all fail and be listed in the failure output, rather + than the example aborting on the first failure. (Myron Marston, rspec/rspec-expectations#776) +* Improve `raise_error` matcher so that it can accept a matcher as a single argument + that matches the message. (Time Wade, rspec/rspec-expectations#782) + +Bug Fixes: + +* Make `contain_exactly` / `match_array` work with strict test doubles + that have not defined `<=>`. (Myron Marston, rspec/rspec-expectations#758) +* Fix `include` matcher so that it omits the diff when it would + confusingly highlight items that are actually included but are not + an exact match in a line-by-line diff. (Tim Wade, rspec/rspec-expectations#763) +* Fix `match` matcher so that it does not blow up when matching a string + or regex against another matcher (rather than a string or regex). + (Myron Marston, rspec/rspec-expectations#772) +* Silence whitespace-only diffs. (Myron Marston, rspec/rspec-expectations#801) + +### 3.2.1 / 2015-04-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.2.0...v3.2.1) + +Bug Fixes: + +* Prevent `Range`s from being enumerated when generating matcher + descriptions. (Jon Rowe, rspec/rspec-expectations#755) +* Ensure exception messages are compared as strings in the `raise_error` + matcher. (Jon Rowe, rspec/rspec-expectations#755) + +### 3.2.0 / 2015-02-03 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.2...v3.2.0) + +Enhancements: + +* Add `block_arg` method to custom matcher API, which allows you to + access the block passed to a custom matcher, if there is one. + (Mike Dalton, rspec/rspec-expectations#645) +* Provide more detail in failure message of `yield_control` matcher. + (Jon Rowe, rspec/rspec-expectations#650) +* Add a shorthand syntax for `chain` in the matcher DSL which assigns values + for use elsewhere, for example `chain :and_smaller_than, :small_value` + creates an `attr_reader` for `small_value` (Tom Stuart, rspec/rspec-expectations#644) +* Provide a more helpful deprecation message when using the `should` syntax. + (Elia Schito, rspec/rspec-expectations#663) +* Provide more detail in the `have_attributes` matcher failure message. + (Jon Rowe, rspec/rspec-expectations#668) +* Make the `have_attributes` matcher diffable. + (Jon Rowe, Alexey Fedorov, rspec/rspec-expectations#668) +* Add `output(...).to_std(out|err)_from_any_process` as alternatives + to `output(...).to_std(out|err)`. The latter doesn't work when a sub + process writes to the named stream but is much faster. + (Alex Genco, rspec/rspec-expectations#700) +* Improve compound matchers (created by `and` and `or`) so that diffs + are included in failures when one or more of their matchers + are diffable. (Alexey Fedorov, rspec/rspec-expectations#713) + +Bug Fixes: + +* Avoid calling `private_methods` from the `be` predicate matcher on + the target object if the object publicly responds to the predicate + method. This avoids a possible error that can occur if the object + raises errors from `private_methods` (which can happen with celluloid + objects). (@chapmajs, rspec/rspec-expectations#670) +* Make `yield_control` (with no modifier) default to + `at_least(:once)` rather than raising a confusing error + when multiple yields are encountered. + (Myron Marston, rspec/rspec-expectations#675) +* Fix "instance variable @color not initialized" warning when using + rspec-expectations outside of an rspec-core context. (Myron Marston, rspec/rspec-expectations#689) +* Fix `start_with` and `end_with` to work properly when checking a + string against an array of strings. (Myron Marston, rspec/rspec-expectations#690) +* Don't use internally delegated matchers when generating descriptions + for examples without doc strings. (Myron Marston, rspec/rspec-expectations#692) + +### 3.1.2 / 2014-09-26 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.1...v3.1.2) + +Bug Fixes: + +* Fix `define_negated_matcher` so that matchers that support fluent + interfaces continue to be negated after you use the chained method. + (Myron Marston, rspec/rspec-expectations#656) +* Fix `define_negated_matcher` so that the matchers fail with an + appropriate failure message. (Myron Marston, rspec/rspec-expectations#659) + +### 3.1.1 / 2014-09-15 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.0...v3.1.1) + +Bug Fixes: + +* Fix regression in `all` matcher in 3.1.0 that prevented it from + working on objects that are not `Enumerable` but do implement + `each_with_index` (such as an ActiveRecord proxy). (Jori Hardman, rspec/rspec-expectations#647) + +### 3.1.0 / 2014-09-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.4...v3.1.0) + +Enhancements: + +* Add `have_attributes` matcher, that passes if actual's attribute + values match the expected attributes hash: + `Person = Struct.new(:name, :age)` + `person = Person.new("Bob", 32)` + `expect(person).to have_attributes(:name => "Bob", :age => 32)`. + (Adam Farhi, rspec/rspec-expectations#571) +* Extended compound matcher support to block matchers, for cases like: + `expect { ... }.to change { x }.to(3).and change { y }.to(4)`. (Myron + Marston, rspec/rspec-expectations#567) +* Include chained methods in custom matcher description and failure message + when new `include_chain_clauses_in_custom_matcher_descriptions` config + option is enabled. (Dan Oved, rspec/rspec-expectations#600) +* Add `thrice` modifier to `yield_control` matcher as a synonym for + `exactly(3).times`. (Dennis Taylor, rspec/rspec-expectations#615) +* Add `RSpec::Matchers.define_negated_matcher`, which defines a negated + version of the named matcher. (Adam Farhi, Myron Marston, rspec/rspec-expectations#618) +* Document and support negation of `contain_exactly`/`match_array`. + (Jon Rowe, rspec/rspec-expectations#626). + +Bug Fixes: + +* Rename private `LegacyMacherAdapter` constant to `LegacyMatcherAdapter` + to fix typo. (Abdelkader Boudih, rspec/rspec-expectations#563) +* Fix `all` matcher so that it fails properly (rather than raising a + `NoMethodError`) when matched against a non-enumerable. (Hao Su, rspec/rspec-expectations#622) + +### 3.0.4 / 2014-08-14 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.3...v3.0.4) + +Bug Fixes: + +* Fix `start_with` and `end_with` so that they work properly with + structs. (Myron Marston, rspec/rspec-expectations#620) +* Fix failure message generation so that structs are printed properly + in failures. Previously failure messages would represent them as + an array. (Myron Marston, rspec/rspec-expectations#620) +* Fix composable matcher support so that it does not wrongly treat + structs as arrays. (Myron Marston, rspec/rspec-expectations#620) + +### 3.0.3 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.2...v3.0.3) + +Bug Fixes: + +* Fix issue with detection of generic operator matchers so they work + correctly when undefined. (Myron Marston, rspec/rspec-expectations#597) +* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, rspec/rspec-expectations#603) +* Fix `include` matcher so that it fails gracefully when matched against + an object that does not respond to `include?`. (Myron Marston, rspec/rspec-expectations#607) + +### 3.0.2 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.1...v3.0.2) + +Bug Fixes: + +* Fix regression in `contain_exactly` (AKA `match_array`) that caused it + to wrongly pass when the expected array was empty. (Myron Marston, rspec/rspec-expectations#581) +* Provide a better error message when you use the `change(obj, :msg)` + form of the change matcher but forget the message argument. (Alex + Sunderland, rspec/rspec-expectations#585) +* Make the `contain_exactly` matcher work with arrays that contain hashes in + arbitrary ordering. (Sam Phippen, rspec/rspec-expectations#578) + +### 3.0.1 / 2014-06-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0...v3.0.1) + +Bug Fixes: + +* Add a missing `require` that would cause the `respond_to` matcher to + fail when used in a project where the rest of RSpec (e.g. core and + expecatations) weren't being used. (Myron Marston, rspec/rspec-expectations#566) +* Structs are no longer treated as arrays when diffed. (Jon Rowe, rspec/rspec-expectations#576) + +### 3.0.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.rc1...v3.0.0) + +No code changes. Just taking it out of pre-release. + +### 3.0.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta2...v3.0.0.rc1) + +Breaking Changes for 3.0.0: + +* Remove `matcher_execution_context` attribute from DSL-defined + custom matchers. (Myron Marston) +* Remove `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston) +* Remove `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston) +* Rename `RSpec::Matchers::Configuration` constant to + `RSpec::Expectations::Configuration`. (Myron Marston) +* Prevent `have_xyz` predicate matchers using private methods. + (Adrian Gonzalez) +* Block matchers must now implement `supports_block_expectations?`. + (Myron Marston) +* Stop supporting `require 'rspec-expectations'`. + Use `require 'rspec/expectations'` instead. (Myron Marston) + +Bug Fixes: + +* Fix `NoMethodError` triggered by beta2 when `YARD` was loaded in + the test environment. (Myron Marston) +* Fix `be_xyz` matcher to accept a `do...end` block. (Myron Marston) +* Fix composable matcher failure message generation logic + so that it does not blow up when given `$stdout` or `$stderr`. + (Myron Marston) +* Fix `change` matcher to work properly with `IO` objects. + (Myron Marston) +* Fix `exist` matcher so that it can be used in composed matcher + expressions involving objects that do not implement `exist?` or + `exists?`. (Daniel Fone) +* Fix composable matcher match logic so that it clones matchers + before using them in order to work properly with matchers + that use internal memoization based on a given `actual` value. + (Myron Marston) +* Fix `be_xyz` and `has_xyz` predicate matchers so that they can + be used in composed matcher expressions involving objects that + do not implement the predicate method. (Daniel Fone) + +Enhancements: + +* Document the remaining public APIs. rspec-expectations now has 100% of + the public API documented and will remain that way (as new undocumented + methods will fail the build). (Myron Marston) +* Improve the formatting of BigDecimal objects in `eq` matcher failure + messages. (Daniel Fone) +* Improve the failure message for `be_xyz` predicate matchers so + that it includes the `inspect` output of the receiver. + (Erik Michaels-Ober, Sam Phippen) +* Add `all` matcher, to allow you to specify that a given matcher + matches all elements in a collection: + `expect([1, 3, 5]).to all( be_odd )`. (Adam Farhi) +* Add boolean aliases (`&`/`|`) for compound operators (`and`/`or`). (Adam Farhi) +* Give users a clear error when they wrongly use a value matcher + in a block expectation expression (e.g. `expect { 3 }.to eq(3)`) + or vice versa. (Myron Marston) + +### 3.0.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta1...v3.0.0.beta2) + +Breaking Changes for 3.0.0: + +* Remove deprecated support for accessing the `RSpec` constant using + `Rspec` or `Spec`. (Myron Marston) +* Remove deprecated `RSpec::Expectations.differ=`. (Myron Marston) +* Remove support for deprecated `expect(...).should`. (Myron Marston) +* Explicitly disallow `expect { }.not_to change { }` with `by`, + `by_at_least`, `by_at_most` or `to`. These have never been supported + but did not raise explicit errors. (Myron Marston) +* Provide `===` rather than `==` as an alias of `matches?` for + all matchers. The semantics of `===` are closer to an RSpec + matcher than `==`. (Myron Marston) +* Remove deprecated `RSpec::Matchers::OperatorMatcher` constant. + (Myron Marston) +* Make `RSpec::Expectations::ExpectationNotMetError` subclass + `Exception` rather than `StandardError` so they can bypass + a bare `rescue` in end-user code (e.g. when an expectation is + set from within a rspec-mocks stub implementation). (Myron Marston) +* Remove Test::Unit and Minitest 4.x integration. (Myron Marston) + +Enhancements: + +* Simplify the failure message of the `be` matcher when matching against: + `true`, `false` and `nil`. (Sam Phippen) +* Update matcher protocol and custom matcher DSL to better align + with the newer `expect` syntax. If you want your matchers to + maintain compatibility with multiple versions of RSpec, you can + alias the new names to the old. (Myron Marston) + * `failure_message_for_should` => `failure_message` + * `failure_message_for_should_not` => `failure_message_when_negated` + * `match_for_should` => `match` + * `match_for_should_not` => `match_when_negated` +* Improve generated descriptions from `change` matcher. (Myron Marston) +* Add support for compound matcher expressions using `and` and `or`. + Simply chain them off of any existing matcher to create an expression + like `expect(alphabet).to start_with("a").and end_with("z")`. + (Eloy Espinaco) +* Add `contain_exactly` as a less ambiguous version of `match_array`. + Note that it expects the expected array to be splatted as + individual args: `expect(array).to contain_exactly(1, 2)` is + the same as `expect(array).to match_array([1, 2])`. (Myron Marston) +* Update `contain_exactly`/`match_array` so that it can match against + other non-array collections (such as a `Set`). (Myron Marston) +* Update built-in matchers so that they can accept matchers as arguments + to allow you to compose matchers in arbitrary ways. (Myron Marston) +* Add `RSpec::Matchers::Composable` mixin that can be used to make + a custom matcher composable as well. Note that custom matchers + defined via `RSpec::Matchers.define` already have this. (Myron + Marston) +* Define noun-phrase aliases for built-in matchers, which can be + used when creating composed matcher expressions that read better + and provide better failure messages. (Myron Marston) +* Add `RSpec::Matchers.alias_matcher` so users can define their own + matcher aliases. The `description` of the matcher will reflect the + alternate matcher name. (Myron Marston) +* Add explicit `be_between` matcher. `be_between` has worked for a + long time as a dynamic predicate matcher, but the failure message + was suboptimal. The new matcher provides a much better failure + message. (Erik Michaels-Ober) +* Enhance the `be_between` matcher to allow for `inclusive` or `exclusive` + comparison (e.g. inclusive of min/max or exclusive of min/max). + (Pedro Gimenez) +* Make failure message for `not_to be #{operator}` less confusing by + only saying it's confusing when comparison operators are used. + (Prathamesh Sonpatki) +* Improve failure message of `eq` matcher when `Time` or `DateTime` + objects are used so that the full sub-second precision is included. + (Thomas Holmes, Jeff Wallace) +* Add `output` matcher for expecting that a block outputs `to_stdout` + or `to_stderr`. (Luca Pette, Matthias Günther) +* Forward a provided block on to the `has_xyz?` method call when + the `have_xyz` matcher is used. (Damian Galarza) +* Provide integration with Minitest 5.x. Require + `rspec/expectations/minitest_integration` after loading minitest + to use rspec-expectations with minitest. (Myron Marston) + +Bug Fixes: + +* Fix wrong matcher descriptions with falsey expected value (yujinakayama) +* Fix `expect { }.not_to change { }.from(x)` so that the matcher only + passes if the starting value is `x`. (Tyler Rick, Myron Marston) +* Fix hash diffing, so that it colorizes properly and doesn't consider trailing + commas when performing the diff. (Jared Norman) +* Fix built-in matchers to fail normally rather than raising + `ArgumentError` when given an object of the wrong type to match + against, so that they work well in composite matcher expressions like + `expect([1.51, "foo"]).to include(a_string_matching(/foo/), a_value_within(0.1).of(1.5))`. + (Myron Marston) + +Deprecations: + +* Retain support for RSpec 2 matcher protocol (e.g. for matchers + in 3rd party extension gems like `shoulda`), but it will print + a deprecation warning. (Myron Marston) + +### 3.0.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.2...v3.0.0.beta1) + +Breaking Changes for 3.0.0: + +* Remove explicit support for 1.8.6. (Jon Rowe) +* Remove the deprecated `be_close` matcher, preferring `be_within` instead. + (Sam Phippen) +* Remove the deprecated `have`, `have_at_least` and `have_at_most` matchers. + You can continue using those matchers through https://github.com/rspec/rspec-collection_matchers, + or you can rewrite your expectations with something like + `expect(your_object.size).to eq(num)`. (Hugo Baraúna) +* Rename `be_true` and `be_false` to `be_truthy` and `be_falsey`. (Sam Phippen) +* Make `expect { }.to_not raise_error(SomeSpecificClass, message)`, + `expect { }.to_not raise_error(SomeSpecificClass)` and + `expect { }.to_not raise_error(message)` invalid, since they are prone + to hiding failures. Instead, use `expect { }.to_not raise_error` (with no + args). (Sam Phippen) +* Within `RSpec::Matchers.define` blocks, helper methods made available + either via `def self.helper` or `extend HelperModule` are no longer + available to the `match` block (or any of the others). Instead + `include` your helper module and define the helper method as an + instance method. (Myron Marston) +* Force upgrading Diff::LCS for encoding compatability with diffs. (Jon Rowe) + +Enhancements: + +* Support `do..end` style block with `raise_error` matcher. (Yuji Nakayama) +* Rewrote custom matcher DSL to simplify its implementation and solve a + few issues. (Myron Marston) +* Allow early `return` from within custom matcher DSL blocks. (Myron + Marston) +* The custom matcher DSL's `chain` can now accept a block. (Myron + Marston) +* Support setting an expectation on a `raise_error` matcher via a chained + `with_message` method call. (Sam Phippen) + +Bug Fixes: + +* Allow `include` and `match` matchers to be used from within a + DSL-defined custom matcher's `match` block. (Myron Marston) +* Correct encoding error message on diff failure (Jon Rowe) + +Deprecations: + + * Using the old `:should` syntax without explicitly configuring it is deprecated. + It will continue to work but will emit a deprecation warning in RSpec 3 if + you do not explicitly enable it. (Sam Phippen) + +### 2.99.2 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.1...v2.99.2) + +Bug Fixes: + +* Fix regression in `Expectations#method_handle_for` where proxy objects + with method delegated would wrongly not return a method handle. + (Jon Rowe, rspec/rspec-expectations#594) +* Fix issue with detection of generic operator matchers so they work + correctly when undefined. (Myron Marston, rspec/rspec-expectations#597) + +### 2.99.1 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0...v2.99.1) + +Bug Fixes: + +* Fix typo in custom matcher `expected` deprecation warning -- it's + `expected_as_array`, not `expected_array`. (Frederick Cheung, rspec/rspec-expectations#562) + +### 2.99.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.rc1...v2.99.0) + +Enhancements: + +* Special case deprecation message for `errors_on` with `rspec-rails` to be more useful. + (Aaron Kromer) + +### 2.99.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta2...2.99.0.rc1) + +Deprecations: + +* Deprecate `matcher_execution_context` attribute on DSL-defined + custom matchers. (Myron Marston) +* Deprecate `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston) +* Deprecate `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston) +* Deprecate `RSpec::Matchers::Configuration` in favor of + `RSpec::Expectations::Configuration`. (Myron Marston) +* Deprecate `be_xyz` predicate matcher on an object that doesn't respond to + `xyz?` or `xyzs?`. (Daniel Fone) +* Deprecate `have_xyz` matcher on an object that doesn't respond to `has_xyz?`. + (Daniel Fone) +* Deprecate `have_xyz` matcher on an object that has a private method `has_xyz?`. + (Jon Rowe) +* Issue a deprecation warning when a block expectation expression is + used with a matcher that doesn't explicitly support block expectations + via `supports_block_expectations?`. (Myron Marston) +* Deprecate `require 'rspec-expectations'`. Use + `require 'rspec/expectations'` instead. (Myron Marston) + +### 2.99.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta1...v2.99.0.beta2) + +Deprecations: + +* Deprecate chaining `by`, `by_at_least`, `by_at_most` or `to` off of + `expect { }.not_to change { }`. The docs have always said these are + not supported for the negative form but now they explicitly raise + errors in RSpec 3. (Myron Marston) +* Change the semantics of `expect { }.not_to change { x }.from(y)`. + In RSpec 2.x, this expectation would only fail if `x` started with + the value of `y` and changed. If it started with a different value + and changed, it would pass. In RSpec 3, it will pass only if the + value starts at `y` and it does not change. (Myron Marston) +* Deprecate `matcher == value` as an alias for `matcher.matches?(value)`, + in favor of `matcher === value`. (Myron Marston) +* Deprecate `RSpec::Matchers::OperatorMatcher` in favor of + `RSpec::Matchers::BuiltIn::OperatorMatcher`. (Myron Marston) +* Deprecate auto-integration with Test::Unit and minitest. + Instead, include `RSpec::Matchers` in the appropriate test case + base class yourself. (Myron Marston) +* Deprecate treating `#expected` on a DSL-generated custom matcher + as an array when only 1 argument is passed to the matcher method. + In RSpec 3 it will be the single value in order to make diffs + work properly. (Jon Rowe) + +### 2.99.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.99.0.beta1) + +Deprecations + +* Deprecate `have`, `have_at_least` and `have_at_most`. You can continue using those + matchers through https://github.com/rspec/rspec-collection_matchers, or + you can rewrite your expectations with something like + `expect(your_object.size).to eq(num)`. (Hugo Baraúna) +* Deprecate `be_xyz` predicate matcher when `xyz?` is a private method. + (Jon Rowe) +* Deprecate `be_true`/`be_false` in favour of `be_truthy`/`be_falsey` + (for Ruby's conditional semantics) or `be true`/`be false` + (for exact equality). (Sam Phippen) +* Deprecate calling helper methods from a custom matcher with the wrong + scope. (Myron Marston) + * `def self.foo` / `extend Helper` can be used to add macro methods + (e.g. methods that call the custom matcher DSL methods), but should + not be used to define helper methods called from within the DSL + blocks. + * `def foo` / `include Helper` is the opposite: it's for helper methods + callable from within a DSL block, but not for defining macros. + * RSpec 2.x allowed helper methods defined either way to be used for + either purpose, but RSpec 3.0 will not. + +### 2.14.5 / 2014-02-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.14.5) + +Bug fixes + +* Fix wrong matcher descriptions with falsey expected value + (yujinakayama) + +### 2.14.4 / 2013-11-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.3...v2.14.4) + +Bug fixes + +* Make the `match` matcher produce a diff output. (Jon Rowe, Ben Moss) +* Choose encoding for diff's more intelligently, and when all else fails fall + back to default internal encoding with replacing characters. (Jon Rowe) + +### 2.14.3 / 2013-09-22 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.2...v2.14.3) + +Bug fixes + +* Fix operator matchers (`should` syntax) when `method` is redefined on target. + (Brandon Turner) +* Fix diffing of hashes with object based keys. (Jon Rowe) +* Fix operator matchers (`should` syntax) when operator is defined via + `method_missing` (Jon Rowe) + +### 2.14.2 / 2013-08-14 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.1...v2.14.2) + +Bug fixes + +* Fix `be_` matcher to not support operator chaining like the + `be` matcher does (e.g. `be == 5`). This led to some odd behaviors + since `be_ == anything` returned a `BeComparedTo` matcher + and was thus always truthy. This was a consequence of the implementation + (e.g. subclassing the basic `Be` matcher) and was not intended behavior. + (Myron Marston). +* Fix `change` matcher to compare using `==` in addition to `===`. This + is important for an expression like: + `expect {}.to change { a.class }.from(ClassA).to(ClassB)` because + `SomeClass === SomeClass` returns false. (Myron Marston) + +### 2.14.1 / 2013-08-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0...2.14.1) + +Bug fixes + +* Ensure diff output uses the same encoding as the encoding of + the string being diff'd to prevent `Encoding::UndefinedConversionError` + errors (Jon Rowe). + +### 2.14.0 / 2013-07-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0.rc1...v2.14.0) + +Bug fixes + +* Values that are not matchers use `#inspect`, rather than `#description` for + documentation output (Andy Lindeman, Sam Phippen). +* Make `expect(a).to be_within(x).percent_of(y)` work with negative y + (Katsuhiko Nishimra). +* Make the `be_predicate` matcher work as expected used with `expect{...}.to + change...` (Sam Phippen). + +### 2.14.0.rc1 / 2013-05-27 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.13.0...v2.14.0.rc1) + +Enhancements + +* Enhance `yield_control` so that you can specify an exact or relative + number of times: `expect { }.to yield_control.exactly(3).times`, + `expect { }.to yield_control.at_least(2).times`, etc (Bartek + Borkowski). +* Make the differ that is used when an expectation fails better handle arrays + by splitting each element of the array onto its own line. (Sam Phippen) +* Accept duck-typed strings that respond to `:to_str` as expectation messages. + (Toby Ovod-Everett) + +Bug fixes + +* Fix differ to not raise errors when dealing with differently-encoded + strings (Jon Rowe). +* Fix `expect(something).to be_within(x).percent_of(y)` where x and y are both + integers (Sam Phippen). +* Fix `have` matcher to handle the fact that on ruby 2.0, + `Enumerator#size` may return nil (Kenta Murata). +* Fix `expect { raise s }.to raise_error(s)` where s is an error instance + on ruby 2.0 (Sam Phippen). +* Fix `expect(object).to raise_error` passing. This now warns the user and + fails the spec (tomykaira). + +Deprecations + +* Deprecate `expect { }.not_to raise_error(SpecificErrorClass)` or + `expect { }.not_to raise_error("some specific message")`. Using + these was prone to hiding failures as they would allow _any other + error_ to pass. (Sam Phippen and David Chelimsky) + +### 2.13.0 / 2013-02-23 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.1...v2.13.0) + +Enhancements + +* Add support for percent deltas to `be_within` matcher: + `expect(value).to be_within(10).percent_of(expected)` + (Myron Marston). +* Add support to `include` matcher to allow it to be given a list + of matchers as the expecteds to match against (Luke Redpath). + +Bug fixes + +* Fix `change` matcher so that it dups strings in order to handle + mutated strings (Myron Marston). +* Fix `should be =~ /some regex/` / `expect(...).to be =~ /some regex/`. + Previously, these either failed with a confusing `undefined method + matches?' for false:FalseClass` error or were no-ops that didn't + actually verify anything (Myron Marston). +* Add compatibility for diff-lcs 1.2 and relax the version + constraint (Peter Goldstein). +* Fix DSL-generated matchers to allow multiple instances of the + same matcher in the same example to have different description + and failure messages based on the expected value (Myron Marston). +* Prevent `undefined method #split for Array` error when dumping + the diff of an array of multiline strings (Myron Marston). +* Don't blow up when comparing strings that are in an encoding + that is not ASCII compatible (Myron Marston). +* Remove confusing "Check the implementation of #==" message + printed for empty diffs (Myron Marston). + +### 2.12.1 / 2012-12-15 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.0...v2.12.1) + +Bug fixes + +* Improve the failure message for an expression like + `{}.should =~ {}`. (Myron Marston and Andy Lindeman) +* Provide a `match_regex` alias so that custom matchers + built using the matcher DSL can use it (since `match` + is a different method in that context). + (Steven Harman) + +### 2.12.0 / 2012-11-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.3...v2.12.0) + +Enhancements + +* Colorize diffs if the `--color` option is configured. (Alex Coplan) +* Include backtraces in unexpected errors handled by `raise_error` + matcher (Myron Marston) +* Print a warning when users accidentally pass a non-string argument + as an expectation message (Sam Phippen) +* `=~` and `match_array` matchers output a more useful error message when + the actual value is not an array (or an object that responds to `#to_ary`) + (Sam Phippen) + +Bug fixes + +* Fix `include` matcher so that `expect({}).to include(:a => nil)` + fails as it should (Sam Phippen). +* Fix `be_an_instance_of` matcher so that `Class#to_s` is used in the + description rather than `Class#inspect`, since some classes (like + `ActiveRecord::Base`) define a long, verbose `#inspect`. + (Tom Stuart) + +### 2.11.3 / 2012-09-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.2...v2.11.3) + +Bug fixes + +* Fix (and deprecate) `expect { }.should` syntax so that it works even + though it was never a documented or intended syntax. It worked as a + consequence of the implementation of `expect` in RSpec 2.10 and + earlier. (Myron Marston) +* Ensure #== is defined on built in matchers so that they can be composed. + For example: + + expect { + user.emailed! + }.to change { user.last_emailed_at }.to be_within(1.second).of(Time.zone.now) + +### 2.11.2 / 2012-07-25 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.1...v2.11.2) + +Bug fixes + +* Define `should` and `should_not` on `Object` rather than `BasicObject` + on MacRuby. On MacRuby, `BasicObject` is defined but is not the root + of the object hierarchy. (Gabriel Gilder) + +### 2.11.1 / 2012-07-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.0...v2.11.1) + +Bug fixes + +* Constrain `actual` in `be_within` matcher to values that respond to `-` instead + of requiring a specific type. + * `Time`, for example, is a legit alternative. + +### 2.11.0 / 2012-07-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.10.0...v2.11.0) + +Enhancements + +* Expand `expect` syntax so that it supports expections on bare values + in addition to blocks (Myron Marston). +* Add configuration options to control available expectation syntaxes + (Myron Marston): + * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :expect }` + * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :should }` + * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }` + * `RSpec.configuration.add_should_and_should_not_to Delegator` + +Bug fixes + +* Allow only `Numeric` values to be the "actual" in the `be_within` matcher. + This prevents confusing error messages. (Su Zhang @zhangsu) +* Define `should` and `should_not` on `BasicObject` rather than `Kernel` + on 1.9. This makes `should` and `should_not` work properly with + `BasicObject`-subclassed proxy objects like `Delegator`. (Myron + Marston) + +### 2.10.0 / 2012-05-03 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.1...v2.10.0) + +Enhancements + +* Add new `start_with` and `end_with` matchers (Jeremy Wadsack) +* Add new matchers for specifying yields (Myron Marston): + * `expect {...}.to yield_control` + * `expect {...}.to yield_with_args(1, 2, 3)` + * `expect {...}.to yield_with_no_args` + * `expect {...}.to yield_successive_args(1, 2, 3)` +* `match_unless_raises` takes multiple exception args + +Bug fixes + +* Fix `be_within` matcher to be inclusive of delta. +* Fix message-specific specs to pass on Rubinius (John Firebaugh) + +### 2.9.1 / 2012-04-03 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.0...v2.9.1) + +Bug fixes + +* Provide a helpful message if the diff between two objects is empty. +* Fix bug diffing single strings with multiline strings. +* Fix for error with using custom matchers inside other custom matchers + (mirasrael) +* Fix using execution context methods in nested DSL matchers (mirasrael) + +### 2.9.0 / 2012-03-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0...v2.9.0) + +Enhancements + +* Move built-in matcher classes to RSpec::Matchers::BuiltIn to reduce pollution + of RSpec::Matchers (which is included in every example). +* Autoload files with matcher classes to improve load time. + +Bug fixes + +* Align `respond_to?` and `method_missing` in DSL-defined matchers. +* Clear out user-defined instance variables between invocations of DSL-defined + matchers. +* Dup the instance of a DSL generated matcher so its state is not changed by + subsequent invocations. +* Treat expected args consistently across positive and negative expectations + (thanks to Ralf Kistner for the heads up) + +### 2.8.0 / 2012-01-04 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc2...v2.8.0) + +Enhancements + +* Better diff output for Hash (Philippe Creux) +* Eliminate Ruby warnings (Olek Janiszewski) + +### 2.8.0.rc2 / 2011-12-19 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc1...v2.8.0.rc2) + +No changes for this release. Just releasing with the other rspec gems. + +### 2.8.0.rc1 / 2011-11-06 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.7.0...v2.8.0.rc1) + +Enhancements + +* Use classes for the built-in matchers (they're faster). +* Eliminate Ruby warnings (Matijs van Zuijlen) + +### 2.7.0 / 2011-10-16 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.6.0...v2.7.0) + +Enhancements + +* `HaveMatcher` converts argument using `to_i` (Alex Bepple & Pat Maddox) +* Improved failure message for the `have_xxx` matcher (Myron Marston) +* `HaveMatcher` supports `count` (Matthew Bellantoni) +* Change matcher dups `Enumerable` before the action, supporting custom + `Enumerable` types like `CollectionProxy` in Rails (David Chelimsky) + +Bug fixes + +* Fix typo in `have(n).xyz` documentation (Jean Boussier) +* fix `safe_sort` for ruby 1.9.2 (`Kernel` now defines `<=>` for Object) (Peter + van Hardenberg) + +### 2.6.0 / 2011-05-12 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.5.0...v2.6.0) + +Enhancements + +* `change` matcher accepts regexps (Robert Davis) +* better descriptions for `have_xxx` matchers (Magnus Bergmark) +* `range.should cover(*values)` (Anders Furseth) + +Bug fixes + +* Removed non-ascii characters that were choking rcov (Geoffrey Byers) +* change matcher dups arrays and hashes so their before/after states can be + compared correctly. +* Fix the order of inclusion of RSpec::Matchers in Test::Unit::TestCase and + MiniTest::Unit::TestCase to prevent a SystemStackError (Myron Marston) + +### 2.5.0 / 2011-02-05 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.4.0...v2.5.0) + +Enhancements + +* `should exist` works with `exist?` or `exists?` (Myron Marston) +* `expect { ... }.not_to do_something` (in addition to `to_not`) + +Documentation + +* improved docs for raise_error matcher (James Almond) + +### 2.4.0 / 2011-01-02 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.3.0...v2.4.0) + +No functional changes in this release, which was made to align with the +rspec-core-2.4.0 release. + +Enhancements + +* improved RDoc for change matcher (Jo Liss) + +### 2.3.0 / 2010-12-12 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.2.1...v2.3.0) + +Enhancements + +* diff strings when include matcher fails (Mike Sassak) + +### 2.2.0 / 2010-11-28 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.1.0...v2.2.0) + +### 2.1.0 / 2010-11-07 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.1...v2.1.0) + +Enhancements + +* `be_within(delta).of(expected)` matcher (Myron Marston) +* Lots of new Cucumber features (Myron Marston) +* Raise error if you try `should != expected` on Ruby-1.9 (Myron Marston) +* Improved failure messages from `throw_symbol` (Myron Marston) + +Bug fixes + +* Eliminate hard dependency on `RSpec::Core` (Myron Marston) +* `have_matcher` - use pluralize only when ActiveSupport inflections are indeed + defined (Josep M Bach) +* throw_symbol matcher no longer swallows exceptions (Myron Marston) +* fix matcher chaining to avoid name collisions (Myron Marston) + +### 2.0.0 / 2010-10-10 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.rc...v2.0.0) + +Enhancements + +* Add match_for_should_not method to matcher DSL (Myron Marston) + +Bug fixes + +* `respond_to` matcher works correctly with `should_not` with multiple methods + (Myron Marston) +* `include` matcher works correctly with `should_not` with multiple values + (Myron Marston) + +### 2.0.0.rc / 2010-10-05 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.22...v2.0.0.rc) + +Enhancements + +* `require 'rspec/expectations'` in a T::U or MiniUnit suite (Josep M. Bach) + +Bug fixes + +* change by 0 passes/fails correctly (Len Smith) +* Add description to satisfy matcher + +### 2.0.0.beta.22 / 2010-09-12 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.20...v2.0.0.beta.22) + +Enhancements + +* diffing improvements + * diff multiline strings + * don't diff single line strings + * don't diff numbers (silly) + * diff regexp + multiline string + +Bug fixes + * `should[_not]` change now handles boolean values correctly diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md new file mode 100644 index 0000000..dae02d8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md @@ -0,0 +1,25 @@ +The MIT License (MIT) +===================== + +* Copyright © 2012 David Chelimsky, Myron Marston +* Copyright © 2006 David Chelimsky, The RSpec Development Team +* Copyright © 2005 Steven Baker + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md new file mode 100644 index 0000000..a649542 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md @@ -0,0 +1,326 @@ +# RSpec Expectations [![Build Status](https://github.com/rspec/rspec-expectations/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-expectations/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-expectations.svg)](https://codeclimate.com/github/rspec/rspec-expectations) + +RSpec::Expectations lets you express expected outcomes on an object in an +example. + +```ruby +expect(account.balance).to eq(Money.new(37.42, :USD)) +``` + +## Install + +If you want to use rspec-expectations with rspec, just install the rspec gem +and RubyGems will also install rspec-expectations for you (along with +rspec-core and rspec-mocks): + +```shell +gem install rspec +``` + +Want to run against the `main` branch? You'll need to include the dependent +RSpec repos as well. Add the following to your `Gemfile`: + +```ruby +%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| + gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' +end +``` + +If you want to use rspec-expectations with another tool, like Test::Unit, +Minitest, or Cucumber, you can install it directly: + +```shell +gem install rspec-expectations +``` + +## Contributing + +Once you've set up the environment, you'll need to cd into the working +directory of whichever repo you want to work in. From there you can run the +specs and cucumber features, and make patches. + +NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You +can treat each RSpec repo as an independent project. + +- [Build details](BUILD_DETAIL.md) +- [Code of Conduct](CODE_OF_CONDUCT.md) +- [Detailed contributing guide](CONTRIBUTING.md) +- [Development setup guide](DEVELOPMENT.md) + +## Basic usage + +Here's an example using rspec-core: + +```ruby +RSpec.describe Order do + it "sums the prices of the items in its line items" do + order = Order.new + order.add_entry(LineItem.new(:item => Item.new( + :price => Money.new(1.11, :USD) + ))) + order.add_entry(LineItem.new(:item => Item.new( + :price => Money.new(2.22, :USD), + :quantity => 2 + ))) + expect(order.total).to eq(Money.new(5.55, :USD)) + end +end +``` + +The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`, `Item` and `Money` classes would be from _your_ code. The last line of the example +expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then +the example passes. If not, it fails with a message like: + +``` + expected: # + got: # +``` + +## Built-in matchers + +### Equivalence + +```ruby +expect(actual).to eq(expected) # passes if actual == expected +expect(actual).to eql(expected) # passes if actual.eql?(expected) +expect(actual).not_to eql(not_expected) # passes if not(actual.eql?(expected)) +``` + +Note: The new `expect` syntax no longer supports the `==` matcher. + +### Identity + +```ruby +expect(actual).to be(expected) # passes if actual.equal?(expected) +expect(actual).to equal(expected) # passes if actual.equal?(expected) +``` + +### Comparisons + +```ruby +expect(actual).to be > expected +expect(actual).to be >= expected +expect(actual).to be <= expected +expect(actual).to be < expected +expect(actual).to be_within(delta).of(expected) +``` + +### Regular expressions + +```ruby +expect(actual).to match(/expression/) +``` + +Note: The new `expect` syntax no longer supports the `=~` matcher. + +### Types/classes + +```ruby +expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected +expect(actual).to be_a(expected) # passes if actual.kind_of?(expected) +expect(actual).to be_an(expected) # an alias for be_a +expect(actual).to be_a_kind_of(expected) # another alias +``` + +### Truthiness + +```ruby +expect(actual).to be_truthy # passes if actual is truthy (not nil or false) +expect(actual).to be true # passes if actual == true +expect(actual).to be_falsy # passes if actual is falsy (nil or false) +expect(actual).to be false # passes if actual == false +expect(actual).to be_nil # passes if actual is nil +expect(actual).to_not be_nil # passes if actual is not nil +``` + +### Expecting errors + +```ruby +expect { ... }.to raise_error +expect { ... }.to raise_error(ErrorClass) +expect { ... }.to raise_error("message") +expect { ... }.to raise_error(ErrorClass, "message") +``` + +### Expecting throws + +```ruby +expect { ... }.to throw_symbol +expect { ... }.to throw_symbol(:symbol) +expect { ... }.to throw_symbol(:symbol, 'value') +``` + +### Yielding + +```ruby +expect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args + +expect { |b| yield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yielded + +expect { |b| 5.tap(&b) }.to yield_with_args(5) +expect { |b| 5.tap(&b) }.to yield_with_args(Integer) +expect { |b| "a string".tap(&b) }.to yield_with_args(/str/) + +expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) +expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2]) +``` + +### Predicate matchers + +```ruby +expect(actual).to be_xxx # passes if actual.xxx? +expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg) +``` + +### Ranges (Ruby >= 1.9 only) + +```ruby +expect(1..10).to cover(3) +``` + +### Collection membership + +```ruby +# exact order, entire collection +expect(actual).to eq(expected) + +# exact order, partial collection (based on an exact position) +expect(actual).to start_with(expected) +expect(actual).to end_with(expected) + +# any order, entire collection +expect(actual).to match_array(expected) + +# You can also express this by passing the expected elements +# as individual arguments +expect(actual).to contain_exactly(expected_element1, expected_element2) + + # any order, partial collection +expect(actual).to include(expected) +``` + +#### Examples + +```ruby +expect([1, 2, 3]).to eq([1, 2, 3]) # Order dependent equality check +expect([1, 2, 3]).to include(1) # Exact ordering, partial collection matches +expect([1, 2, 3]).to include(2, 3) # +expect([1, 2, 3]).to start_with(1) # As above, but from the start of the collection +expect([1, 2, 3]).to start_with(1, 2) # +expect([1, 2, 3]).to end_with(3) # As above but from the end of the collection +expect([1, 2, 3]).to end_with(2, 3) # +expect({:a => 'b'}).to include(:a => 'b') # Matching within hashes +expect("this string").to include("is str") # Matching within strings +expect("this string").to start_with("this") # +expect("this string").to end_with("ring") # +expect([1, 2, 3]).to contain_exactly(2, 3, 1) # Order independent matches +expect([1, 2, 3]).to match_array([3, 2, 1]) # + +# Order dependent compound matchers +expect( + [{:a => 'hash'},{:a => 'another'}] +).to match([a_hash_including(:a => 'hash'), a_hash_including(:a => 'another')]) +``` + +## `should` syntax + +In addition to the `expect` syntax, rspec-expectations continues to support the +`should` syntax: + +```ruby +actual.should eq expected +actual.should be > 3 +[1, 2, 3].should_not include 4 +``` + +See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/main/Should.md) + +## Compound Matcher Expressions + +You can also create compound matcher expressions using `and` or `or`: + +``` ruby +expect(alphabet).to start_with("a").and end_with("z") +expect(stoplight.color).to eq("red").or eq("green").or eq("yellow") +``` + +## Composing Matchers + +Many of the built-in matchers are designed to take matchers as +arguments, to allow you to flexibly specify only the essential +aspects of an object or data structure. In addition, all of the +built-in matchers have one or more aliases that provide better +phrasing for when they are used as arguments to another matcher. + +### Examples + +```ruby +expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) ) + +expect { s = "barn" }.to change { s } + .from( a_string_matching(/foo/) ) + .to( a_string_matching(/bar/) ) + +expect(["barn", 2.45]).to contain_exactly( + a_value_within(0.1).of(2.5), + a_string_starting_with("bar") +) + +expect(["barn", "food", 2.45]).to end_with( + a_string_matching("foo"), + a_value > 2 +) + +expect(["barn", 2.45]).to include( a_string_starting_with("bar") ) + +expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/)) + +hash = { + :a => { + :b => ["foo", 5], + :c => { :d => 2.05 } + } +} + +expect(hash).to match( + :a => { + :b => a_collection_containing_exactly( + a_string_starting_with("f"), + an_instance_of(Integer) + ), + :c => { :d => (a_value < 3) } + } +) + +expect { |probe| + [1, 2, 3].each(&probe) +}.to yield_successive_args( a_value < 2, 2, a_value > 2 ) +``` + +## Usage outside rspec-core + +You always need to load `rspec/expectations` even if you only want to use one part of the library: + +```ruby +require 'rspec/expectations' +``` + +Then simply include `RSpec::Matchers` in any class: + +```ruby +class MyClass + include RSpec::Matchers + + def do_something(arg) + expect(arg).to be > 0 + # do other stuff + end +end +``` + +## Also see + +* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) +* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) +* [https://github.com/rspec/rspec-mocks](https://github.com/rspec/rspec-mocks) +* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb new file mode 100644 index 0000000..9e11ea0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb @@ -0,0 +1,82 @@ +require 'rspec/support' +RSpec::Support.require_rspec_support "caller_filter" +RSpec::Support.require_rspec_support "warnings" +RSpec::Support.require_rspec_support "object_formatter" + +require 'rspec/matchers' + +RSpec::Support.define_optimized_require_for_rspec(:expectations) { |f| require_relative(f) } + +%w[ + expectation_target + configuration + fail_with + handler + version +].each { |file| RSpec::Support.require_rspec_expectations(file) } + +module RSpec + # RSpec::Expectations provides a simple, readable API to express + # the expected outcomes in a code example. To express an expected + # outcome, wrap an object or block in `expect`, call `to` or `to_not` + # (aliased as `not_to`) and pass it a matcher object: + # + # expect(order.total).to eq(Money.new(5.55, :USD)) + # expect(list).to include(user) + # expect(message).not_to match(/foo/) + # expect { do_something }.to raise_error + # + # The last form (the block form) is needed to match against ruby constructs + # that are not objects, but can only be observed when executing a block + # of code. This includes raising errors, throwing symbols, yielding, + # and changing values. + # + # When `expect(...).to` is invoked with a matcher, it turns around + # and calls `matcher.matches?()`. For example, + # in the expression: + # + # expect(order.total).to eq(Money.new(5.55, :USD)) + # + # ...`eq(Money.new(5.55, :USD))` returns a matcher object, and it results + # in the equivalent of `eq.matches?(order.total)`. If `matches?` returns + # `true`, the expectation is met and execution continues. If `false`, then + # the spec fails with the message returned by `eq.failure_message`. + # + # Given the expression: + # + # expect(order.entries).not_to include(entry) + # + # ...the `not_to` method (also available as `to_not`) invokes the equivalent of + # `include.matches?(order.entries)`, but it interprets `false` as success, and + # `true` as a failure, using the message generated by + # `include.failure_message_when_negated`. + # + # rspec-expectations ships with a standard set of useful matchers, and writing + # your own matchers is quite simple. + # + # See [RSpec::Matchers](../RSpec/Matchers) for more information about the + # built-in matchers that ship with rspec-expectations, and how to write your + # own custom matchers. + module Expectations + # Exception raised when an expectation fails. + # + # @note We subclass Exception so that in a stub implementation if + # the user sets an expectation, it can't be caught in their + # code by a bare `rescue`. + # @api public + class ExpectationNotMetError < Exception + end + + # Exception raised from `aggregate_failures` when multiple expectations fail. + # + # @note The constant is defined here but the extensive logic of this class + # is lazily defined when `FailureAggregator` is autoloaded, since we do + # not need to waste time defining that functionality unless + # `aggregate_failures` is used. + class MultipleExpectationsNotMetError < ExpectationNotMetError + end + + autoload :BlockSnippetExtractor, "rspec/expectations/block_snippet_extractor" + autoload :FailureAggregator, "rspec/expectations/failure_aggregator" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb new file mode 100644 index 0000000..25cc326 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb @@ -0,0 +1,255 @@ +module RSpec + module Expectations + # @private + class BlockSnippetExtractor # rubocop:disable Metrics/ClassLength + # rubocop should properly handle `Struct.new {}` as an inner class definition. + + attr_reader :proc, :method_name + + def self.try_extracting_single_line_body_of(proc, method_name) + lines = new(proc, method_name).body_content_lines + return nil unless lines.count == 1 + lines.first + rescue Error + nil + end + + def initialize(proc, method_name) + @proc = proc + @method_name = method_name.to_s.freeze + end + + # Ideally we should properly handle indentations of multiline snippet, + # but it's not implemented yet since because we use result of this method only when it's a + # single line and implementing the logic introduces additional complexity. + def body_content_lines + raw_body_lines.map(&:strip).reject(&:empty?) + end + + private + + def raw_body_lines + raw_body_snippet.split("\n") + end + + def raw_body_snippet + block_token_extractor.body_tokens.map(&:string).join + end + + def block_token_extractor + @block_token_extractor ||= BlockTokenExtractor.new(method_name, source, beginning_line_number) + end + + if RSpec.respond_to?(:world) + def source + raise TargetNotFoundError unless File.exist?(file_path) + RSpec.world.source_from_file(file_path) + end + else + # :nocov: + RSpec::Support.require_rspec_support 'source' + def source + raise TargetNotFoundError unless File.exist?(file_path) + @source ||= RSpec::Support::Source.from_file(file_path) + end + # :nocov: + end + + def file_path + source_location.first + end + + def beginning_line_number + source_location.last + end + + def source_location + proc.source_location || raise(TargetNotFoundError) + end + + Error = Class.new(StandardError) + TargetNotFoundError = Class.new(Error) + AmbiguousTargetError = Class.new(Error) + + # @private + # Performs extraction of block body snippet using tokens, + # which cannot be done with node information. + BlockTokenExtractor = Struct.new(:method_name, :source, :beginning_line_number) do + attr_reader :state, :body_tokens + + def initialize(*) + super + parse! + end + + private + + def parse! + @state = :initial + + catch(:finish) do + source.tokens.each do |token| + invoke_state_handler(token) + end + end + end + + def finish! + throw :finish + end + + def invoke_state_handler(token) + __send__("#{state}_state", token) + end + + def initial_state(token) + @state = :after_method_call if token.location == block_locator.method_call_location + end + + def after_method_call_state(token) + @state = :after_opener if handle_opener_token(token) + end + + def after_opener_state(token) + if handle_closer_token(token) + finish_or_find_next_block_if_incorrect! + elsif pipe_token?(token) + finalize_pending_tokens! + @state = :after_beginning_of_args + else + pending_tokens << token + handle_opener_token(token) + @state = :after_beginning_of_body unless token.type == :on_sp + end + end + + def after_beginning_of_args_state(token) + @state = :after_beginning_of_body if pipe_token?(token) + end + + def after_beginning_of_body_state(token) + if handle_closer_token(token) + finish_or_find_next_block_if_incorrect! + else + pending_tokens << token + handle_opener_token(token) + end + end + + def pending_tokens + @pending_tokens ||= [] + end + + def finalize_pending_tokens! + pending_tokens.freeze.tap do + @pending_tokens = nil + end + end + + def finish_or_find_next_block_if_incorrect! + body_tokens = finalize_pending_tokens! + + if correct_block?(body_tokens) + @body_tokens = body_tokens + finish! + else + @state = :after_method_call + end + end + + def handle_opener_token(token) + opener_token?(token).tap do |boolean| + opener_token_stack.push(token) if boolean + end + end + + def opener_token?(token) + token.type == :on_lbrace || (token.type == :on_kw && token.string == 'do') + end + + def handle_closer_token(token) + if opener_token_stack.last.closed_by?(token) + opener_token_stack.pop + opener_token_stack.empty? + else + false + end + end + + def opener_token_stack + @opener_token_stack ||= [] + end + + def pipe_token?(token) + token.type == :on_op && token.string == '|' + end + + def correct_block?(body_tokens) + return true if block_locator.body_content_locations.empty? + content_location = block_locator.body_content_locations.first + content_location.between?(body_tokens.first.location, body_tokens.last.location) + end + + def block_locator + @block_locator ||= BlockLocator.new(method_name, source, beginning_line_number) + end + end + + # @private + # Locates target block with node information (semantics), which tokens don't have. + BlockLocator = Struct.new(:method_name, :source, :beginning_line_number) do + def method_call_location + @method_call_location ||= method_ident_node.location + end + + def body_content_locations + @body_content_locations ||= block_body_node.map(&:location).compact + end + + private + + def method_ident_node + method_call_node = block_wrapper_node.children.first + method_call_node.find do |node| + method_ident_node?(node) + end + end + + def block_body_node + block_node = block_wrapper_node.children[1] + block_node.children.last + end + + def block_wrapper_node + case candidate_block_wrapper_nodes.size + when 1 + candidate_block_wrapper_nodes.first + when 0 + raise TargetNotFoundError + else + raise AmbiguousTargetError + end + end + + def candidate_block_wrapper_nodes + @candidate_block_wrapper_nodes ||= candidate_method_ident_nodes.map do |method_ident_node| + block_wrapper_node = method_ident_node.each_ancestor.find { |node| node.type == :method_add_block } + next nil unless block_wrapper_node + method_call_node = block_wrapper_node.children.first + method_call_node.include?(method_ident_node) ? block_wrapper_node : nil + end.compact + end + + def candidate_method_ident_nodes + source.nodes_by_line_number[beginning_line_number].select do |node| + method_ident_node?(node) + end + end + + def method_ident_node?(node) + node.type == :@ident && node.args.first == method_name + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb new file mode 100644 index 0000000..21620fb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb @@ -0,0 +1,244 @@ +RSpec::Support.require_rspec_expectations "syntax" + +module RSpec + module Expectations + # Provides configuration options for rspec-expectations. + # If you are using rspec-core, you can access this via a + # block passed to `RSpec::Core::Configuration#expect_with`. + # Otherwise, you can access it via RSpec::Expectations.configuration. + # + # @example + # RSpec.configure do |rspec| + # rspec.expect_with :rspec do |c| + # # c is the config object + # end + # end + # + # # or + # + # RSpec::Expectations.configuration + class Configuration + # @private + FALSE_POSITIVE_BEHAVIOURS = + { + :warn => lambda { |message| RSpec.warning message }, + :raise => lambda { |message| raise ArgumentError, message }, + :nothing => lambda { |_| true }, + } + + def initialize + @on_potential_false_positives = :warn + @strict_predicate_matchers = false + end + + # Configures the supported syntax. + # @param [Array, Symbol] values the syntaxes to enable + # @example + # RSpec.configure do |rspec| + # rspec.expect_with :rspec do |c| + # c.syntax = :should + # # or + # c.syntax = :expect + # # or + # c.syntax = [:should, :expect] + # end + # end + def syntax=(values) + if Array(values).include?(:expect) + Expectations::Syntax.enable_expect + else + Expectations::Syntax.disable_expect + end + + if Array(values).include?(:should) + Expectations::Syntax.enable_should + else + Expectations::Syntax.disable_should + end + end + + # Configures the maximum character length that RSpec will print while + # formatting an object. You can set length to nil to prevent RSpec from + # doing truncation. + # @param [Fixnum] length the number of characters to limit the formatted output to. + # @example + # RSpec.configure do |rspec| + # rspec.expect_with :rspec do |c| + # c.max_formatted_output_length = 200 + # end + # end + def max_formatted_output_length=(length) + RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = length + end + + # The list of configured syntaxes. + # @return [Array] the list of configured syntaxes. + # @example + # unless RSpec::Matchers.configuration.syntax.include?(:expect) + # raise "this RSpec extension gem requires the rspec-expectations `:expect` syntax" + # end + def syntax + syntaxes = [] + syntaxes << :should if Expectations::Syntax.should_enabled? + syntaxes << :expect if Expectations::Syntax.expect_enabled? + syntaxes + end + + if ::RSpec.respond_to?(:configuration) + def color? + ::RSpec.configuration.color_enabled? + end + else + # :nocov: + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + attr_writer :color + + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + def color? + defined?(@color) && @color + end + # :nocov: + end + + # :nocov: Because this is only really _useful_ on 1.8, and hard to test elsewhere. + # + # Adds `should` and `should_not` to the given classes + # or modules. This can be used to ensure `should` works + # properly on things like proxy objects (particular + # `Delegator`-subclassed objects on 1.8). + # + # @param [Array] modules the list of classes or modules + # to add `should` and `should_not` to. + def add_should_and_should_not_to(*modules) + modules.each do |mod| + Expectations::Syntax.enable_should(mod) + end + end + # :nocov: + + # Sets or gets the backtrace formatter. The backtrace formatter should + # implement `#format_backtrace(Array)`. This is used + # to format backtraces of errors handled by the `raise_error` + # matcher. + # + # If you are using rspec-core, rspec-core's backtrace formatting + # will be used (including respecting the presence or absence of + # the `--backtrace` option). + # + # @!attribute [rw] backtrace_formatter + attr_writer :backtrace_formatter + def backtrace_formatter + @backtrace_formatter ||= if defined?(::RSpec.configuration.backtrace_formatter) + ::RSpec.configuration.backtrace_formatter + else + NullBacktraceFormatter + end + end + + # Sets if custom matcher descriptions and failure messages + # should include clauses from methods defined using `chain`. + # @param value [Boolean] + attr_writer :include_chain_clauses_in_custom_matcher_descriptions + + # Indicates whether or not custom matcher descriptions and failure messages + # should include clauses from methods defined using `chain`. It is + # false by default for backwards compatibility. + def include_chain_clauses_in_custom_matcher_descriptions? + @include_chain_clauses_in_custom_matcher_descriptions ||= false + end + + # @private + def reset_syntaxes_to_default + self.syntax = [:should, :expect] + RSpec::Expectations::Syntax.warn_about_should! + end + + # @api private + # Null implementation of a backtrace formatter used by default + # when rspec-core is not loaded. Does no filtering. + NullBacktraceFormatter = Module.new do + def self.format_backtrace(backtrace) + backtrace + end + end + + # Configures whether RSpec will warn about matcher use which will + # potentially cause false positives in tests. + # + # @param [Boolean] boolean + def warn_about_potential_false_positives=(boolean) + if boolean + self.on_potential_false_positives = :warn + elsif warn_about_potential_false_positives? + self.on_potential_false_positives = :nothing + else + # no-op, handler is something else + end + end + + # Configures what RSpec will do about matcher use which would potentially cause + # false positives in tests. Defaults to `:warn` since this is generally the desired behavior, + # but can also be set to `:raise` or `:nothing`. + # + # @overload on_potential_false_positives + # @return [Symbol] the behavior setting + # @overload on_potential_false_positives=(value) + # @param [Symbol] behavior can be set to `:warn`, `:raise` or `:nothing` + # @return [Symbol] the behavior setting + attr_reader :on_potential_false_positives + + def on_potential_false_positives=(behavior) + unless FALSE_POSITIVE_BEHAVIOURS.key?(behavior) + raise ArgumentError, "Supported values are: #{FALSE_POSITIVE_BEHAVIOURS.keys}" + end + @on_potential_false_positives = behavior + end + + # Configures RSpec to check predicate matchers to `be(true)` / `be(false)` (strict), + # or `be_truthy` / `be_falsey` (not strict). + # Historically, the default was `false`, but `true` is recommended. + # + # @overload strict_predicate_matchers + # @return [Boolean] + # @overload strict_predicate_matchers? + # @return [Boolean] + # @overload strict_predicate_matchers=(value) + # @param [Boolean] value + attr_reader :strict_predicate_matchers + + def strict_predicate_matchers=(value) + raise ArgumentError, "Pass `true` or `false`" unless value == true || value == false + @strict_predicate_matchers = value + end + + def strict_predicate_matchers? + @strict_predicate_matchers + end + + # Indicates whether RSpec will warn about matcher use which will + # potentially cause false positives in tests, generally you want to + # avoid such scenarios so this defaults to `true`. + def warn_about_potential_false_positives? + on_potential_false_positives == :warn + end + + # @private + def false_positives_handler + FALSE_POSITIVE_BEHAVIOURS.fetch(@on_potential_false_positives) + end + end + + # The configuration object. + # @return [RSpec::Expectations::Configuration] the configuration object + def self.configuration + @configuration ||= Configuration.new + end + + # set default syntax + configuration.reset_syntaxes_to_default + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb new file mode 100644 index 0000000..7d1e8d4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb @@ -0,0 +1,163 @@ +module RSpec + module Expectations + # Wraps the target of an expectation. + # + # @example + # expect(something) # => ExpectationTarget wrapping something + # expect { do_something } # => ExpectationTarget wrapping the block + # + # # used with `to` + # expect(actual).to eq(3) + # + # # with `not_to` + # expect(actual).not_to eq(3) + # + # @note `ExpectationTarget` is not intended to be instantiated + # directly by users. Use `expect` instead. + class ExpectationTarget + # @private + # Used as a sentinel value to be able to tell when the user + # did not pass an argument. We can't use `nil` for that because + # `nil` is a valid value to pass. + UndefinedValue = Module.new + + # @note this name aligns with `Minitest::Expectation` so that our + # {InstanceMethods} module can be included in that class when + # used in a Minitest context. + # @return [Object] the target of the expectation + attr_reader :target + + # @api private + def initialize(value) + @target = value + end + + # @private + def self.for(value, block) + if UndefinedValue.equal?(value) + unless block + raise ArgumentError, "You must pass either an argument or a block to `expect`." + end + BlockExpectationTarget.new(block) + elsif block + raise ArgumentError, "You cannot pass both an argument and a block to `expect`." + else + ValueExpectationTarget.new(value) + end + end + + # Defines instance {ExpectationTarget} instance methods. These are defined + # in a module so we can include it in `Minitest::Expectation` when + # `rspec/expectations/minitest_integration` is loaded in order to + # support usage with Minitest. + module InstanceMethods + # Runs the given expectation, passing if `matcher` returns true. + # @example + # expect(value).to eq(5) + # expect { perform }.to raise_error + # @param [Matcher] + # matcher + # @param [String, Proc] message optional message to display when the expectation fails + # @return [Boolean] true if the expectation succeeds (else raises) + # @see RSpec::Matchers + def to(matcher=nil, message=nil, &block) + prevent_operator_matchers(:to) unless matcher + RSpec::Expectations::PositiveExpectationHandler.handle_matcher(target, matcher, message, &block) + end + + # Runs the given expectation, passing if `matcher` returns false. + # @example + # expect(value).not_to eq(5) + # @param [Matcher] + # matcher + # @param [String, Proc] message optional message to display when the expectation fails + # @return [Boolean] false if the negative expectation succeeds (else raises) + # @see RSpec::Matchers + def not_to(matcher=nil, message=nil, &block) + prevent_operator_matchers(:not_to) unless matcher + RSpec::Expectations::NegativeExpectationHandler.handle_matcher(target, matcher, message, &block) + end + alias to_not not_to + + private + + def prevent_operator_matchers(verb) + raise ArgumentError, "The expect syntax does not support operator matchers, " \ + "so you must pass a matcher to `##{verb}`." + end + end + + include InstanceMethods + end + + # @private + # Validates the provided matcher to ensure it supports block + # expectations, in order to avoid user confusion when they + # use a block thinking the expectation will be on the return + # value of the block rather than the block itself. + class ValueExpectationTarget < ExpectationTarget + def to(matcher=nil, message=nil, &block) + enforce_value_expectation(matcher) + super + end + + def not_to(matcher=nil, message=nil, &block) + enforce_value_expectation(matcher) + super + end + + private + + def enforce_value_expectation(matcher) + return if supports_value_expectations?(matcher) + + RSpec.deprecate( + "expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}", + :message => + "The implicit block expectation syntax is deprecated, you should pass " \ + "a block rather than an argument to `expect` to use the provided " \ + "block expectation matcher or the matcher must implement " \ + "`supports_value_expectations?`. e.g `expect { value }.to " \ + "#{RSpec::Support::ObjectFormatter.format(matcher)}` not " \ + "`expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}`" + ) + end + + def supports_value_expectations?(matcher) + !matcher.respond_to?(:supports_value_expectations?) || matcher.supports_value_expectations? + end + end + + # @private + # Validates the provided matcher to ensure it supports block + # expectations, in order to avoid user confusion when they + # use a block thinking the expectation will be on the return + # value of the block rather than the block itself. + class BlockExpectationTarget < ExpectationTarget + def to(matcher, message=nil, &block) + enforce_block_expectation(matcher) + super + end + + def not_to(matcher, message=nil, &block) + enforce_block_expectation(matcher) + super + end + alias to_not not_to + + private + + def enforce_block_expectation(matcher) + return if supports_block_expectations?(matcher) + + raise ExpectationNotMetError, "You must pass an argument rather than a block to `expect` to use the provided " \ + "matcher (#{RSpec::Support::ObjectFormatter.format(matcher)}), or the matcher must implement " \ + "`supports_block_expectations?`." + end + + def supports_block_expectations?(matcher) + matcher.respond_to?(:supports_block_expectations?) && matcher.supports_block_expectations? + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb new file mode 100644 index 0000000..17b66b3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb @@ -0,0 +1,39 @@ +module RSpec + module Expectations + class << self + # @private + class Differ + # @private + OBJECT_PREPARER = lambda do |object| + RSpec::Matchers::Composable.surface_descriptions_in(object) + end + end + + # @private + def differ + RSpec::Support::Differ.new( + :object_preparer => Differ::OBJECT_PREPARER, + :color => RSpec::Matchers.configuration.color? + ) + end + + # Raises an RSpec::Expectations::ExpectationNotMetError with message. + # @param [String] message + # @param [Object] expected + # @param [Object] actual + # + # Adds a diff to the failure message when `expected` and `actual` are + # both present. + def fail_with(message, expected=nil, actual=nil) + unless message + raise ArgumentError, "Failure message is nil. Does your matcher define the " \ + "appropriate failure_message[_when_negated] method to return a string?" + end + + message = ::RSpec::Matchers::MultiMatcherDiff.from(expected, actual).message_with_diff(message, differ) + + RSpec::Support.notify_failure(RSpec::Expectations::ExpectationNotMetError.new message) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb new file mode 100644 index 0000000..b573bba --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb @@ -0,0 +1,236 @@ +module RSpec + module Expectations + # @private + class FailureAggregator + attr_reader :block_label, :metadata + + # @private + class AggregatedFailure + # :nocov: + # `inspect` was apparently used by some versions early in ruby 3 while constructing + # NoMethodError, but seems to be no longer. + # + # @private + MESSAGE = + 'AggregatedFailure: This method caused a failure which has been ' \ + 'suppressed to be aggregated into our failure report by returning ' \ + 'this value, further errors can be ignored.' + + def inspect + MESSAGE + end + # :nocov: + end + + AGGREGATED_FAILURE = AggregatedFailure.new + + def aggregate + RSpec::Support.with_failure_notifier(self) do + begin + yield + rescue ExpectationNotMetError => e + # Normally, expectation failures will be notified via the `call` method, below, + # but since the failure notifier uses a thread local variable, failing expectations + # in another thread will still raise. We handle that here and categorize it as part + # of `failures` rather than letting it fall through and be categorized as part of + # `other_errors`. + failures << e + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + # While it is normally a bad practice to rescue `Exception`, it's important we do + # so here. It's low risk (`notify_aggregated_failures` below will re-raise the exception, + # or raise a `MultipleExpectationsNotMetError` that includes the exception), and it's + # essential that the user is notified of expectation failures that may have already + # occurred in the `aggregate_failures` block. Those expectation failures may provide + # important diagnostics for understanding why this exception occurred, and if we simply + # allowed this exception to be raised as-is, it would (wrongly) suggest to the user + # that the expectation passed when it did not, which would be quite confusing. + other_errors << e + end + end + + notify_aggregated_failures + end + + def failures + @failures ||= [] + end + + def other_errors + @other_errors ||= [] + end + + # This method is defined to satisfy the callable interface + # expected by `RSpec::Support.with_failure_notifier`. + def call(failure, options) + source_id = options[:source_id] + return if source_id && @seen_source_ids.key?(source_id) + + @seen_source_ids[source_id] = true + assign_backtrace(failure) unless failure.backtrace + failures << failure + + AGGREGATED_FAILURE + end + + private + + if RSpec::Support::Ruby.jruby? && RSpec::Support::Ruby.jruby_version < '9.2.0.0' + # On JRuby 9.1.x.x and before, `caller` and `raise` produce different backtraces with + # regards to `.java` stack frames. It's important that we use `raise` for JRuby to produce + # a backtrace that has a continuous common section with the raised `MultipleExpectationsNotMetError`, + # so that rspec-core's truncation logic can work properly on it to list the backtrace + # relative to the `aggregate_failures` block. + # :nocov: + def assign_backtrace(failure) + raise failure + rescue failure.class => e + failure.set_backtrace(e.backtrace) + end + # :nocov: + else + # Using `caller` performs better (and is simpler) than `raise` on most Rubies. + def assign_backtrace(failure) + failure.set_backtrace(caller) + end + end + + def initialize(block_label, metadata) + @block_label = block_label + @metadata = metadata + @seen_source_ids = {} # don't want to load stdlib set + end + + def notify_aggregated_failures + all_errors = failures + other_errors + + case all_errors.size + when 0 then return true + when 1 then RSpec::Support.notify_failure all_errors.first + else RSpec::Support.notify_failure MultipleExpectationsNotMetError.new(self) + end + end + end + + # Exception raised from `aggregate_failures` when multiple expectations fail. + class MultipleExpectationsNotMetError + # @return [String] The fully formatted exception message. + def message + @message ||= (["#{summary}:"] + enumerated_failures + enumerated_errors).join("\n\n") + end + + # @return [Array] The list of expectation failures. + def failures + @failure_aggregator.failures + end + + # @return [Array] The list of other exceptions. + def other_errors + @failure_aggregator.other_errors + end + + # @return [Array] The list of expectation failures and other exceptions, combined. + attr_reader :all_exceptions + + # @return [String] The user-assigned label for the aggregation block. + def aggregation_block_label + @failure_aggregator.block_label + end + + # @return [Hash] The metadata hash passed to `aggregate_failures`. + def aggregation_metadata + @failure_aggregator.metadata + end + + # @return [String] A summary of the failure, including the block label and a count of failures. + def summary + "Got #{exception_count_description} from failure aggregation " \ + "block#{block_description}" + end + + # return [String] A description of the failure/error counts. + def exception_count_description + failure_count = pluralize("failure", failures.size) + return failure_count if other_errors.empty? + error_count = pluralize("other error", other_errors.size) + "#{failure_count} and #{error_count}" + end + + private + + def initialize(failure_aggregator) + @failure_aggregator = failure_aggregator + @all_exceptions = failures + other_errors + end + + def block_description + return "" unless aggregation_block_label + " #{aggregation_block_label.inspect}" + end + + def pluralize(noun, count) + "#{count} #{noun}#{'s' unless count == 1}" + end + + def enumerated(exceptions, index_offset) + exceptions.each_with_index.map do |exception, index| + index += index_offset + formatted_message = "#{yield exception}\n#{format_backtrace(exception.backtrace).first}" + "#{index_label index}#{indented formatted_message, index}" + end + end + + def exclusion_patterns + patterns = %w[/lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle:] + patterns << "org/jruby/" if RSpec::Support::Ruby.jruby? + patterns.map! { |s| Regexp.new(s.gsub('/', File::SEPARATOR)) } + end + + def format_backtrace(backtrace) + backtrace.map { |l| backtrace_line(l) }.compact.tap { |filtered| filtered.concat backtrace if filtered.empty? } + end + + def backtrace_line(line) + return if [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *exclusion_patterns)].any? { |p| line =~ p } + + # It changes the current path that is relative to + # system root to be relative to the project root. + line.sub(/(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/, '\\1.\\2'.freeze).sub(/\A([^:]+:\d+)$/, '\\1'.freeze) + end + + def enumerated_failures + enumerated(failures, 0, &:message) + end + + def enumerated_errors + enumerated(other_errors, failures.size) do |error| + "#{error.class}: #{error.message}" + end + end + + def indented(failure_message, index) + line_1, *rest = failure_message.strip.lines.to_a + first_line_indentation = ' ' * (longest_index_label_width - width_of_label(index)) + + first_line_indentation + line_1 + rest.map do |line| + line =~ /\S/ ? indentation + line : line + end.join + end + + def indentation + @indentation ||= ' ' * longest_index_label_width + end + + def longest_index_label_width + @longest_index_label_width ||= width_of_label(failures.size) + end + + def width_of_label(index) + index_label(index).chars.count + end + + def index_label(index) + " #{index + 1}) " + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb new file mode 100644 index 0000000..d86061a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb @@ -0,0 +1,181 @@ +module RSpec + module Expectations + # @private + module ExpectationHelper + def self.check_message(msg) + unless msg.nil? || msg.respond_to?(:to_str) || msg.respond_to?(:call) + RSpec.warning( + "ignoring the provided expectation message argument" \ + "(#{ msg.inspect }) since it is not a string or a proc" + ) + end + end + + # Returns an RSpec-3+ compatible matcher, wrapping a legacy one + # in an adapter if necessary. + # + # @private + def self.modern_matcher_from(matcher) + LegacyMatcherAdapter::RSpec2.wrap(matcher) || + LegacyMatcherAdapter::RSpec1.wrap(matcher) || matcher + end + + def self.with_matcher(handler, matcher, message) + check_message(message) + matcher = modern_matcher_from(matcher) + yield matcher + ensure + ::RSpec::Matchers.last_expectation_handler = handler + ::RSpec::Matchers.last_matcher = matcher + end + + def self.handle_failure(matcher, message, failure_message_method) + message = message.call if message.respond_to?(:call) + message ||= matcher.__send__(failure_message_method) + + if matcher.respond_to?(:diffable?) && matcher.diffable? + ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual + else + ::RSpec::Expectations.fail_with message + end + end + end + + # @private + class PositiveExpectationHandler + def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) + ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| + return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) unless initial_matcher + + match_result = matcher.matches?(actual, &block) + if custom_message && match_result.respond_to?(:error_generator) + match_result.error_generator.opts[:message] = custom_message + end + + match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message) + end + end + + def self.verb + 'is expected to' + end + + def self.should_method + :should + end + + def self.opposite_should_method + :should_not + end + end + + # @private + class NegativeExpectationHandler + def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) + ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| + return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) unless initial_matcher + + negated_match_result = does_not_match?(matcher, actual, &block) + if custom_message && negated_match_result.respond_to?(:error_generator) + negated_match_result.error_generator.opts[:message] = custom_message + end + + negated_match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message_when_negated) + end + end + + def self.does_not_match?(matcher, actual, &block) + if matcher.respond_to?(:does_not_match?) + matcher.does_not_match?(actual, &block) + else + !matcher.matches?(actual, &block) + end + end + + def self.verb + 'is expected not to' + end + + def self.should_method + :should_not + end + + def self.opposite_should_method + :should + end + end + + # Wraps a matcher written against one of the legacy protocols in + # order to present the current protocol. + # + # @private + class LegacyMatcherAdapter < Matchers::MatcherDelegator + def initialize(matcher) + super + ::RSpec.warn_deprecation(<<-EOS.gsub(/^\s+\|/, ''), :type => "legacy_matcher") + |#{matcher.class.name || matcher.inspect} implements a legacy RSpec matcher + |protocol. For the current protocol you should expose the failure messages + |via the `failure_message` and `failure_message_when_negated` methods. + |(Used from #{CallerFilter.first_non_rspec_line}) + EOS + end + + def self.wrap(matcher) + new(matcher) if interface_matches?(matcher) + end + + # Starting in RSpec 1.2 (and continuing through all 2.x releases), + # the failure message protocol was: + # * `failure_message_for_should` + # * `failure_message_for_should_not` + # @private + class RSpec2 < self + def failure_message + base_matcher.failure_message_for_should + end + + def failure_message_when_negated + base_matcher.failure_message_for_should_not + end + + def self.interface_matches?(matcher) + ( + !matcher.respond_to?(:failure_message) && + matcher.respond_to?(:failure_message_for_should) + ) || ( + !matcher.respond_to?(:failure_message_when_negated) && + matcher.respond_to?(:failure_message_for_should_not) + ) + end + end + + # Before RSpec 1.2, the failure message protocol was: + # * `failure_message` + # * `negative_failure_message` + # @private + class RSpec1 < self + def failure_message + base_matcher.failure_message + end + + def failure_message_when_negated + base_matcher.negative_failure_message + end + + # Note: `failure_message` is part of the RSpec 3 protocol + # (paired with `failure_message_when_negated`), so we don't check + # for `failure_message` here. + def self.interface_matches?(matcher) + !matcher.respond_to?(:failure_message_when_negated) && + matcher.respond_to?(:negative_failure_message) + end + end + end + + # RSpec 3.0 was released with the class name misspelled. For SemVer compatibility, + # we will provide this misspelled alias until 4.0. + # @deprecated Use LegacyMatcherAdapter instead. + # @private + LegacyMacherAdapter = LegacyMatcherAdapter + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb new file mode 100644 index 0000000..94cdb5f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb @@ -0,0 +1,58 @@ +require 'rspec/expectations' + +Minitest::Test.class_eval do + include ::RSpec::Matchers + + # This `expect` will only be called if the user is using Minitest < 5.6 + # or if they are _not_ using Minitest::Spec on 5.6+. Minitest::Spec on 5.6+ + # defines its own `expect` and will have the assertions incremented via our + # definitions of `to`/`not_to`/`to_not` below. + def expect(*a, &b) + self.assertions += 1 + super + end + + # Convert a `MultipleExpectationsNotMetError` to a `Minitest::Assertion` error so + # it gets counted in minitest's summary stats as a failure rather than an error. + # It would be nice to make `MultipleExpectationsNotMetError` subclass + # `Minitest::Assertion`, but Minitest's implementation does not treat subclasses + # the same, so this is the best we can do. + def aggregate_failures(*args, &block) + super + rescue RSpec::Expectations::MultipleExpectationsNotMetError => e + assertion_failed = Minitest::Assertion.new(e.message) + assertion_failed.set_backtrace e.backtrace + raise assertion_failed + end +end + +# Older versions of Minitest (e.g. before 5.6) do not define +# `Minitest::Expectation`. +if defined?(::Minitest::Expectation) + Minitest::Expectation.class_eval do + include RSpec::Expectations::ExpectationTarget::InstanceMethods + + def to(*args) + ctx.assertions += 1 + super + end + + def not_to(*args) + ctx.assertions += 1 + super + end + + def to_not(*args) + ctx.assertions += 1 + super + end + end +end + +module RSpec + module Expectations + remove_const :ExpectationNotMetError + # Exception raised when an expectation fails. + const_set :ExpectationNotMetError, ::Minitest::Assertion + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb new file mode 100644 index 0000000..b843034 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb @@ -0,0 +1,132 @@ +module RSpec + module Expectations + # @api private + # Provides methods for enabling and disabling the available + # syntaxes provided by rspec-expectations. + module Syntax + module_function + + # @api private + # Determines where we add `should` and `should_not`. + def default_should_host + @default_should_host ||= ::Object.ancestors.last + end + + # @api private + # Instructs rspec-expectations to warn on first usage of `should` or `should_not`. + # Enabled by default. This is largely here to facilitate testing. + def warn_about_should! + @warn_about_should = true + end + + # @api private + # Generates a deprecation warning for the given method if no warning + # has already been issued. + def warn_about_should_unless_configured(method_name) + return unless @warn_about_should + + RSpec.deprecate( + "Using `#{method_name}` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax", + :replacement => "the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }`" + ) + + @warn_about_should = false + end + + # @api private + # Enables the `should` syntax. + def enable_should(syntax_host=default_should_host) + @warn_about_should = false if syntax_host == default_should_host + return if should_enabled?(syntax_host) + + syntax_host.module_exec do + def should(matcher=nil, message=nil, &block) + ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) + ::RSpec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block) + end + + def should_not(matcher=nil, message=nil, &block) + ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) + ::RSpec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block) + end + end + end + + # @api private + # Disables the `should` syntax. + def disable_should(syntax_host=default_should_host) + return unless should_enabled?(syntax_host) + + syntax_host.module_exec do + undef should + undef should_not + end + end + + # @api private + # Enables the `expect` syntax. + def enable_expect(syntax_host=::RSpec::Matchers) + return if expect_enabled?(syntax_host) + + syntax_host.module_exec do + def expect(value=::RSpec::Expectations::ExpectationTarget::UndefinedValue, &block) + ::RSpec::Expectations::ExpectationTarget.for(value, block) + end + end + end + + # @api private + # Disables the `expect` syntax. + def disable_expect(syntax_host=::RSpec::Matchers) + return unless expect_enabled?(syntax_host) + + syntax_host.module_exec do + undef expect + end + end + + # @api private + # Indicates whether or not the `should` syntax is enabled. + def should_enabled?(syntax_host=default_should_host) + syntax_host.method_defined?(:should) + end + + # @api private + # Indicates whether or not the `expect` syntax is enabled. + def expect_enabled?(syntax_host=::RSpec::Matchers) + syntax_host.method_defined?(:expect) + end + end + end +end + +if defined?(BasicObject) + # The legacy `:should` syntax adds the following methods directly to + # `BasicObject` so that they are available off of any object. Note, however, + # that this syntax does not always play nice with delegate/proxy objects. + # We recommend you use the non-monkeypatching `:expect` syntax instead. + class BasicObject + # @method should(matcher, message) + # Passes if `matcher` returns true. Available on every `Object`. + # @example + # actual.should eq expected + # actual.should match /expression/ + # @param [Matcher] + # matcher + # @param [String] message optional message to display when the expectation fails + # @return [Boolean] true if the expectation succeeds (else raises) + # @note This is only available when you have enabled the `:should` syntax. + # @see RSpec::Matchers + + # @method should_not(matcher, message) + # Passes if `matcher` returns false. Available on every `Object`. + # @example + # actual.should_not eq expected + # @param [Matcher] + # matcher + # @param [String] message optional message to display when the expectation fails + # @return [Boolean] false if the negative expectation succeeds (else raises) + # @note This is only available when you have enabled the `:should` syntax. + # @see RSpec::Matchers + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb new file mode 100644 index 0000000..0fc9ef9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb @@ -0,0 +1,8 @@ +module RSpec + module Expectations + # @private + module Version + STRING = '3.13.5' + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb new file mode 100644 index 0000000..d5347d1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb @@ -0,0 +1,1046 @@ +require 'rspec/support' +RSpec::Support.require_rspec_support 'matcher_definition' +RSpec::Support.define_optimized_require_for_rspec(:matchers) { |f| require_relative(f) } + +%w[ + english_phrasing + composable + built_in + generated_descriptions + dsl + matcher_delegator + aliased_matcher + multi_matcher_diff +].each { |file| RSpec::Support.require_rspec_matchers(file) } + +# RSpec's top level namespace. All of rspec-expectations is contained +# in the `RSpec::Expectations` and `RSpec::Matchers` namespaces. +module RSpec + # RSpec::Matchers provides a number of useful matchers we use to define + # expectations. Any object that implements the [matcher protocol](Matchers/MatcherProtocol) + # can be used as a matcher. + # + # ## Predicates + # + # In addition to matchers that are defined explicitly, RSpec will create + # custom matchers on the fly for any arbitrary predicate, giving your specs a + # much more natural language feel. + # + # A Ruby predicate is a method that ends with a "?" and returns true or false. + # Common examples are `empty?`, `nil?`, and `instance_of?`. + # + # All you need to do is write `expect(..).to be_` followed by the predicate + # without the question mark, and RSpec will figure it out from there. + # For example: + # + # expect([]).to be_empty # => [].empty?() | passes + # expect([]).not_to be_empty # => [].empty?() | fails + # + # In addition to prefixing the predicate matchers with "be_", you can also use "be_a_" + # and "be_an_", making your specs read much more naturally: + # + # expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes + # + # expect(3).to be_a_kind_of(Integer) # => 3.kind_of?(Numeric) | passes + # expect(3).to be_a_kind_of(Numeric) # => 3.kind_of?(Numeric) | passes + # expect(3).to be_an_instance_of(Integer) # => 3.instance_of?(Integer) | passes + # expect(3).not_to be_an_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails + # + # RSpec will also create custom matchers for predicates like `has_key?`. To + # use this feature, just state that the object should have_key(:key) and RSpec will + # call has_key?(:key) on the target. For example: + # + # expect(:a => "A").to have_key(:a) + # expect(:a => "A").to have_key(:b) # fails + # + # You can use this feature to invoke any predicate that begins with "has_", whether it is + # part of the Ruby libraries (like `Hash#has_key?`) or a method you wrote on your own class. + # + # Note that RSpec does not provide composable aliases for these dynamic predicate + # matchers. You can easily define your own aliases, though: + # + # RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin + # expect(user_list).to include(a_user_who_is_an_admin) + # + # ## Alias Matchers + # + # With {RSpec::Matchers.alias_matcher}, you can easily create an + # alternate name for a given matcher. + # + # The description will also change according to the new name: + # + # RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to + # sum_to(3).description # => "sum to 3" + # a_list_that_sums_to(3).description # => "a list that sums to 3" + # + # or you can specify a custom description like this: + # + # RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description| + # description.sub("be sorted by", "a list sorted by") + # end + # + # be_sorted_by(:age).description # => "be sorted by age" + # a_list_sorted_by(:age).description # => "a list sorted by age" + # + # ## Custom Matchers + # + # When you find that none of the stock matchers provide a natural feeling + # expectation, you can very easily write your own using RSpec's matcher DSL + # or writing one from scratch. + # + # ### Matcher DSL + # + # Imagine that you are writing a game in which players can be in various + # zones on a virtual board. To specify that bob should be in zone 4, you + # could say: + # + # expect(bob.current_zone).to eql(Zone.new("4")) + # + # But you might find it more expressive to say: + # + # expect(bob).to be_in_zone("4") + # + # and/or + # + # expect(bob).not_to be_in_zone("3") + # + # You can create such a matcher like so: + # + # RSpec::Matchers.define :be_in_zone do |zone| + # match do |player| + # player.in_zone?(zone) + # end + # end + # + # This will generate a be_in_zone method that returns a matcher + # with logical default messages for failures. You can override the failure + # messages and the generated description as follows: + # + # RSpec::Matchers.define :be_in_zone do |zone| + # match do |player| + # player.in_zone?(zone) + # end + # + # failure_message do |player| + # # generate and return the appropriate string. + # end + # + # failure_message_when_negated do |player| + # # generate and return the appropriate string. + # end + # + # description do + # # generate and return the appropriate string. + # end + # end + # + # Each of the message-generation methods has access to the block arguments + # passed to the create method (in this case, zone). The + # failure message methods (failure_message and + # failure_message_when_negated) are passed the actual value (the + # receiver of expect(..) or expect(..).not_to). + # + # ### Custom Matcher from scratch + # + # You could also write a custom matcher from scratch, as follows: + # + # class BeInZone + # def initialize(expected) + # @expected = expected + # end + # + # def matches?(target) + # @target = target + # @target.current_zone.eql?(Zone.new(@expected)) + # end + # + # def failure_message + # "expected #{@target.inspect} to be in Zone #{@expected}" + # end + # + # def failure_message_when_negated + # "expected #{@target.inspect} not to be in Zone #{@expected}" + # end + # end + # + # ... and a method like this: + # + # def be_in_zone(expected) + # BeInZone.new(expected) + # end + # + # And then expose the method to your specs. This is normally done + # by including the method and the class in a module, which is then + # included in your spec: + # + # module CustomGameMatchers + # class BeInZone + # # ... + # end + # + # def be_in_zone(expected) + # # ... + # end + # end + # + # describe "Player behaviour" do + # include CustomGameMatchers + # # ... + # end + # + # or you can include in globally in a spec_helper.rb file required + # from your spec file(s): + # + # RSpec::configure do |config| + # config.include(CustomGameMatchers) + # end + # + # ### Making custom matchers composable + # + # RSpec's built-in matchers are designed to be composed, in expressions like: + # + # expect(["barn", 2.45]).to contain_exactly( + # a_value_within(0.1).of(2.5), + # a_string_starting_with("bar") + # ) + # + # Custom matchers can easily participate in composed matcher expressions like these. + # Include {RSpec::Matchers::Composable} in your custom matcher to make it support + # being composed (matchers defined using the DSL have this included automatically). + # Within your matcher's `matches?` method (or the `match` block, if using the DSL), + # use `values_match?(expected, actual)` rather than `expected == actual`. + # Under the covers, `values_match?` is able to match arbitrary + # nested data structures containing a mix of both matchers and non-matcher objects. + # It uses `===` and `==` to perform the matching, considering the values to + # match if either returns `true`. The `Composable` mixin also provides some helper + # methods for surfacing the matcher descriptions within your matcher's description + # or failure messages. + # + # RSpec's built-in matchers each have a number of aliases that rephrase the matcher + # from a verb phrase (such as `be_within`) to a noun phrase (such as `a_value_within`), + # which reads better when the matcher is passed as an argument in a composed matcher + # expressions, and also uses the noun-phrase wording in the matcher's `description`, + # for readable failure messages. You can alias your custom matchers in similar fashion + # using {RSpec::Matchers.alias_matcher}. + # + # ## Negated Matchers + # + # Sometimes if you want to test for the opposite using a more descriptive name + # instead of using `not_to`, you can use {RSpec::Matchers.define_negated_matcher}: + # + # RSpec::Matchers.define_negated_matcher :exclude, :include + # include(1, 2).description # => "include 1 and 2" + # exclude(1, 2).description # => "exclude 1 and 2" + # + # While the most obvious negated form may be to add a `not_` prefix, + # the failure messages you get with that form can be confusing (e.g. + # "expected [actual] to not [verb], but did not"). We've found it works + # best to find a more positive name for the negated form, such as + # `avoid_changing` rather than `not_change`. + # + module Matchers # rubocop:disable Metrics/ModuleLength + extend ::RSpec::Matchers::DSL + + # @!macro [attach] alias_matcher + # @!parse + # alias $1 $2 + # @!visibility private + # We define this override here so we can attach a YARD macro to it. + # It ensures that our docs list all the matcher aliases. + def self.alias_matcher(*args, &block) + super(*args, &block) + end + + # @!method self.alias_matcher(new_name, old_name, options={}, &description_override) + # Extended from {RSpec::Matchers::DSL#alias_matcher}. + + # @!method self.define(name, &declarations) + # Extended from {RSpec::Matchers::DSL#define}. + + # @!method self.define_negated_matcher(negated_name, base_name, &description_override) + # Extended from {RSpec::Matchers::DSL#define_negated_matcher}. + + # @method expect + # Supports `expect(actual).to matcher` syntax by wrapping `actual` in an + # `ExpectationTarget`. + # @example + # expect(actual).to eq(expected) + # expect(actual).not_to eq(expected) + # @return [Expectations::ExpectationTarget] + # @see Expectations::ExpectationTarget#to + # @see Expectations::ExpectationTarget#not_to + + # Allows multiple expectations in the provided block to fail, and then + # aggregates them into a single exception, rather than aborting on the + # first expectation failure like normal. This allows you to see all + # failures from an entire set of expectations without splitting each + # off into its own example (which may slow things down if the example + # setup is expensive). + # + # @param label [String] label for this aggregation block, which will be + # included in the aggregated exception message. + # @param metadata [Hash] additional metadata about this failure aggregation + # block. If multiple expectations fail, it will be exposed from the + # {Expectations::MultipleExpectationsNotMetError} exception. Mostly + # intended for internal RSpec use but you can use it as well. + # @yield Block containing as many expectation as you want. The block is + # simply yielded to, so you can trust that anything that works outside + # the block should work within it. + # @raise [Expectations::MultipleExpectationsNotMetError] raised when + # multiple expectations fail. + # @raise [Expectations::ExpectationNotMetError] raised when a single + # expectation fails. + # @raise [Exception] other sorts of exceptions will be raised as normal. + # + # @example + # aggregate_failures("verifying response") do + # expect(response.status).to eq(200) + # expect(response.headers).to include("Content-Type" => "text/plain") + # expect(response.body).to include("Success") + # end + # + # @note The implementation of this feature uses a thread-local variable, + # which means that if you have an expectation failure in another thread, + # it'll abort like normal. + def aggregate_failures(label=nil, metadata={}, &block) + Expectations::FailureAggregator.new(label, metadata).aggregate(&block) + end + + # Passes if actual is truthy (anything but false or nil) + def be_truthy + BuiltIn::BeTruthy.new + end + alias_matcher :a_truthy_value, :be_truthy + + # Passes if actual is falsey (false or nil) + def be_falsey + BuiltIn::BeFalsey.new + end + alias_matcher :be_falsy, :be_falsey + alias_matcher :a_falsey_value, :be_falsey + alias_matcher :a_falsy_value, :be_falsey + + # Passes if actual is nil + def be_nil + BuiltIn::BeNil.new + end + alias_matcher :a_nil_value, :be_nil + + # @example + # expect(actual).to be_truthy + # expect(actual).to be_falsey + # expect(actual).to be_nil + # expect(actual).to be_[arbitrary_predicate](*args) + # expect(actual).not_to be_nil + # expect(actual).not_to be_[arbitrary_predicate](*args) + # + # Given true, false, or nil, will pass if actual value is true, false or + # nil (respectively). Given no args means the caller should satisfy an if + # condition (to be or not to be). + # + # Predicates are any Ruby method that ends in a "?" and returns true or + # false. Given be_ followed by arbitrary_predicate (without the "?"), + # RSpec will match convert that into a query against the target object. + # + # The arbitrary_predicate feature will handle any predicate prefixed with + # "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of) or "be_" + # (e.g. be_empty), letting you choose the prefix that best suits the + # predicate. + def be(*args) + args.empty? ? Matchers::BuiltIn::Be.new : equal(*args) + end + alias_matcher :a_value, :be, :klass => AliasedMatcherWithOperatorSupport + + # passes if target.kind_of?(klass) + def be_a(klass) + be_a_kind_of(klass) + end + alias_method :be_an, :be_a + + # Passes if actual.instance_of?(expected) + # + # @example + # expect(5).to be_an_instance_of(Integer) + # expect(5).not_to be_an_instance_of(Numeric) + # expect(5).not_to be_an_instance_of(Float) + def be_an_instance_of(expected) + BuiltIn::BeAnInstanceOf.new(expected) + end + alias_method :be_instance_of, :be_an_instance_of + alias_matcher :an_instance_of, :be_an_instance_of + + # Passes if actual.kind_of?(expected) + # + # @example + # expect(5).to be_a_kind_of(Integer) + # expect(5).to be_a_kind_of(Numeric) + # expect(5).not_to be_a_kind_of(Float) + def be_a_kind_of(expected) + BuiltIn::BeAKindOf.new(expected) + end + alias_method :be_kind_of, :be_a_kind_of + alias_matcher :a_kind_of, :be_a_kind_of + + # Passes if actual.between?(min, max). Works with any Comparable object, + # including String, Symbol, Time, or Numeric (Fixnum, Bignum, Integer, + # Float, Complex, and Rational). + # + # By default, `be_between` is inclusive (i.e. passes when given either the max or min value), + # but you can make it `exclusive` by chaining that off the matcher. + # + # @example + # expect(5).to be_between(1, 10) + # expect(11).not_to be_between(1, 10) + # expect(10).not_to be_between(1, 10).exclusive + def be_between(min, max) + BuiltIn::BeBetween.new(min, max) + end + alias_matcher :a_value_between, :be_between + + # Passes if actual == expected +/- delta + # + # @example + # expect(result).to be_within(0.5).of(3.0) + # expect(result).not_to be_within(0.5).of(3.0) + def be_within(delta) + BuiltIn::BeWithin.new(delta) + end + alias_matcher :a_value_within, :be_within + alias_matcher :within, :be_within + + # Applied to a proc, specifies that its execution will cause some value to + # change. + # + # @param [Object] receiver + # @param [Symbol] message the message to send the receiver + # + # You can either pass receiver and message, or a block, + # but not both. + # + # When passing a block, it must use the `{ ... }` format, not + # do/end, as `{ ... }` binds to the `change` method, whereas do/end + # would errantly bind to the `expect(..).to` or `expect(...).not_to` method. + # + # You can chain any of the following off of the end to specify details + # about the change: + # + # * `from` + # * `to` + # + # or any one of: + # + # * `by` + # * `by_at_least` + # * `by_at_most` + # + # @example + # expect { + # team.add_player(player) + # }.to change(roster, :count) + # + # expect { + # team.add_player(player) + # }.to change(roster, :count).by(1) + # + # expect { + # team.add_player(player) + # }.to change(roster, :count).by_at_least(1) + # + # expect { + # team.add_player(player) + # }.to change(roster, :count).by_at_most(1) + # + # string = "string" + # expect { + # string.reverse! + # }.to change { string }.from("string").to("gnirts") + # + # string = "string" + # expect { + # string + # }.not_to change { string }.from("string") + # + # expect { + # person.happy_birthday + # }.to change(person, :birthday).from(32).to(33) + # + # expect { + # employee.develop_great_new_social_networking_app + # }.to change(employee, :title).from("Mail Clerk").to("CEO") + # + # expect { + # doctor.leave_office + # }.to change(doctor, :sign).from(/is in/).to(/is out/) + # + # user = User.new(:type => "admin") + # expect { + # user.symbolize_type + # }.to change(user, :type).from(String).to(Symbol) + # + # == Notes + # + # Evaluates `receiver.message` or `block` before and after it + # evaluates the block passed to `expect`. If the value is the same + # object, its before/after `hash` value is used to see if it has changed. + # Therefore, your object needs to properly implement `hash` to work correctly + # with this matcher. + # + # `expect( ... ).not_to change` supports the form that specifies `from` + # (which specifies what you expect the starting, unchanged value to be) + # but does not support forms with subsequent calls to `by`, `by_at_least`, + # `by_at_most` or `to`. + def change(receiver=nil, message=nil, &block) + BuiltIn::Change.new(receiver, message, &block) + end + alias_matcher :a_block_changing, :change + alias_matcher :changing, :change + + # Passes if actual contains all of the expected regardless of order. + # This works for collections. Pass in multiple args and it will only + # pass if all args are found in collection. + # + # @note This is also available using the `=~` operator with `should`, + # but `=~` is not supported with `expect`. + # + # @example + # expect([1, 2, 3]).to contain_exactly(1, 2, 3) + # expect([1, 2, 3]).to contain_exactly(1, 3, 2) + # + # @see #match_array + def contain_exactly(*items) + BuiltIn::ContainExactly.new(items) + end + alias_matcher :a_collection_containing_exactly, :contain_exactly + alias_matcher :containing_exactly, :contain_exactly + + # Passes if actual covers expected. This works for + # Ranges. You can also pass in multiple args + # and it will only pass if all args are found in Range. + # + # @example + # expect(1..10).to cover(5) + # expect(1..10).to cover(4, 6) + # expect(1..10).to cover(4, 6, 11) # fails + # expect(1..10).not_to cover(11) + # expect(1..10).not_to cover(5) # fails + # + # ### Warning:: Ruby >= 1.9 only + def cover(*values) + BuiltIn::Cover.new(*values) + end + alias_matcher :a_range_covering, :cover + alias_matcher :covering, :cover + + # Matches if the actual value ends with the expected value(s). In the case + # of a string, matches against the last `expected.length` characters of the + # actual string. In the case of an array, matches against the last + # `expected.length` elements of the actual array. + # + # @example + # expect("this string").to end_with "string" + # expect([0, 1, 2, 3, 4]).to end_with 4 + # expect([0, 2, 3, 4, 4]).to end_with 3, 4 + def end_with(*expected) + BuiltIn::EndWith.new(*expected) + end + alias_matcher :a_collection_ending_with, :end_with + alias_matcher :a_string_ending_with, :end_with + alias_matcher :ending_with, :end_with + + # Passes if actual == expected. + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more + # information about equality in Ruby. + # + # @example + # expect(5).to eq(5) + # expect(5).not_to eq(3) + def eq(expected) + BuiltIn::Eq.new(expected) + end + alias_matcher :an_object_eq_to, :eq + alias_matcher :eq_to, :eq + + # Passes if `actual.eql?(expected)` + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more + # information about equality in Ruby. + # + # @example + # expect(5).to eql(5) + # expect(5).not_to eql(3) + def eql(expected) + BuiltIn::Eql.new(expected) + end + alias_matcher :an_object_eql_to, :eql + alias_matcher :eql_to, :eql + + # Passes if actual.equal?(expected) (object identity). + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more + # information about equality in Ruby. + # + # @example + # expect(5).to equal(5) # Integers are equal + # expect("5").not_to equal("5") # Strings that look the same are not the same object + def equal(expected) + BuiltIn::Equal.new(expected) + end + alias_matcher :an_object_equal_to, :equal + alias_matcher :equal_to, :equal + + # Passes if `actual.exist?` or `actual.exists?` + # + # @example + # expect(File).to exist("path/to/file") + def exist(*args) + BuiltIn::Exist.new(*args) + end + alias_matcher :an_object_existing, :exist + alias_matcher :existing, :exist + + # Passes if actual's attribute values match the expected attributes hash. + # This works no matter how you define your attribute readers. + # + # @example + # Person = Struct.new(:name, :age) + # person = Person.new("Bob", 32) + # + # expect(person).to have_attributes(:name => "Bob", :age => 32) + # expect(person).to have_attributes(:name => a_string_starting_with("B"), :age => (a_value > 30) ) + # + # @note It will fail if actual doesn't respond to any of the expected attributes. + # + # @example + # expect(person).to have_attributes(:color => "red") + def have_attributes(expected) + BuiltIn::HaveAttributes.new(expected) + end + alias_matcher :an_object_having_attributes, :have_attributes + alias_matcher :having_attributes, :have_attributes + + # Passes if actual includes expected. This works for + # collections and Strings. You can also pass in multiple args + # and it will only pass if all args are found in collection. + # + # @example + # expect([1,2,3]).to include(3) + # expect([1,2,3]).to include(2,3) + # expect([1,2,3]).to include(2,3,4) # fails + # expect([1,2,3]).not_to include(4) + # expect("spread").to include("read") + # expect("spread").not_to include("red") + # expect(:a => 1, :b => 2).to include(:a) + # expect(:a => 1, :b => 2).to include(:a, :b) + # expect(:a => 1, :b => 2).to include(:a => 1) + # expect(:a => 1, :b => 2).to include(:b => 2, :a => 1) + # expect(:a => 1, :b => 2).to include(:c) # fails + # expect(:a => 1, :b => 2).not_to include(:a => 2) + def include(*expected) + BuiltIn::Include.new(*expected) + end + alias_matcher :a_collection_including, :include + alias_matcher :a_string_including, :include + alias_matcher :a_hash_including, :include + alias_matcher :including, :include + + # Passes if the provided matcher passes when checked against all + # elements of the collection. + # + # @example + # expect([1, 3, 5]).to all be_odd + # expect([1, 3, 6]).to all be_odd # fails + # + # @note The negative form `not_to all` is not supported. Instead + # use `not_to include` or pass a negative form of a matcher + # as the argument (e.g. `all exclude(:foo)`). + # + # @note You can also use this with compound matchers as well. + # + # @example + # expect([1, 3, 5]).to all( be_odd.and be_an(Integer) ) + def all(expected) + BuiltIn::All.new(expected) + end + + # Given a `Regexp` or `String`, passes if `actual.match(pattern)` + # Given an arbitrary nested data structure (e.g. arrays and hashes), + # matches if `expected === actual` || `actual == expected` for each + # pair of elements. + # + # @example + # expect(email).to match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) + # expect(email).to match("@example.com") + # + # @example + # hash = { + # :a => { + # :b => ["foo", 5], + # :c => { :d => 2.05 } + # } + # } + # + # expect(hash).to match( + # :a => { + # :b => a_collection_containing_exactly( + # a_string_starting_with("f"), + # an_instance_of(Integer) + # ), + # :c => { :d => (a_value < 3) } + # } + # ) + # + # @note The `match_regex` alias is deprecated and is not recommended for use. + # It was added in 2.12.1 to facilitate its use from within custom + # matchers (due to how the custom matcher DSL was evaluated in 2.x, + # `match` could not be used there), but is no longer needed in 3.x. + def match(expected) + BuiltIn::Match.new(expected) + end + alias_matcher :match_regex, :match + alias_matcher :an_object_matching, :match + alias_matcher :a_string_matching, :match + alias_matcher :matching, :match + + # An alternate form of `contain_exactly` that accepts + # the expected contents as a single array arg rather + # than splatted out as individual items. + # + # @example + # expect(results).to contain_exactly(1, 2) + # # is identical to: + # expect(results).to match_array([1, 2]) + # + # @see #contain_exactly + def match_array(items) + contain_exactly(*items) + end + alias_matcher :an_array_matching, :match_array do |desc| + desc.sub("contain exactly", "an array containing exactly") + end + + # With no arg, passes if the block outputs `to_stdout` or `to_stderr`. + # With a string, passes if the block outputs that specific string `to_stdout` or `to_stderr`. + # With a regexp or matcher, passes if the block outputs a string `to_stdout` or `to_stderr` that matches. + # + # To capture output from any spawned subprocess as well, use `to_stdout_from_any_process` or + # `to_stderr_from_any_process`. Output from any process that inherits the main process's corresponding + # standard stream will be captured. + # + # @example + # expect { print 'foo' }.to output.to_stdout + # expect { print 'foo' }.to output('foo').to_stdout + # expect { print 'foo' }.to output(/foo/).to_stdout + # + # expect { do_something }.to_not output.to_stdout + # + # expect { warn('foo') }.to output.to_stderr + # expect { warn('foo') }.to output('foo').to_stderr + # expect { warn('foo') }.to output(/foo/).to_stderr + # + # expect { do_something }.to_not output.to_stderr + # + # expect { system('echo foo') }.to output("foo\n").to_stdout_from_any_process + # expect { system('echo foo', out: :err) }.to output("foo\n").to_stderr_from_any_process + # + # @note `to_stdout` and `to_stderr` work by temporarily replacing `$stdout` or `$stderr`, + # so they're not able to intercept stream output that explicitly uses `STDOUT`/`STDERR` + # or that uses a reference to `$stdout`/`$stderr` that was stored before the + # matcher was used. + # @note `to_stdout_from_any_process` and `to_stderr_from_any_process` use Tempfiles, and + # are thus significantly (~30x) slower than `to_stdout` and `to_stderr`. + def output(expected=nil) + BuiltIn::Output.new(expected) + end + alias_matcher :a_block_outputting, :output + + # With no args, matches if any error is raised. + # With a named error, matches only if that specific error is raised. + # With a named error and message specified as a String, matches only if both match. + # With a named error and message specified as a Regexp, matches only if both match. + # Pass an optional block to perform extra verifications on the exception matched + # + # @example + # expect { do_something_risky }.to raise_error + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError) + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError) { |error| expect(error.data).to eq 42 } + # expect { do_something_risky }.to raise_error { |error| expect(error.data).to eq 42 } + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, "that was too risky") + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, /oo ri/) + # expect { do_something_risky }.to raise_error("that was too risky") + # + # expect { do_something_risky }.not_to raise_error + def raise_error(error=BuiltIn::RaiseError::UndefinedValue, message=nil, &block) + BuiltIn::RaiseError.new(error, message, &block) + end + alias_method :raise_exception, :raise_error + + alias_matcher :a_block_raising, :raise_error do |desc| + desc.sub("raise", "a block raising") + end + + alias_matcher :raising, :raise_error do |desc| + desc.sub("raise", "raising") + end + + # Matches if the target object responds to all of the names + # provided. Names can be Strings or Symbols. + # + # @example + # expect("string").to respond_to(:length) + # + def respond_to(*names) + BuiltIn::RespondTo.new(*names) + end + alias_matcher :an_object_responding_to, :respond_to + alias_matcher :responding_to, :respond_to + + # Passes if the submitted block returns true. Yields target to the + # block. + # + # Generally speaking, this should be thought of as a last resort when + # you can't find any other way to specify the behaviour you wish to + # specify. + # + # If you do find yourself in such a situation, you could always write + # a custom matcher, which would likely make your specs more expressive. + # + # @param description [String] optional description to be used for this matcher. + # + # @example + # expect(5).to satisfy { |n| n > 3 } + # expect(5).to satisfy("be greater than 3") { |n| n > 3 } + def satisfy(description=nil, &block) + BuiltIn::Satisfy.new(description, &block) + end + alias_matcher :an_object_satisfying, :satisfy + alias_matcher :satisfying, :satisfy + + # Matches if the actual value starts with the expected value(s). In the + # case of a string, matches against the first `expected.length` characters + # of the actual string. In the case of an array, matches against the first + # `expected.length` elements of the actual array. + # + # @example + # expect("this string").to start_with "this s" + # expect([0, 1, 2, 3, 4]).to start_with 0 + # expect([0, 2, 3, 4, 4]).to start_with 0, 1 + def start_with(*expected) + BuiltIn::StartWith.new(*expected) + end + alias_matcher :a_collection_starting_with, :start_with + alias_matcher :a_string_starting_with, :start_with + alias_matcher :starting_with, :start_with + + # Given no argument, matches if a proc throws any Symbol. + # + # Given a Symbol, matches if the given proc throws the specified Symbol. + # + # Given a Symbol and an arg, matches if the given proc throws the + # specified Symbol with the specified arg. + # + # @example + # expect { do_something_risky }.to throw_symbol + # expect { do_something_risky }.to throw_symbol(:that_was_risky) + # expect { do_something_risky }.to throw_symbol(:that_was_risky, 'culprit') + # + # expect { do_something_risky }.not_to throw_symbol + # expect { do_something_risky }.not_to throw_symbol(:that_was_risky) + # expect { do_something_risky }.not_to throw_symbol(:that_was_risky, 'culprit') + def throw_symbol(expected_symbol=nil, expected_arg=nil) + BuiltIn::ThrowSymbol.new(expected_symbol, expected_arg) + end + + alias_matcher :a_block_throwing, :throw_symbol do |desc| + desc.sub("throw", "a block throwing") + end + + alias_matcher :throwing, :throw_symbol do |desc| + desc.sub("throw", "throwing") + end + + # Passes if the method called in the expect block yields, regardless + # of whether or not arguments are yielded. + # + # @example + # expect { |b| 5.tap(&b) }.to yield_control + # expect { |b| "a".to_sym(&b) }.not_to yield_control + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + def yield_control + BuiltIn::YieldControl.new + end + alias_matcher :a_block_yielding_control, :yield_control + alias_matcher :yielding_control, :yield_control + + # Passes if the method called in the expect block yields with + # no arguments. Fails if it does not yield, or yields with arguments. + # + # @example + # expect { |b| User.transaction(&b) }.to yield_with_no_args + # expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5` + # expect { |b| "a".to_sym(&b) }.not_to yield_with_no_args # because it does not yield + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + # @note This matcher is not designed for use with methods that yield + # multiple times. + def yield_with_no_args + BuiltIn::YieldWithNoArgs.new + end + alias_matcher :a_block_yielding_with_no_args, :yield_with_no_args + alias_matcher :yielding_with_no_args, :yield_with_no_args + + # Given no arguments, matches if the method called in the expect + # block yields with arguments (regardless of what they are or how + # many there are). + # + # Given arguments, matches if the method called in the expect block + # yields with arguments that match the given arguments. + # + # Argument matching is done using `===` (the case match operator) + # and `==`. If the expected and actual arguments match with either + # operator, the matcher will pass. + # + # @example + # expect { |b| 5.tap(&b) }.to yield_with_args # because #tap yields an arg + # expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5 + # expect { |b| 5.tap(&b) }.to yield_with_args(Integer) # because Integer === 5 + # expect { |b| File.open("f.txt", &b) }.to yield_with_args(/txt/) # because /txt/ === "f.txt" + # + # expect { |b| User.transaction(&b) }.not_to yield_with_args # because it yields no args + # expect { |b| 5.tap(&b) }.not_to yield_with_args(1, 2, 3) + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + # @note This matcher is not designed for use with methods that yield + # multiple times. + def yield_with_args(*args) + BuiltIn::YieldWithArgs.new(*args) + end + alias_matcher :a_block_yielding_with_args, :yield_with_args + alias_matcher :yielding_with_args, :yield_with_args + + # Designed for use with methods that repeatedly yield (such as + # iterators). Passes if the method called in the expect block yields + # multiple times with arguments matching those given. + # + # Argument matching is done using `===` (the case match operator) + # and `==`. If the expected and actual arguments match with either + # operator, the matcher will pass. + # + # @example + # expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) + # expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2]) + # expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2) + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + def yield_successive_args(*args) + BuiltIn::YieldSuccessiveArgs.new(*args) + end + alias_matcher :a_block_yielding_successive_args, :yield_successive_args + alias_matcher :yielding_successive_args, :yield_successive_args + + # Delegates to {RSpec::Expectations.configuration}. + # This is here because rspec-core's `expect_with` option + # looks for a `configuration` method on the mixin + # (`RSpec::Matchers`) to yield to a block. + # @return [RSpec::Expectations::Configuration] the configuration object + def self.configuration + Expectations.configuration + end + + private + + BE_PREDICATE_REGEX = /^(?:be_(?:an?_)?)(.*)/ + HAS_REGEX = /^(?:have_)(.*)/ + DYNAMIC_MATCHER_REGEX = Regexp.union(BE_PREDICATE_REGEX, HAS_REGEX) + + def method_missing(method, *args, &block) + case method.to_s + when BE_PREDICATE_REGEX + BuiltIn::BePredicate.new(method, *args, &block) + when HAS_REGEX + BuiltIn::Has.new(method, *args, &block) + else + super + end + end + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) + + if RUBY_VERSION.to_f >= 1.9 + def respond_to_missing?(method, *) + method =~ DYNAMIC_MATCHER_REGEX || super + end + else # for 1.8.7 + # :nocov: + def respond_to?(method, *) + method = method.to_s + method =~ DYNAMIC_MATCHER_REGEX || super + end + public :respond_to? + # :nocov: + end + + # @api private + def self.is_a_matcher?(obj) + return true if ::RSpec::Matchers::BuiltIn::BaseMatcher === obj + begin + return false if obj.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher) + rescue NoMethodError + # Some objects, like BasicObject, don't implemented standard + # reflection methods. + return false + end + return false unless obj.respond_to?(:matches?) + + obj.respond_to?(:failure_message) || + obj.respond_to?(:failure_message_for_should) # support legacy matchers + end + + ::RSpec::Support.register_matcher_definition do |obj| + is_a_matcher?(obj) + end + + # @api private + def self.is_a_describable_matcher?(obj) + is_a_matcher?(obj) && obj.respond_to?(:description) + end + + class << self + private + + if RSpec::Support::Ruby.mri? && RUBY_VERSION[0, 3] == '1.9' + # Note that `included` doesn't work for this because it is triggered + # _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather + # than _before_, like `append_features`. It's important we check this before + # in order to find the cases where it was already previously included. + # @api private + # :nocov: + def append_features(mod) + return super if mod < self # `mod < self` indicates a re-inclusion. + + subclasses = ObjectSpace.each_object(Class).select { |c| c < mod && c < self } + return super unless subclasses.any? + + subclasses.reject! { |s| subclasses.any? { |s2| s < s2 } } # Filter to the root ancestor. + subclasses = subclasses.map { |s| "`#{s}`" }.join(", ") + + RSpec.warning "`#{self}` has been included in a superclass (`#{mod}`) " \ + "after previously being included in subclasses (#{subclasses}), " \ + "which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \ + "(https://redmine.ruby-lang.org/issues/3351). To work around this, " \ + "either upgrade to MRI 2.0+, include a dup of the module (e.g. " \ + "`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \ + "before it is included in subclasses (#{subclasses}). See " \ + "https://github.com/rspec/rspec-expectations/issues/814 for more info" + + super + end + # :nocov: + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb new file mode 100644 index 0000000..c52c4c4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb @@ -0,0 +1,116 @@ +module RSpec + module Matchers + # Decorator that wraps a matcher and overrides `description` + # using the provided block in order to support an alias + # of a matcher. This is intended for use when composing + # matchers, so that you can use an expression like + # `include( a_value_within(0.1).of(3) )` rather than + # `include( be_within(0.1).of(3) )`, and have the corresponding + # description read naturally. + # + # @api private + class AliasedMatcher < MatcherDelegator + def initialize(base_matcher, description_block) + @description_block = description_block + super(base_matcher) + end + + # Forward messages on to the wrapped matcher. + # Since many matchers provide a fluent interface + # (e.g. `a_value_within(0.1).of(3)`), we need to wrap + # the returned value if it responds to `description`, + # so that our override can be applied when it is eventually + # used. + def method_missing(*) + return_val = super + return return_val unless RSpec::Matchers.is_a_matcher?(return_val) + self.class.new(return_val, @description_block) + end + + # Provides the description of the aliased matcher. Aliased matchers + # are designed to behave identically to the original matcher except + # for the description and failure messages. The description is different + # to reflect the aliased name. + # + # @api private + def description + @description_block.call(super) + end + + # Provides the failure_message of the aliased matcher. Aliased matchers + # are designed to behave identically to the original matcher except + # for the description and failure messages. The failure_message is different + # to reflect the aliased name. + # + # @api private + def failure_message + @description_block.call(super) + end + + # Provides the failure_message_when_negated of the aliased matcher. Aliased matchers + # are designed to behave identically to the original matcher except + # for the description and failure messages. The failure_message_when_negated is different + # to reflect the aliased name. + # + # @api private + def failure_message_when_negated + @description_block.call(super) + end + end + + # Decorator used for matchers that have special implementations of + # operators like `==` and `===`. + # @private + class AliasedMatcherWithOperatorSupport < AliasedMatcher + # We undef these so that they get delegated via `method_missing`. + undef == + undef === + end + + # @private + class AliasedNegatedMatcher < AliasedMatcher + def matches?(*args, &block) + if @base_matcher.respond_to?(:does_not_match?) + @base_matcher.does_not_match?(*args, &block) + else + !super + end + end + + def does_not_match?(*args, &block) + @base_matcher.matches?(*args, &block) + end + + def failure_message + optimal_failure_message(__method__, :failure_message_when_negated) + end + + def failure_message_when_negated + optimal_failure_message(__method__, :failure_message) + end + + private + + DefaultFailureMessages = BuiltIn::BaseMatcher::DefaultFailureMessages + + # For a matcher that uses the default failure messages, we prefer to + # use the override provided by the `description_block`, because it + # includes the phrasing that the user has expressed a preference for + # by going through the effort of defining a negated matcher. + # + # However, if the override didn't actually change anything, then we + # should return the opposite failure message instead -- the overridden + # message is going to be confusing if we return it as-is, as it represents + # the non-negated failure message for a negated match (or vice versa). + def optimal_failure_message(same, inverted) + if DefaultFailureMessages.has_default_failure_messages?(@base_matcher) + base_message = @base_matcher.__send__(same) + overridden = @description_block.call(base_message) + return overridden if overridden != base_message + end + + @base_matcher.__send__(inverted) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb new file mode 100644 index 0000000..e6237ff --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb @@ -0,0 +1,53 @@ +RSpec::Support.require_rspec_matchers "built_in/base_matcher" + +module RSpec + module Matchers + # Container module for all built-in matchers. The matcher classes are here + # (rather than directly under `RSpec::Matchers`) in order to prevent name + # collisions, since `RSpec::Matchers` gets included into the user's namespace. + # + # Autoloading is used to delay when the matcher classes get loaded, allowing + # rspec-matchers to boot faster, and avoiding loading matchers the user is + # not using. + module BuiltIn + autoload :BeAKindOf, 'rspec/matchers/built_in/be_kind_of' + autoload :BeAnInstanceOf, 'rspec/matchers/built_in/be_instance_of' + autoload :BeBetween, 'rspec/matchers/built_in/be_between' + autoload :Be, 'rspec/matchers/built_in/be' + autoload :BeComparedTo, 'rspec/matchers/built_in/be' + autoload :BeFalsey, 'rspec/matchers/built_in/be' + autoload :BeHelpers, 'rspec/matchers/built_in/be' + autoload :BeNil, 'rspec/matchers/built_in/be' + autoload :BePredicate, 'rspec/matchers/built_in/has' + autoload :BeTruthy, 'rspec/matchers/built_in/be' + autoload :BeWithin, 'rspec/matchers/built_in/be_within' + autoload :Change, 'rspec/matchers/built_in/change' + autoload :Compound, 'rspec/matchers/built_in/compound' + autoload :ContainExactly, 'rspec/matchers/built_in/contain_exactly' + autoload :Cover, 'rspec/matchers/built_in/cover' + autoload :EndWith, 'rspec/matchers/built_in/start_or_end_with' + autoload :Eq, 'rspec/matchers/built_in/eq' + autoload :Eql, 'rspec/matchers/built_in/eql' + autoload :Equal, 'rspec/matchers/built_in/equal' + autoload :Exist, 'rspec/matchers/built_in/exist' + autoload :Has, 'rspec/matchers/built_in/has' + autoload :HaveAttributes, 'rspec/matchers/built_in/have_attributes' + autoload :Include, 'rspec/matchers/built_in/include' + autoload :All, 'rspec/matchers/built_in/all' + autoload :Match, 'rspec/matchers/built_in/match' + autoload :NegativeOperatorMatcher, 'rspec/matchers/built_in/operators' + autoload :OperatorMatcher, 'rspec/matchers/built_in/operators' + autoload :Output, 'rspec/matchers/built_in/output' + autoload :PositiveOperatorMatcher, 'rspec/matchers/built_in/operators' + autoload :RaiseError, 'rspec/matchers/built_in/raise_error' + autoload :RespondTo, 'rspec/matchers/built_in/respond_to' + autoload :Satisfy, 'rspec/matchers/built_in/satisfy' + autoload :StartWith, 'rspec/matchers/built_in/start_or_end_with' + autoload :ThrowSymbol, 'rspec/matchers/built_in/throw_symbol' + autoload :YieldControl, 'rspec/matchers/built_in/yield' + autoload :YieldSuccessiveArgs, 'rspec/matchers/built_in/yield' + autoload :YieldWithArgs, 'rspec/matchers/built_in/yield' + autoload :YieldWithNoArgs, 'rspec/matchers/built_in/yield' + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb new file mode 100644 index 0000000..27cce20 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb @@ -0,0 +1,86 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `all`. + # Not intended to be instantiated directly. + class All < BaseMatcher + # @private + attr_reader :matcher, :failed_objects + + def initialize(matcher) + @matcher = matcher + @failed_objects = {} + end + + # @private + def does_not_match?(_actual) + raise NotImplementedError, '`expect().not_to all( matcher )` is not supported.' + end + + # @api private + # @return [String] + def failure_message + unless iterable? + return "#{improve_hash_formatting(super)}, but was not iterable" + end + + all_messages = [improve_hash_formatting(super)] + failed_objects.each do |index, matcher_failure_message| + all_messages << failure_message_for_item(index, matcher_failure_message) + end + all_messages.join("\n\n") + end + + # @api private + # @return [String] + def description + improve_hash_formatting "all #{description_of matcher}" + end + + private + + def match(_expected, _actual) + return false unless iterable? + + index_failed_objects + failed_objects.empty? + end + + def index_failed_objects + actual.each_with_index do |actual_item, index| + cloned_matcher = matcher.clone + matches = cloned_matcher.matches?(actual_item) + failed_objects[index] = cloned_matcher.failure_message unless matches + end + end + + def failure_message_for_item(index, failure_message) + failure_message = indent_multiline_message(add_new_line_if_needed(failure_message)) + indent_multiline_message("object at index #{index} failed to match:#{failure_message}") + end + + def add_new_line_if_needed(message) + message.start_with?("\n") ? message : "\n#{message}" + end + + def indent_multiline_message(message) + message = message.sub(/\n+\z/, '') + message.lines.map do |line| + line =~ /\S/ ? ' ' + line : line + end.join + end + + def initialize_copy(other) + @matcher = @matcher.clone + @failed_objects = @failed_objects.clone + super + end + + def iterable? + @actual.respond_to?(:each_with_index) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb new file mode 100644 index 0000000..8dd5133 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb @@ -0,0 +1,225 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # + # Used _internally_ as a base class for matchers that ship with + # rspec-expectations and rspec-rails. + # + # ### Warning: + # + # This class is for internal use, and subject to change without notice. + # We strongly recommend that you do not base your custom matchers on this + # class. If/when this changes, we will announce it and remove this warning. + class BaseMatcher + include RSpec::Matchers::Composable + + # @api private + # Used to detect when no arg is passed to `initialize`. + # `nil` cannot be used because it's a valid value to pass. + UNDEFINED = Object.new.freeze + + # @private + attr_reader :actual, :expected, :rescued_exception + + # @private + attr_writer :matcher_name + + def initialize(expected=UNDEFINED) + @expected = expected unless UNDEFINED.equal?(expected) + end + + # @api private + # Indicates if the match is successful. Delegates to `match`, which + # should be defined on a subclass. Takes care of consistently + # initializing the `actual` attribute. + def matches?(actual) + @actual = actual + match(expected, actual) + end + + # @api private + # Used to wrap a block of code that will indicate failure by + # raising one of the named exceptions. + # + # This is used by rspec-rails for some of its matchers that + # wrap rails' assertions. + def match_unless_raises(*exceptions) + exceptions.unshift Exception if exceptions.empty? + begin + yield + true + rescue *exceptions => @rescued_exception + false + end + end + + # @api private + # Generates a description using {EnglishPhrasing}. + # @return [String] + def description + desc = EnglishPhrasing.split_words(self.class.matcher_name) + desc << EnglishPhrasing.list(@expected) if defined?(@expected) + desc + end + + # @api private + # Matchers are not diffable by default. Override this to make your + # subclass diffable. + def diffable? + false + end + + # @api private + # Most matchers are value matchers (i.e. meant to work with `expect(value)`) + # rather than block matchers (i.e. meant to work with `expect { }`), so + # this defaults to false. Block matchers must override this to return true. + def supports_block_expectations? + false + end + + # @private + def supports_value_expectations? + true + end + + # @api private + def expects_call_stack_jump? + false + end + + # @private + def expected_formatted + RSpec::Support::ObjectFormatter.format(@expected) + end + + # @private + def actual_formatted + RSpec::Support::ObjectFormatter.format(@actual) + end + + # @private + def self.matcher_name + @matcher_name ||= underscore(name.split('::').last) + end + + # @private + def matcher_name + if defined?(@matcher_name) + @matcher_name + else + self.class.matcher_name + end + end + + # @private + # Borrowed from ActiveSupport. + def self.underscore(camel_cased_word) + word = camel_cased_word.to_s.dup + word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2') + word.gsub!(/([a-z\d])([A-Z])/, '\1_\2') + word.tr!('-', '_') + word.downcase! + word + end + private_class_method :underscore + + # @private + module HashFormatting + # `{ :a => 5, :b => 2 }.inspect` produces: + # + # {:a=>5, :b=>2} + # + # ...but it looks much better as: + # + # {:a => 5, :b => 2} + # + # This is idempotent and safe to run on a string multiple times. + def improve_hash_formatting(inspect_string) + inspect_string.gsub(/(\S)=>(\S)/, '\1 => \2') + end + module_function :improve_hash_formatting + end + + include HashFormatting + + # @private + module StringEncodingFormatting + # @api private + # @return [Boolean] True if the actual and expected string encoding are different. + # i.e. the failure may be related to encoding differences and the encoding + # should be shown to the user. false otherwise. + if String.method_defined?(:encoding) + def string_encoding_differs? + actual.is_a?(String) && expected.is_a?(String) && actual.encoding != expected.encoding + end + else + # @api private + # @return [Boolean] False always as the curent Ruby version does not support String encoding + # :nocov: + def string_encoding_differs? + false + end + # :nocov: + end + module_function :string_encoding_differs? + + if String.method_defined?(:encoding) + # @api private + # Formats a String's encoding as a human readable string + # @param value [String] + # @return [String] + def format_encoding(value) + "#" + end + else + # @api private + # Formats a String's encoding as a human readable string + # @param _value [String] + # @return [nil] nil as the curent Ruby version does not support String encoding + # :nocov: + def format_encoding(_value) + nil + end + # :nocov: + end + module_function :format_encoding + end + + include StringEncodingFormatting + + # @api private + # Provides default implementations of failure messages, based on the `description`. + module DefaultFailureMessages + # @api private + # Provides a good generic failure message. Based on `description`. + # When subclassing, if you are not satisfied with this failure message + # you often only need to override `description`. + # @return [String] + def failure_message + "expected #{description_of @actual} to #{description}".dup + end + + # @api private + # Provides a good generic negative failure message. Based on `description`. + # When subclassing, if you are not satisfied with this failure message + # you often only need to override `description`. + # @return [String] + def failure_message_when_negated + "expected #{description_of @actual} not to #{description}".dup + end + + # @private + def self.has_default_failure_messages?(matcher) + matcher.method(:failure_message).owner == self && + matcher.method(:failure_message_when_negated).owner == self + rescue NameError + false + end + end + + include DefaultFailureMessages + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb new file mode 100644 index 0000000..40d4017 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb @@ -0,0 +1,191 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_truthy`. + # Not intended to be instantiated directly. + class BeTruthy < BaseMatcher + # @api private + # @return [String] + def failure_message + "expected: truthy value\n got: #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected: falsey value\n got: #{actual_formatted}" + end + + private + + def match(_, actual) + !!actual + end + end + + # @api private + # Provides the implementation for `be_falsey`. + # Not intended to be instantiated directly. + class BeFalsey < BaseMatcher + # @api private + # @return [String] + def failure_message + "expected: falsey value\n got: #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected: truthy value\n got: #{actual_formatted}" + end + + private + + def match(_, actual) + !actual + end + end + + # @api private + # Provides the implementation for `be_nil`. + # Not intended to be instantiated directly. + class BeNil < BaseMatcher + # @api private + # @return [String] + def failure_message + "expected: nil\n got: #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected: not nil\n got: nil" + end + + private + + def match(_, actual) + actual.nil? + end + end + + # @private + module BeHelpers + private + + def args_to_s + @args.empty? ? "" : parenthesize(inspected_args.join(', ')) + end + + def parenthesize(string) + "(#{string})" + end + + def inspected_args + @args.map { |a| RSpec::Support::ObjectFormatter.format(a) } + end + + def expected_to_sentence + EnglishPhrasing.split_words(@expected) + end + + def args_to_sentence + EnglishPhrasing.list(@args) + end + end + + # @api private + # Provides the implementation for `be`. + # Not intended to be instantiated directly. + class Be < BaseMatcher + include BeHelpers + + def initialize(*args) + @args = args + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to evaluate to true" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} to evaluate to false" + end + + [:==, :<, :<=, :>=, :>, :===, :=~].each do |operator| + define_method operator do |operand| + BeComparedTo.new(operand, operator) + end + end + + private + + def match(_, actual) + !!actual + end + end + + # @api private + # Provides the implementation of `be value`. + # Not intended to be instantiated directly. + class BeComparedTo < BaseMatcher + include BeHelpers + + def initialize(operand, operator) + @expected = operand + @operator = operator + @args = [] + end + + def matches?(actual) + perform_match(actual) + rescue ArgumentError, NoMethodError + false + end + + def does_not_match?(actual) + !perform_match(actual) + rescue ArgumentError, NoMethodError + false + end + + # @api private + # @return [String] + def failure_message + "expected: #{@operator} #{expected_formatted}\n" \ + " got: #{@operator.to_s.gsub(/./, ' ')} #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + message = "`expect(#{actual_formatted}).not_to " \ + "be #{@operator} #{expected_formatted}`" + if [:<, :>, :<=, :>=].include?(@operator) + message + " not only FAILED, it is a bit confusing." + else + message + end + end + + # @api private + # @return [String] + def description + "be #{@operator} #{expected_to_sentence}#{args_to_sentence}" + end + + private + + def perform_match(actual) + @actual = actual + @actual.__send__ @operator, @expected + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb new file mode 100644 index 0000000..55f084e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb @@ -0,0 +1,77 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_between`. + # Not intended to be instantiated directly. + class BeBetween < BaseMatcher + def initialize(min, max) + @min, @max = min, max + inclusive + end + + # @api public + # Makes the between comparison inclusive. + # + # @example + # expect(3).to be_between(2, 3).inclusive + # + # @note The matcher is inclusive by default; this simply provides + # a way to be more explicit about it. + def inclusive + @less_than_operator = :<= + @greater_than_operator = :>= + @mode = :inclusive + self + end + + # @api public + # Makes the between comparison exclusive. + # + # @example + # expect(3).to be_between(2, 4).exclusive + def exclusive + @less_than_operator = :< + @greater_than_operator = :> + @mode = :exclusive + self + end + + # @api private + # @return [Boolean] + def matches?(actual) + @actual = actual + comparable? && compare + rescue ArgumentError + false + end + + # @api private + # @return [String] + def failure_message + "#{super}#{not_comparable_clause}" + end + + # @api private + # @return [String] + def description + "be between #{description_of @min} and #{description_of @max} (#{@mode})" + end + + private + + def comparable? + @actual.respond_to?(@less_than_operator) && @actual.respond_to?(@greater_than_operator) + end + + def not_comparable_clause + ", but it does not respond to `#{@less_than_operator}` and `#{@greater_than_operator}`" unless comparable? + end + + def compare + @actual.__send__(@greater_than_operator, @min) && @actual.__send__(@less_than_operator, @max) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb new file mode 100644 index 0000000..e71d380 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb @@ -0,0 +1,26 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_an_instance_of`. + # Not intended to be instantiated directly. + class BeAnInstanceOf < BaseMatcher + # @api private + # @return [String] + def description + "be an instance of #{expected}" + end + + private + + def match(expected, actual) + actual.instance_of?(expected) + rescue NoMethodError + raise ::ArgumentError, "The #{matcher_name} matcher requires that " \ + "the actual object responds to #instance_of? method " \ + "but a `NoMethodError` was encountered instead." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb new file mode 100644 index 0000000..4fe23bd --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb @@ -0,0 +1,20 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_a_kind_of`. + # Not intended to be instantiated directly. + class BeAKindOf < BaseMatcher + private + + def match(expected, actual) + actual.kind_of?(expected) + rescue NoMethodError + raise ::ArgumentError, "The #{matcher_name} matcher requires that " \ + "the actual object responds to #kind_of? method " \ + "but a `NoMethodError` was encountered instead." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb new file mode 100644 index 0000000..7a2b5b5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb @@ -0,0 +1,72 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_within`. + # Not intended to be instantiated directly. + class BeWithin < BaseMatcher + def initialize(delta) + @delta = delta + end + + # @api public + # Sets the expected value. + def of(expected) + @expected = expected + @tolerance = @delta + @unit = '' + self + end + + # @api public + # Sets the expected value, and makes the matcher do + # a percent comparison. + def percent_of(expected) + @expected = expected + @tolerance = @expected.abs * @delta / 100.0 + @unit = '%' + self + end + + # @private + def matches?(actual) + @actual = actual + raise needs_expected unless defined? @expected + numeric? && (@actual - @expected).abs <= @tolerance + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to #{description}#{not_numeric_clause}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} not to #{description}" + end + + # @api private + # @return [String] + def description + "be within #{@delta}#{@unit} of #{expected_formatted}" + end + + private + + def numeric? + @actual.respond_to?(:-) + end + + def needs_expected + ArgumentError.new "You must set an expected value using #of: be_within(#{@delta}).of(expected_value)" + end + + def not_numeric_clause + ", but it could not be treated as a numeric value" unless numeric? + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb new file mode 100644 index 0000000..00e65dc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb @@ -0,0 +1,452 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `change`. + # Not intended to be instantiated directly. + class Change < BaseMatcher + # @api public + # Specifies the delta of the expected change. + def by(expected_delta) + ChangeRelatively.new(change_details, expected_delta, :by) do |actual_delta| + values_match?(expected_delta, actual_delta) + end + end + + # @api public + # Specifies a minimum delta of the expected change. + def by_at_least(minimum) + ChangeRelatively.new(change_details, minimum, :by_at_least) do |actual_delta| + actual_delta >= minimum + end + end + + # @api public + # Specifies a maximum delta of the expected change. + def by_at_most(maximum) + ChangeRelatively.new(change_details, maximum, :by_at_most) do |actual_delta| + actual_delta <= maximum + end + end + + # @api public + # Specifies the new value you expect. + def to(value) + ChangeToValue.new(change_details, value) + end + + # @api public + # Specifies the original value. + def from(value) + ChangeFromValue.new(change_details, value) + end + + # @private + def matches?(event_proc) + raise_block_syntax_error if block_given? + perform_change(event_proc) && change_details.changed? + end + + def does_not_match?(event_proc) + raise_block_syntax_error if block_given? + perform_change(event_proc) && !change_details.changed? + end + + # @api private + # @return [String] + def failure_message + "expected #{change_details.value_representation} to have changed, " \ + "but #{positive_failure_reason}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{change_details.value_representation} not to have changed, " \ + "but #{negative_failure_reason}" + end + + # @api private + # @return [String] + def description + "change #{change_details.value_representation}" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def initialize(receiver=nil, message=nil, &block) + @receiver = receiver + @message = message + @block = block + end + + def change_details + @change_details ||= ChangeDetails.new(matcher_name, @receiver, @message, &@block) + end + + def perform_change(event_proc) + @event_proc = event_proc + change_details.perform_change(event_proc) do |actual_before| + # pre-compute values derived from the `before` value before the + # mutation is applied, in case the specified mutation is mutation + # of a single object (rather than a changing what object a method + # returns). We need to cache these values before the `before` value + # they are based on potentially gets mutated. + @actual_before_description = description_of(actual_before) + end + end + + def raise_block_syntax_error + raise SyntaxError, "Block not received by the `change` matcher. " \ + "Perhaps you want to use `{ ... }` instead of do/end?" + end + + def positive_failure_reason + return "was not given a block" unless Proc === @event_proc + "is still #{@actual_before_description}" + end + + def negative_failure_reason + return "was not given a block" unless Proc === @event_proc + "did change from #{@actual_before_description} " \ + "to #{description_of change_details.actual_after}" + end + end + + # Used to specify a relative change. + # @api private + class ChangeRelatively < BaseMatcher + def initialize(change_details, expected_delta, relativity, &comparer) + @change_details = change_details + @expected_delta = expected_delta + @relativity = relativity + @comparer = comparer + end + + # @private + def failure_message + "expected #{@change_details.value_representation} to have changed " \ + "#{@relativity.to_s.tr('_', ' ')} " \ + "#{description_of @expected_delta}, but #{failure_reason}" + end + + # @private + def matches?(event_proc) + @event_proc = event_proc + @change_details.perform_change(event_proc) && @comparer.call(@change_details.actual_delta) + end + + # @private + def does_not_match?(_event_proc) + raise NotImplementedError, "`expect { }.not_to change " \ + "{ }.#{@relativity}()` is not supported" + end + + # @private + def description + "change #{@change_details.value_representation} " \ + "#{@relativity.to_s.tr('_', ' ')} #{description_of @expected_delta}" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def failure_reason + return "was not given a block" unless Proc === @event_proc + "was changed by #{description_of @change_details.actual_delta}" + end + end + + # @api private + # Base class for specifying a change from and/or to specific values. + class SpecificValuesChange < BaseMatcher + # @private + MATCH_ANYTHING = ::Object.ancestors.last + + def initialize(change_details, from, to) + @change_details = change_details + @expected_before = from + @expected_after = to + end + + # @private + def matches?(event_proc) + perform_change(event_proc) && @change_details.changed? && @matches_before && matches_after? + end + + # @private + def description + "change #{@change_details.value_representation} #{change_description}" + end + + # @private + def failure_message + return not_given_a_block_failure unless Proc === @event_proc + return before_value_failure unless @matches_before + return did_not_change_failure unless @change_details.changed? + after_value_failure + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def perform_change(event_proc) + @event_proc = event_proc + @change_details.perform_change(event_proc) do |actual_before| + # pre-compute values derived from the `before` value before the + # mutation is applied, in case the specified mutation is mutation + # of a single object (rather than a changing what object a method + # returns). We need to cache these values before the `before` value + # they are based on potentially gets mutated. + @matches_before = values_match?(@expected_before, actual_before) + @actual_before_description = description_of(actual_before) + end + end + + def matches_after? + values_match?(@expected_after, @change_details.actual_after) + end + + def before_value_failure + "expected #{@change_details.value_representation} " \ + "to have initially been #{description_of @expected_before}, " \ + "but was #{@actual_before_description}" + end + + def after_value_failure + "expected #{@change_details.value_representation} " \ + "to have changed to #{description_of @expected_after}, " \ + "but is now #{description_of @change_details.actual_after}" + end + + def did_not_change_failure + "expected #{@change_details.value_representation} " \ + "to have changed #{change_description}, but did not change" + end + + def did_change_failure + "expected #{@change_details.value_representation} not to have changed, but " \ + "did change from #{@actual_before_description} " \ + "to #{description_of @change_details.actual_after}" + end + + def not_given_a_block_failure + "expected #{@change_details.value_representation} to have changed " \ + "#{change_description}, but was not given a block" + end + end + + # @api private + # Used to specify a change from a specific value + # (and, optionally, to a specific value). + class ChangeFromValue < SpecificValuesChange + def initialize(change_details, expected_before) + @description_suffix = nil + super(change_details, expected_before, MATCH_ANYTHING) + end + + # @api public + # Specifies the new value you expect. + def to(value) + @expected_after = value + @description_suffix = " to #{description_of value}" + self + end + + # @private + def does_not_match?(event_proc) + if @description_suffix + raise NotImplementedError, "`expect { }.not_to change { }.to()` " \ + "is not supported" + end + + perform_change(event_proc) && !@change_details.changed? && @matches_before + end + + # @private + def failure_message_when_negated + return not_given_a_block_failure unless Proc === @event_proc + return before_value_failure unless @matches_before + did_change_failure + end + + private + + def change_description + "from #{description_of @expected_before}#{@description_suffix}" + end + end + + # @api private + # Used to specify a change to a specific value + # (and, optionally, from a specific value). + class ChangeToValue < SpecificValuesChange + def initialize(change_details, expected_after) + @description_suffix = nil + super(change_details, MATCH_ANYTHING, expected_after) + end + + # @api public + # Specifies the original value. + def from(value) + @expected_before = value + @description_suffix = " from #{description_of value}" + self + end + + # @private + def does_not_match?(_event_proc) + raise NotImplementedError, "`expect { }.not_to change { }.to()` " \ + "is not supported" + end + + private + + def change_description + "to #{description_of @expected_after}#{@description_suffix}" + end + end + + # @private + # Encapsulates the details of the before/after values. + # + # Note that this class exposes the `actual_after` value, to allow the + # matchers above to derive failure messages, etc from the value on demand + # as needed, but it intentionally does _not_ expose the `actual_before` + # value. Some usages of the `change` matcher mutate a specific object + # returned by the value proc, which means that failure message snippets, + # etc, which are derived from the `before` value may not be accurate if + # they are lazily computed as needed. We must pre-compute them before + # applying the change in the `expect` block. To ensure that all `change` + # matchers do that properly, we do not expose the `actual_before` value. + # Instead, matchers must pass a block to `perform_change`, which yields + # the `actual_before` value before applying the change. + class ChangeDetails + attr_reader :actual_after + + UNDEFINED = Module.new.freeze + + def initialize(matcher_name, receiver=nil, message=nil, &block) + if receiver && !message + raise( + ArgumentError, + "`change` requires either an object and message " \ + "(`change(obj, :msg)`) or a block (`change { }`). " \ + "You passed an object but no message." + ) + end + + @matcher_name = matcher_name + @receiver = receiver + @message = message + @value_proc = block + # TODO: temporary measure to mute warning of access to an initialized + # instance variable when a deprecated implicit block expectation + # syntax is used. This may be removed once `fail` is used, and the + # matcher never issues this warning. + @actual_after = UNDEFINED + end + + def value_representation + @value_representation ||= + if @message + "`#{message_notation(@receiver, @message)}`" + elsif (value_block_snippet = extract_value_block_snippet) + "`#{value_block_snippet}`" + else + 'result' + end + end + + def perform_change(event_proc) + @actual_before = evaluate_value_proc + @before_hash = @actual_before.hash + yield @actual_before if block_given? + + return false unless Proc === event_proc + event_proc.call + + @actual_after = evaluate_value_proc + @actual_hash = @actual_after.hash + true + end + + def changed? + # Consider it changed if either: + # + # - The before/after values are unequal + # - The before/after values have different hash values + # + # The latter case specifically handles the case when the value proc + # returns the exact same object, but it has been mutated. + # + # Note that it is not sufficient to only check the hashes; it is + # possible for two values to be unequal (and of different classes) + # but to return the same hash value. Also, some objects may change + # their hash after being compared with `==`/`!=`. + @actual_before != @actual_after || @before_hash != @actual_hash + end + + def actual_delta + @actual_after - @actual_before + end + + private + + def evaluate_value_proc + @value_proc ? @value_proc.call : @receiver.__send__(@message) + end + + def message_notation(receiver, message) + case receiver + when Module + "#{receiver}.#{message}" + else + "#{Support.class_of(receiver)}##{message}" + end + end + + if RSpec::Support::RubyFeatures.ripper_supported? + def extract_value_block_snippet + return nil unless @value_proc + Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@value_proc, @matcher_name) + end + else + # :nocov: + def extract_value_block_snippet + nil + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb new file mode 100644 index 0000000..3a7fb1e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb @@ -0,0 +1,293 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Base class for `and` and `or` compound matchers. + class Compound < BaseMatcher + # @private + attr_reader :matcher_1, :matcher_2, :evaluator + + def initialize(matcher_1, matcher_2) + @matcher_1 = matcher_1 + @matcher_2 = matcher_2 + end + + # @private + def does_not_match?(_actual) + raise NotImplementedError, "`expect(...).not_to matcher.#{conjunction} matcher` " \ + "is not supported, since it creates a bit of an ambiguity. Instead, define negated versions " \ + "of whatever matchers you wish to negate with `RSpec::Matchers.define_negated_matcher` and " \ + "use `expect(...).to matcher.#{conjunction} matcher`." + end + + # @api private + # @return [String] + def description + "#{matcher_1.description} #{conjunction} #{matcher_2.description}" + end + + # @api private + def supports_block_expectations? + matcher_supports_block_expectations?(matcher_1) && + matcher_supports_block_expectations?(matcher_2) + end + + # @api private + def supports_value_expectations? + matcher_supports_value_expectations?(matcher_1) && + matcher_supports_value_expectations?(matcher_2) + end + + # @api private + def expects_call_stack_jump? + NestedEvaluator.matcher_expects_call_stack_jump?(matcher_1) || + NestedEvaluator.matcher_expects_call_stack_jump?(matcher_2) + end + + # @api private + # @return [Boolean] + def diffable? + matcher_is_diffable?(matcher_1) || matcher_is_diffable?(matcher_2) + end + + # @api private + # @return [RSpec::Matchers::MultiMatcherDiff] + def expected + return nil unless evaluator + ::RSpec::Matchers::MultiMatcherDiff.for_many_matchers(diffable_matcher_list) + end + + protected + + def diffable_matcher_list + list = [] + list.concat(diffable_matcher_list_for(matcher_1)) unless matcher_1_matches? + list.concat(diffable_matcher_list_for(matcher_2)) unless matcher_2_matches? + list + end + + private + + def initialize_copy(other) + @matcher_1 = @matcher_1.clone + @matcher_2 = @matcher_2.clone + super + end + + def match(_expected, actual) + evaluator_klass = if supports_block_expectations? && Proc === actual + NestedEvaluator + elsif supports_value_expectations? + SequentialEvaluator + else + # Can't raise an ArgumentError in this context, as it's rescued + raise "Block and value matchers can't be combined in a compound expectation (#{matcher_1.description}, #{matcher_2.description})" + end + + @evaluator = evaluator_klass.new(actual, matcher_1, matcher_2) + end + + def indent_multiline_message(message) + message.lines.map do |line| + line =~ /\S/ ? ' ' + line : line + end.join + end + + def compound_failure_message + "#{indent_multiline_message(matcher_1.failure_message.sub(/\n+\z/, ''))}" \ + "\n\n...#{conjunction}:" \ + "\n\n#{indent_multiline_message(matcher_2.failure_message.sub(/\A\n+/, ''))}" + end + + def matcher_1_matches? + evaluator.matcher_matches?(matcher_1) + end + + def matcher_2_matches? + evaluator.matcher_matches?(matcher_2) + end + + def matcher_supports_block_expectations?(matcher) + matcher.supports_block_expectations? + rescue NoMethodError + false + end + + def matcher_supports_value_expectations?(matcher) + matcher.supports_value_expectations? + rescue NoMethodError + true + end + + def matcher_is_diffable?(matcher) + matcher.diffable? + rescue NoMethodError + false + end + + def diffable_matcher_list_for(matcher) + return [] unless matcher_is_diffable?(matcher) + return matcher.diffable_matcher_list if Compound === matcher + [matcher] + end + + # For value expectations, we can evaluate the matchers sequentially. + class SequentialEvaluator + def initialize(actual, *) + @actual = actual + end + + def matcher_matches?(matcher) + matcher.matches?(@actual) + end + end + + # Normally, we evaluate the matching sequentially. For an expression like + # `expect(x).to foo.and bar`, this becomes: + # + # expect(x).to foo + # expect(x).to bar + # + # For block expectations, we need to nest them instead, so that + # `expect { x }.to foo.and bar` becomes: + # + # expect { + # expect { x }.to foo + # }.to bar + # + # This is necessary so that the `expect` block is only executed once. + class NestedEvaluator + def initialize(actual, matcher_1, matcher_2) + @actual = actual + @matcher_1 = matcher_1 + @matcher_2 = matcher_2 + @match_results = {} + + inner, outer = order_block_matchers + + @match_results[outer] = outer.matches?(Proc.new do |*args| + @match_results[inner] = inner.matches?(inner_matcher_block(args)) + end) + end + + def matcher_matches?(matcher) + @match_results.fetch(matcher) do + raise ArgumentError, "Your #{matcher.description} has no match " \ + "results, this can occur when an unexpected call stack or " \ + "local jump occurs. Perhaps one of your matchers needs to " \ + "declare `expects_call_stack_jump?` as `true`?" + end + end + + private + + # Some block matchers (such as `yield_xyz`) pass args to the `expect` block. + # When such a matcher is used as the outer matcher, we need to forward the + # the args on to the `expect` block. + def inner_matcher_block(outer_args) + return @actual if outer_args.empty? + + Proc.new do |*inner_args| + unless inner_args.empty? + raise ArgumentError, "(#{@matcher_1.description}) and " \ + "(#{@matcher_2.description}) cannot be combined in a compound expectation " \ + "since both matchers pass arguments to the block." + end + + @actual.call(*outer_args) + end + end + + # For a matcher like `raise_error` or `throw_symbol`, where the block will jump + # up the call stack, we need to order things so that it is the inner matcher. + # For example, we need it to be this: + # + # expect { + # expect { + # x += 1 + # raise "boom" + # }.to raise_error("boom") + # }.to change { x }.by(1) + # + # ...rather than: + # + # expect { + # expect { + # x += 1 + # raise "boom" + # }.to change { x }.by(1) + # }.to raise_error("boom") + # + # In the latter case, the after-block logic in the `change` matcher would never + # get executed because the `raise "boom"` line would jump to the `rescue` in the + # `raise_error` logic, so only the former case will work properly. + # + # This method figures out which matcher should be the inner matcher and which + # should be the outer matcher. + def order_block_matchers + return @matcher_1, @matcher_2 unless self.class.matcher_expects_call_stack_jump?(@matcher_2) + return @matcher_2, @matcher_1 unless self.class.matcher_expects_call_stack_jump?(@matcher_1) + + raise ArgumentError, "(#{@matcher_1.description}) and " \ + "(#{@matcher_2.description}) cannot be combined in a compound expectation " \ + "because they both expect a call stack jump." + end + + def self.matcher_expects_call_stack_jump?(matcher) + matcher.expects_call_stack_jump? + rescue NoMethodError + false + end + end + + # @api public + # Matcher used to represent a compound `and` expectation. + class And < self + # @api private + # @return [String] + def failure_message + if matcher_1_matches? + matcher_2.failure_message + elsif matcher_2_matches? + matcher_1.failure_message + else + compound_failure_message + end + end + + private + + def match(*) + super + matcher_1_matches? && matcher_2_matches? + end + + def conjunction + "and" + end + end + + # @api public + # Matcher used to represent a compound `or` expectation. + class Or < self + # @api private + # @return [String] + def failure_message + compound_failure_message + end + + private + + def match(*) + super + matcher_1_matches? || matcher_2_matches? + end + + def conjunction + "or" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb new file mode 100644 index 0000000..f80572c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb @@ -0,0 +1,312 @@ +module RSpec + module Matchers + module BuiltIn + # rubocop:disable Metrics/ClassLength + # @api private + # Provides the implementation for `contain_exactly` and `match_array`. + # Not intended to be instantiated directly. + class ContainExactly < BaseMatcher + # @api private + # @return [String] + def failure_message + if Array === actual + generate_failure_message + else + "expected a collection that can be converted to an array with " \ + "`#to_ary` or `#to_a`, but got #{actual_formatted}" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + list = EnglishPhrasing.list(surface_descriptions_in(expected)) + "expected #{actual_formatted} not to contain exactly#{list}" + end + + # @api private + # @return [String] + def description + list = EnglishPhrasing.list(surface_descriptions_in(expected)) + "contain exactly#{list}" + end + + def matches?(actual) + @pairings_maximizer = nil + @best_solution = nil + @extra_items = nil + @missing_items = nil + super(actual) + end + + private + + def generate_failure_message + message = expected_collection_line + message += actual_collection_line + message += missing_elements_line unless missing_items.empty? + message += extra_elements_line unless extra_items.empty? + message + end + + def expected_collection_line + message_line('expected collection contained', expected, true) + end + + def actual_collection_line + message_line('actual collection contained', actual) + end + + def missing_elements_line + message_line('the missing elements were', missing_items, true) + end + + def extra_elements_line + message_line('the extra elements were', extra_items) + end + + def describe_collection(collection, surface_descriptions=false) + if surface_descriptions + "#{description_of(safe_sort(surface_descriptions_in collection))}\n" + else + "#{description_of(safe_sort(collection))}\n" + end + end + + def message_line(prefix, collection, surface_descriptions=false) + "%-32s%s" % [prefix + ':', + describe_collection(collection, surface_descriptions)] + end + + def match(_expected, _actual) + return false unless convert_actual_to_an_array + match_when_sorted? || (extra_items.empty? && missing_items.empty?) + end + + # This cannot always work (e.g. when dealing with unsortable items, + # or matchers as expected items), but it's practically free compared to + # the slowness of the full matching algorithm, and in common cases this + # works, so it's worth a try. + def match_when_sorted? + values_match?(safe_sort(expected), safe_sort(actual)) + end + + def convert_actual_to_an_array + if actual.respond_to?(:to_ary) + @actual = actual.to_ary + elsif actual.respond_to?(:to_a) && !to_a_disallowed?(actual) + @actual = actual.to_a + else + false + end + end + + def safe_sort(array) + array.sort + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + array + end + + if RUBY_VERSION == "1.8.7" + # :nocov: + def to_a_disallowed?(object) + case object + when NilClass, String then true + else Kernel == RSpec::Support.method_handle_for(object, :to_a).owner + end + end + # :nocov: + else + def to_a_disallowed?(object) + NilClass === object + end + end + + def missing_items + @missing_items ||= best_solution.unmatched_expected_indexes.map do |index| + expected[index] + end + end + + def extra_items + @extra_items ||= best_solution.unmatched_actual_indexes.map do |index| + actual[index] + end + end + + def best_solution + @best_solution ||= pairings_maximizer.find_best_solution + end + + def pairings_maximizer + @pairings_maximizer ||= begin + expected_matches = Hash[Array.new(expected.size) { |i| [i, []] }] + actual_matches = Hash[Array.new(actual.size) { |i| [i, []] }] + + expected.each_with_index do |e, ei| + actual.each_with_index do |a, ai| + next unless values_match?(e, a) + + expected_matches[ei] << ai + actual_matches[ai] << ei + end + end + + PairingsMaximizer.new(expected_matches, actual_matches) + end + end + + # Once we started supporting composing matchers, the algorithm for this matcher got + # much more complicated. Consider this expression: + # + # expect(["fool", "food"]).to contain_exactly(/foo/, /fool/) + # + # This should pass (because we can pair /fool/ with "fool" and /foo/ with "food"), but + # the original algorithm used by this matcher would pair the first elements it could + # (/foo/ with "fool"), which would leave /fool/ and "food" unmatched. When we have + # an expected element which is a matcher that matches a superset of actual items + # compared to another expected element matcher, we need to consider every possible pairing. + # + # This class is designed to maximize the number of actual/expected pairings -- or, + # conversely, to minimize the number of unpaired items. It's essentially a brute + # force solution, but with a few heuristics applied to reduce the size of the + # problem space: + # + # * Any items which match none of the items in the other list are immediately + # placed into the `unmatched_expected_indexes` or `unmatched_actual_indexes` array. + # The extra items and missing items in the matcher failure message are derived + # from these arrays. + # * Any items which reciprocally match only each other are paired up and not + # considered further. + # + # What's left is only the items which match multiple items from the other list + # (or vice versa). From here, it performs a brute-force depth-first search, + # looking for a solution which pairs all elements in both lists, or, barring that, + # that produces the fewest unmatched items. + # + # @private + class PairingsMaximizer + # @private + Solution = Struct.new(:unmatched_expected_indexes, :unmatched_actual_indexes, + :indeterminate_expected_indexes, :indeterminate_actual_indexes) do + def worse_than?(other) + unmatched_item_count > other.unmatched_item_count + end + + def candidate? + indeterminate_expected_indexes.empty? && + indeterminate_actual_indexes.empty? + end + + def ideal? + candidate? && ( + unmatched_expected_indexes.empty? || + unmatched_actual_indexes.empty? + ) + end + + def unmatched_item_count + unmatched_expected_indexes.count + unmatched_actual_indexes.count + end + + def +(derived_candidate_solution) + self.class.new( + unmatched_expected_indexes + derived_candidate_solution.unmatched_expected_indexes, + unmatched_actual_indexes + derived_candidate_solution.unmatched_actual_indexes, + # Ignore the indeterminate indexes: by the time we get here, + # we've dealt with all indeterminates. + [], [] + ) + end + end + + attr_reader :expected_to_actual_matched_indexes, :actual_to_expected_matched_indexes, :solution + + def initialize(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes) + @expected_to_actual_matched_indexes = expected_to_actual_matched_indexes + @actual_to_expected_matched_indexes = actual_to_expected_matched_indexes + + unmatched_expected_indexes, indeterminate_expected_indexes = + categorize_indexes(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes) + + unmatched_actual_indexes, indeterminate_actual_indexes = + categorize_indexes(actual_to_expected_matched_indexes, expected_to_actual_matched_indexes) + + @solution = Solution.new(unmatched_expected_indexes, unmatched_actual_indexes, + indeterminate_expected_indexes, indeterminate_actual_indexes) + end + + def find_best_solution + return solution if solution.candidate? + best_solution_so_far = NullSolution + + expected_index = solution.indeterminate_expected_indexes.first + actuals = expected_to_actual_matched_indexes[expected_index] + + actuals.each do |actual_index| + solution = best_solution_for_pairing(expected_index, actual_index) + return solution if solution.ideal? + best_solution_so_far = solution if best_solution_so_far.worse_than?(solution) + end + + best_solution_so_far + end + + private + + # @private + # Starting solution that is worse than any other real solution. + NullSolution = Class.new do + def self.worse_than?(_other) + true + end + end + + def categorize_indexes(indexes_to_categorize, other_indexes) + unmatched = [] + indeterminate = [] + + indexes_to_categorize.each_pair do |index, matches| + if matches.empty? + unmatched << index + elsif !reciprocal_single_match?(matches, index, other_indexes) + indeterminate << index + end + end + + return unmatched, indeterminate + end + + def reciprocal_single_match?(matches, index, other_list) + return false unless matches.one? + other_list[matches.first] == [index] + end + + def best_solution_for_pairing(expected_index, actual_index) + modified_expecteds = apply_pairing_to( + solution.indeterminate_expected_indexes, + expected_to_actual_matched_indexes, actual_index) + + modified_expecteds.delete(expected_index) + + modified_actuals = apply_pairing_to( + solution.indeterminate_actual_indexes, + actual_to_expected_matched_indexes, expected_index) + + modified_actuals.delete(actual_index) + + solution + self.class.new(modified_expecteds, modified_actuals).find_best_solution + end + + def apply_pairing_to(indeterminates, original_matches, other_list_index) + indeterminates.inject({}) do |accum, index| + accum[index] = original_matches[index] - [other_list_index] + accum + end + end + end + end + # rubocop:enable Metrics/ClassLength + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb new file mode 100644 index 0000000..aa91310 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb @@ -0,0 +1,171 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Abstract class to implement `once`, `at_least` and other + # count constraints. + module CountExpectation + # @api public + # Specifies that the method is expected to match once. + def once + exactly(1) + end + + # @api public + # Specifies that the method is expected to match twice. + def twice + exactly(2) + end + + # @api public + # Specifies that the method is expected to match thrice. + def thrice + exactly(3) + end + + # @api public + # Specifies that the method is expected to match the given number of times. + def exactly(number) + set_expected_count(:==, number) + self + end + + # @api public + # Specifies the maximum number of times the method is expected to match + def at_most(number) + set_expected_count(:<=, number) + self + end + + # @api public + # Specifies the minimum number of times the method is expected to match + def at_least(number) + set_expected_count(:>=, number) + self + end + + # @api public + # No-op. Provides syntactic sugar. + def times + self + end + + protected + # @api private + attr_reader :count_expectation_type, :expected_count + + private + + if RUBY_VERSION.to_f > 1.8 + def cover?(count, number) + count.cover?(number) + end + else + # :nocov: + def cover?(count, number) + number >= count.first && number <= count.last + end + # :nocov: + end + + def expected_count_matches?(actual_count) + @actual_count = actual_count + return @actual_count > 0 unless count_expectation_type + return cover?(expected_count, actual_count) if count_expectation_type == :<=> + + @actual_count.__send__(count_expectation_type, expected_count) + end + + def has_expected_count? + !!count_expectation_type + end + + def set_expected_count(relativity, n) + raise_unsupported_count_expectation if unsupported_count_expectation?(relativity) + + count = count_constraint_to_number(n) + + if count_expectation_type == :<= && relativity == :>= + raise_impossible_count_expectation(count) if count > expected_count + @count_expectation_type = :<=> + @expected_count = count..expected_count + elsif count_expectation_type == :>= && relativity == :<= + raise_impossible_count_expectation(count) if count < expected_count + @count_expectation_type = :<=> + @expected_count = expected_count..count + else + @count_expectation_type = relativity + @expected_count = count + end + end + + def raise_impossible_count_expectation(count) + text = + case count_expectation_type + when :<= then "at_least(#{count}).at_most(#{expected_count})" + when :>= then "at_least(#{expected_count}).at_most(#{count})" + end + raise ArgumentError, "The constraint #{text} is not possible" + end + + def raise_unsupported_count_expectation + text = + case count_expectation_type + when :<= then "at_least" + when :>= then "at_most" + when :<=> then "at_least/at_most combination" + else "count" + end + raise ArgumentError, "Multiple #{text} constraints are not supported" + end + + def count_constraint_to_number(n) + case n + when Numeric then n + when :once then 1 + when :twice then 2 + when :thrice then 3 + else + raise ArgumentError, "Expected a number, :once, :twice or :thrice," \ + " but got #{n}" + end + end + + def unsupported_count_expectation?(relativity) + return true if count_expectation_type == :== + return true if count_expectation_type == :<=> + (count_expectation_type == :<= && relativity == :<=) || + (count_expectation_type == :>= && relativity == :>=) + end + + def count_expectation_description + "#{human_readable_expectation_type}#{human_readable_count(expected_count)}" + end + + def count_failure_reason(action) + "#{count_expectation_description}" \ + " but #{action}#{human_readable_count(@actual_count)}" + end + + def human_readable_expectation_type + case count_expectation_type + when :<= then ' at most' + when :>= then ' at least' + when :<=> then ' between' + else '' + end + end + + def human_readable_count(count) + case count + when Range then " #{count.first} and #{count.last} times" + when nil then '' + when 1 then ' once' + when 2 then ' twice' + else " #{count} times" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb new file mode 100644 index 0000000..47474a2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb @@ -0,0 +1,24 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `cover`. + # Not intended to be instantiated directly. + class Cover < BaseMatcher + def initialize(*expected) + @expected = expected + end + + def matches?(range) + @actual = range + @expected.all? { |e| range.cover?(e) } + end + + def does_not_match?(range) + @actual = range + expected.none? { |e| range.cover?(e) } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb new file mode 100644 index 0000000..08ed656 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb @@ -0,0 +1,44 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `eq`. + # Not intended to be instantiated directly. + class Eq < BaseMatcher + # @api private + # @return [String] + def failure_message + if string_encoding_differs? + "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using ==)\n" + else + "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + "\nexpected: value != #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n" + end + + # @api private + # @return [String] + def description + "eq #{expected_formatted}" + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + private + + def match(expected, actual) + actual == expected + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb new file mode 100644 index 0000000..32560df --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb @@ -0,0 +1,38 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `eql`. + # Not intended to be instantiated directly. + class Eql < BaseMatcher + # @api private + # @return [String] + def failure_message + if string_encoding_differs? + "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using eql?)\n" + else + "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + "\nexpected: value != #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n" + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + private + + def match(expected, actual) + actual.eql? expected + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb new file mode 100644 index 0000000..bbab3ed --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb @@ -0,0 +1,81 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `equal`. + # Not intended to be instantiated directly. + class Equal < BaseMatcher + # @api private + # @return [String] + def failure_message + if expected_is_a_literal_singleton? + simple_failure_message + else + detailed_failure_message + end + end + + # @api private + # @return [String] + def failure_message_when_negated + <<-MESSAGE + +expected not #{inspect_object(actual)} + got #{inspect_object(expected)} + +Compared using equal?, which compares object identity. + +MESSAGE + end + + # @api private + # @return [Boolean] + def diffable? + !expected_is_a_literal_singleton? + end + + private + + def match(expected, actual) + actual.equal? expected + end + + LITERAL_SINGLETONS = [true, false, nil] + + def expected_is_a_literal_singleton? + LITERAL_SINGLETONS.include?(expected) + end + + def actual_inspected + if LITERAL_SINGLETONS.include?(actual) + actual_formatted + else + inspect_object(actual) + end + end + + def simple_failure_message + "\nexpected #{expected_formatted}\n got #{actual_inspected}\n" + end + + def detailed_failure_message + <<-MESSAGE + +expected #{inspect_object(expected)} + got #{inspect_object(actual)} + +Compared using equal?, which compares object identity, +but expected and actual are not the same object. Use +`expect(actual).to eq(expected)` if you don't care about +object identity in this example. + +MESSAGE + end + + def inspect_object(o) + "#<#{o.class}:#{o.object_id}> => #{RSpec::Support::ObjectFormatter.format(o)}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb new file mode 100644 index 0000000..438625d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb @@ -0,0 +1,90 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `exist`. + # Not intended to be instantiated directly. + class Exist < BaseMatcher + def initialize(*expected) + @expected = expected + end + + # @api private + # @return [Boolean] + def matches?(actual) + @actual = actual + @test = ExistenceTest.new @actual, @expected + @test.valid_test? && @test.actual_exists? + end + + # @api private + # @return [Boolean] + def does_not_match?(actual) + @actual = actual + @test = ExistenceTest.new @actual, @expected + @test.valid_test? && !@test.actual_exists? + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to exist#{@test.validity_message}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} not to exist#{@test.validity_message}" + end + + # @api private + # Simple class for memoizing actual/expected for this matcher + # and examining the match + class ExistenceTest < Struct.new(:actual, :expected) + # @api private + # @return [Boolean] + def valid_test? + uniq_truthy_values.size == 1 + end + + # @api private + # @return [Boolean] + def actual_exists? + existence_values.first + end + + # @api private + # @return [String] + def validity_message + case uniq_truthy_values.size + when 0 + " but it does not respond to either `exist?` or `exists?`" + when 2 + " but `exist?` and `exists?` returned different values:\n\n"\ + " exist?: #{existence_values.first}\n"\ + "exists?: #{existence_values.last}" + end + end + + private + + def uniq_truthy_values + @uniq_truthy_values ||= existence_values.map { |v| !!v }.uniq + end + + def existence_values + @existence_values ||= predicates.map { |p| actual.__send__(p, *expected) } + end + + def predicates + @predicates ||= [:exist?, :exists?].select { |p| actual.respond_to?(p) && !deprecated(p, actual) } + end + + def deprecated(predicate, actual) + predicate == :exists? && (File == actual || FileTest == actual || Dir == actual) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb new file mode 100644 index 0000000..0f4e7e4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb @@ -0,0 +1,194 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for dynamic predicate matchers. + # Not intended to be inherited directly. + class DynamicPredicate < BaseMatcher + include BeHelpers + + def initialize(method_name, *args, &block) + @method_name, @args, @block = method_name, args, block + end + ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true) + + # @private + def matches?(actual, &block) + @actual = actual + @block ||= block + predicate_accessible? && predicate_matches? + end + + # @private + def does_not_match?(actual, &block) + @actual = actual + @block ||= block + predicate_accessible? && predicate_matches?(false) + end + + # @api private + # @return [String] + def failure_message + failure_message_expecting(true) + end + + # @api private + # @return [String] + def failure_message_when_negated + failure_message_expecting(false) + end + + # @api private + # @return [String] + def description + "#{method_description}#{args_to_sentence}" + end + + private + + # Catch a semi-frequent typo - if you have strict_predicate_matchers disabled and + # expect(spy).to have_receieveddd(:foo) it would be evergreen - the dynamic matcher + # queries `has_receiveddd?`, the spy _fakes_ the method, returning its (truthy) self. + if defined?(RSpec::Mocks::Double) + def really_responds_to?(method) + if RSpec::Mocks::Double === @actual + @actual.respond_to?(method) && methods_include?(method) + else + @actual.respond_to?(method) + end + end + else + # :nocov: + def really_responds_to?(method) + @actual.respond_to?(method) + end + # :nocov: + end + + def predicate_accessible? + really_responds_to?(predicate) + end + + # support 1.8.7, evaluate once at load time for performance + if String === methods.first + # :nocov: + def private_predicate? + @actual.private_methods.include? predicate.to_s + end + + def methods_include?(method) + @actual.methods.include?(method.to_s) + end + # :nocov: + else + def private_predicate? + @actual.private_methods.include? predicate + end + + def methods_include?(method) + @actual.methods.include?(method) + end + end + + def predicate_result + @predicate_result = actual.__send__(predicate_method_name, *@args, &@block) + end + + def predicate_method_name + predicate + end + + def predicate_matches?(value=true) + if RSpec::Expectations.configuration.strict_predicate_matchers? + value == predicate_result + else + value == !!predicate_result + end + end + + def root + # On 1.9, there appears to be a bug where String#match can return `false` + # rather than the match data object. Changing to Regex#match appears to + # work around this bug. For an example of this bug, see: + # https://travis-ci.org/rspec/rspec-expectations/jobs/27549635 + self.class::REGEX.match(@method_name.to_s).captures.first + end + + def method_description + EnglishPhrasing.split_words(@method_name) + end + + def failure_message_expecting(value) + validity_message || + "expected `#{actual_formatted}.#{predicate}#{args_to_s}` to #{expectation_of value}, got #{description_of @predicate_result}" + end + + def expectation_of(value) + if RSpec::Expectations.configuration.strict_predicate_matchers? + "return #{value}" + elsif value + "be truthy" + else + "be falsey" + end + end + + def validity_message + return nil if predicate_accessible? + + "expected #{actual_formatted} to respond to `#{predicate}`#{failure_to_respond_explanation}" + end + + def failure_to_respond_explanation + if private_predicate? + " but `#{predicate}` is a private method" + end + end + end + + # @api private + # Provides the implementation for `has_`. + # Not intended to be instantiated directly. + class Has < DynamicPredicate + # :nodoc: + REGEX = Matchers::HAS_REGEX + private + def predicate + @predicate ||= :"has_#{root}?" + end + end + + # @api private + # Provides the implementation of `be_`. + # Not intended to be instantiated directly. + class BePredicate < DynamicPredicate + # :nodoc: + REGEX = Matchers::BE_PREDICATE_REGEX + private + def predicate + @predicate ||= :"#{root}?" + end + + def predicate_method_name + actual.respond_to?(predicate) ? predicate : present_tense_predicate + end + + def failure_to_respond_explanation + super || if predicate == :true? + " or perhaps you meant `be true` or `be_truthy`" + elsif predicate == :false? + " or perhaps you meant `be false` or `be_falsey`" + end + end + + def predicate_accessible? + super || really_responds_to?(present_tense_predicate) + end + + def present_tense_predicate + :"#{root}s?" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb new file mode 100644 index 0000000..89be3f2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb @@ -0,0 +1,114 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `have_attributes`. + # Not intended to be instantiated directly. + class HaveAttributes < BaseMatcher + # @private + attr_reader :respond_to_failed + + def initialize(expected) + @expected = expected + @values = {} + @respond_to_failed = false + @negated = false + end + + # @private + def actual + @values + end + + # @api private + # @return [Boolean] + def matches?(actual) + @actual = actual + @negated = false + return false unless respond_to_attributes? + perform_match(:all?) + end + + # @api private + # @return [Boolean] + def does_not_match?(actual) + @actual = actual + @negated = true + return false unless respond_to_attributes? + perform_match(:none?) + end + + # @api private + # @return [String] + def description + described_items = surface_descriptions_in(expected) + improve_hash_formatting "have attributes #{RSpec::Support::ObjectFormatter.format(described_items)}" + end + + # @api private + # @return [Boolean] + def diffable? + !@respond_to_failed && !@negated + end + + # @api private + # @return [String] + def failure_message + respond_to_failure_message_or do + "expected #{actual_formatted} to #{description} but had attributes #{ formatted_values }" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + respond_to_failure_message_or { "expected #{actual_formatted} not to #{description}" } + end + + private + + def cache_all_values + @values = {} + expected.each do |attribute_key, _attribute_value| + actual_value = @actual.__send__(attribute_key) + @values[attribute_key] = actual_value + end + end + + def perform_match(predicate) + cache_all_values + expected.__send__(predicate) do |attribute_key, attribute_value| + actual_has_attribute?(attribute_key, attribute_value) + end + end + + def actual_has_attribute?(attribute_key, attribute_value) + values_match?(attribute_value, @values.fetch(attribute_key)) + end + + def respond_to_attributes? + matches = respond_to_matcher.matches?(@actual) + @respond_to_failed = !matches + matches + end + + def respond_to_matcher + @respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments.tap { |m| m.ignoring_method_signature_failure! } + end + + def respond_to_failure_message_or + if respond_to_failed + respond_to_matcher.failure_message + else + improve_hash_formatting(yield) + end + end + + def formatted_values + values = RSpec::Support::ObjectFormatter.format(@values) + improve_hash_formatting(values) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb new file mode 100644 index 0000000..3fedee3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb @@ -0,0 +1,218 @@ +require 'rspec/matchers/built_in/count_expectation' + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `include`. + # Not intended to be instantiated directly. + class Include < BaseMatcher # rubocop:disable Metrics/ClassLength + include CountExpectation + # @private + attr_reader :expecteds + + # @api private + def initialize(*expecteds) + raise(ArgumentError, 'include() is not supported, please supply an argument') if expecteds.empty? + @expecteds = expecteds + end + + # @api private + # @return [Boolean] + def matches?(actual) + check_actual?(actual) && + if check_expected_count? + expected_count_matches?(count_inclusions) + else + perform_match { |v| v } + end + end + + # @api private + # @return [Boolean] + def does_not_match?(actual) + check_actual?(actual) && + if check_expected_count? + !expected_count_matches?(count_inclusions) + else + perform_match { |v| !v } + end + end + + # @api private + # @return [String] + def description + improve_hash_formatting("include#{readable_list_of(expecteds)}#{count_expectation_description}") + end + + # @api private + # @return [String] + def failure_message + format_failure_message("to") { super } + end + + # @api private + # @return [String] + def failure_message_when_negated + format_failure_message("not to") { super } + end + + # @api private + # @return [Boolean] + def diffable? + !diff_would_wrongly_highlight_matched_item? + end + + # @api private + # @return [Array, Hash] + def expected + if expecteds.one? && Hash === expecteds.first + expecteds.first + else + expecteds + end + end + + private + + def check_actual?(actual) + actual = actual.to_hash if convert_to_hash?(actual) + @actual = actual + @actual.respond_to?(:include?) + end + + def check_expected_count? + case + when !has_expected_count? + return false + when expecteds.size != 1 + raise NotImplementedError, 'Count constraint supported only when testing for a single value being included' + when actual.is_a?(Hash) + raise NotImplementedError, 'Count constraint on hash keys not implemented' + end + true + end + + def format_failure_message(preposition) + msg = if actual.respond_to?(:include?) + "expected #{description_of @actual} #{preposition}" \ + " include#{readable_list_of @divergent_items}" \ + "#{count_failure_reason('it is included') if has_expected_count?}" + else + "#{yield}, but it does not respond to `include?`" + end + improve_hash_formatting(msg) + end + + def readable_list_of(items) + described_items = surface_descriptions_in(items) + if described_items.all? { |item| item.is_a?(Hash) } + " #{described_items.inject(:merge).inspect}" + else + EnglishPhrasing.list(described_items) + end + end + + def perform_match(&block) + @divergent_items = excluded_from_actual(&block) + @divergent_items.empty? + end + + def excluded_from_actual + return [] unless @actual.respond_to?(:include?) + + expecteds.inject([]) do |memo, expected_item| + if comparing_hash_to_a_subset?(expected_item) + expected_item.each do |(key, value)| + memo << { key => value } unless yield actual_hash_includes?(key, value) + end + elsif comparing_hash_keys?(expected_item) + memo << expected_item unless yield actual_hash_has_key?(expected_item) + else + memo << expected_item unless yield actual_collection_includes?(expected_item) + end + memo + end + end + + def comparing_hash_to_a_subset?(expected_item) + actual.is_a?(Hash) && expected_item.is_a?(Hash) + end + + def actual_hash_includes?(expected_key, expected_value) + actual_value = + actual.fetch(expected_key) do + actual.find(Proc.new { return false }) { |actual_key, _| values_match?(expected_key, actual_key) }[1] + end + values_match?(expected_value, actual_value) + end + + def comparing_hash_keys?(expected_item) + actual.is_a?(Hash) && !expected_item.is_a?(Hash) + end + + def actual_hash_has_key?(expected_key) + # We check `key?` first for perf: + # `key?` is O(1), but `any?` is O(N). + + has_exact_key = + begin + actual.key?(expected_key) + rescue + false + end + + has_exact_key || actual.keys.any? { |key| values_match?(expected_key, key) } + end + + def actual_collection_includes?(expected_item) + return actual.scan(expected_item).size > 0 if Regexp === expected_item && String === actual + return true if actual.include?(expected_item) + + # String lacks an `any?` method... + return false unless actual.respond_to?(:any?) + + actual.any? { |value| values_match?(expected_item, value) } + end + + if RUBY_VERSION < '1.9' + # :nocov: + def count_enumerable(expected_item) + actual.select { |value| values_match?(expected_item, value) }.size + end + # :nocov: + else + def count_enumerable(expected_item) + actual.count { |value| values_match?(expected_item, value) } + end + end + + def count_inclusions + @divergent_items = expected + case actual + when String + actual.scan(expected.first).length + when Enumerable + count_enumerable(Hash === expected ? expected : expected.first) + else + raise NotImplementedError, 'Count constraints are implemented for Enumerable and String values only' + end + end + + def diff_would_wrongly_highlight_matched_item? + return false unless actual.is_a?(String) && expected.is_a?(Array) + return false if Regexp === expecteds.first + + lines = actual.split("\n") + expected.any? do |str| + actual.include?(str) && lines.none? { |line| line == str } + end + end + + def convert_to_hash?(obj) + !obj.respond_to?(:include?) && obj.respond_to?(:to_hash) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb new file mode 100644 index 0000000..a822f76 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb @@ -0,0 +1,120 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `match`. + # Not intended to be instantiated directly. + class Match < BaseMatcher + def initialize(expected) + super(expected) + + @expected_captures = nil + end + # @api private + # @return [String] + def description + if @expected_captures && @expected.match(actual) + "match #{surface_descriptions_in(expected).inspect} with captures #{surface_descriptions_in(@expected_captures).inspect}" + else + "match #{surface_descriptions_in(expected).inspect}" + end + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + # Used to specify the captures we match against + # @return [self] + def with_captures(*captures) + @expected_captures = captures + self + end + + # @api private + # @return [String] + def failure_message + if Array === expected && !(actual.respond_to?(:to_a) || actual.respond_to?(:to_ary)) + return "expected a collection that can be converted to an array with " \ + "`#to_ary` or `#to_a`, but got #{actual_formatted}" + end + + super + end + + private + + def match(expected, actual) + return match_captures(expected, actual) if @expected_captures + return true if values_match?(expected, actual) + return false if Array === expected + return false unless can_safely_call_match?(expected, actual) + actual.match(expected) + end + + def can_safely_call_match?(expected, actual) + return false unless actual.respond_to?(:match) + + !(RSpec::Matchers.is_a_matcher?(expected) && + (String === actual || Regexp === actual)) + end + + def match_captures(expected, actual) + match = actual.match(expected) + if match + match = ReliableMatchData.new(match) + if match.names.empty? + values_match?(@expected_captures, match.captures) + else + expected_matcher = @expected_captures.last + values_match?(expected_matcher, Hash[match.names.zip(match.captures)]) || + values_match?(expected_matcher, Hash[match.names.map(&:to_sym).zip(match.captures)]) || + values_match?(@expected_captures, match.captures) + end + else + false + end + end + end + + # @api private + # Used to wrap match data and make it reliable for 1.8.7 + class ReliableMatchData + def initialize(match_data) + @match_data = match_data + end + + if RUBY_VERSION == "1.8.7" + # @api private + # Returns match data names for named captures + # @return Array + # :nocov: + def names + [] + end + # :nocov: + else + # @api private + # Returns match data names for named captures + # @return Array + def names + match_data.names + end + end + + # @api private + # returns an array of captures from the match data + # @return Array + def captures + match_data.captures + end + + protected + + attr_reader :match_data + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb new file mode 100644 index 0000000..64f8f3b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb @@ -0,0 +1,128 @@ +require 'rspec/support' + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for operator matchers. + # Not intended to be instantiated directly. + # Only available for use with `should`. + class OperatorMatcher + class << self + # @private + def registry + @registry ||= {} + end + + # @private + def register(klass, operator, matcher) + registry[klass] ||= {} + registry[klass][operator] = matcher + end + + # @private + def unregister(klass, operator) + registry[klass] && registry[klass].delete(operator) + end + + # @private + def get(klass, operator) + klass.ancestors.each do |ancestor| + matcher = registry[ancestor] && registry[ancestor][operator] + return matcher if matcher + end + + nil + end + end + + register Enumerable, '=~', BuiltIn::ContainExactly + + def initialize(actual) + @actual = actual + end + + # @private + def self.use_custom_matcher_or_delegate(operator) + define_method(operator) do |expected| + if !has_non_generic_implementation_of?(operator) && (matcher = OperatorMatcher.get(@actual.class, operator)) + @actual.__send__(::RSpec::Matchers.last_expectation_handler.should_method, matcher.new(expected)) + else + eval_match(@actual, operator, expected) + end + end + + negative_operator = operator.sub(/^=/, '!') + if negative_operator != operator && respond_to?(negative_operator) + define_method(negative_operator) do |_expected| + opposite_should = ::RSpec::Matchers.last_expectation_handler.opposite_should_method + raise "RSpec does not support `#{::RSpec::Matchers.last_expectation_handler.should_method} #{negative_operator} expected`. " \ + "Use `#{opposite_should} #{operator} expected` instead." + end + end + end + + ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator| + use_custom_matcher_or_delegate operator + end + + # @private + def fail_with_message(message) + RSpec::Expectations.fail_with(message, @expected, @actual) + end + + # @api private + # @return [String] + def description + "#{@operator} #{RSpec::Support::ObjectFormatter.format(@expected)}" + end + + private + + def has_non_generic_implementation_of?(op) + Support.method_handle_for(@actual, op).owner != ::Kernel + rescue NameError + false + end + + def eval_match(actual, operator, expected) + ::RSpec::Matchers.last_matcher = self + @operator, @expected = operator, expected + __delegate_operator(actual, operator, expected) + end + end + + # @private + # Handles operator matcher for `should`. + class PositiveOperatorMatcher < OperatorMatcher + def __delegate_operator(actual, operator, expected) + if actual.__send__(operator, expected) + true + else + expected_formatted = RSpec::Support::ObjectFormatter.format(expected) + actual_formatted = RSpec::Support::ObjectFormatter.format(actual) + + if ['==', '===', '=~'].include?(operator) + fail_with_message("expected: #{expected_formatted}\n got: #{actual_formatted} (using #{operator})") + else + fail_with_message("expected: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") + end + end + end + end + + # @private + # Handles operator matcher for `should_not`. + class NegativeOperatorMatcher < OperatorMatcher + def __delegate_operator(actual, operator, expected) + return false unless actual.__send__(operator, expected) + + expected_formatted = RSpec::Support::ObjectFormatter.format(expected) + actual_formatted = RSpec::Support::ObjectFormatter.format(actual) + + fail_with_message("expected not: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb new file mode 100644 index 0000000..8c3cced --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb @@ -0,0 +1,207 @@ +require 'stringio' + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `output`. + # Not intended to be instantiated directly. + class Output < BaseMatcher + def initialize(expected) + @expected = expected + @actual = "" + @block = nil + @stream_capturer = NullCapture + end + + def matches?(block) + @block = block + return false unless Proc === block + @actual = @stream_capturer.capture(block) + @expected ? values_match?(@expected, @actual) : captured? + end + + def does_not_match?(block) + !matches?(block) && Proc === block + end + + # @api public + # Tells the matcher to match against stdout. + # Works only when the main Ruby process prints to stdout + def to_stdout + @stream_capturer = CaptureStdout + self + end + + # @api public + # Tells the matcher to match against stderr. + # Works only when the main Ruby process prints to stderr + def to_stderr + @stream_capturer = CaptureStderr + self + end + + # @api public + # Tells the matcher to match against stdout. + # Works when subprocesses print to stdout as well. + # This is significantly (~30x) slower than `to_stdout` + def to_stdout_from_any_process + @stream_capturer = CaptureStreamToTempfile.new("stdout", $stdout) + self + end + + # @api public + # Tells the matcher to match against stderr. + # Works when subprocesses print to stderr as well. + # This is significantly (~30x) slower than `to_stderr` + def to_stderr_from_any_process + @stream_capturer = CaptureStreamToTempfile.new("stderr", $stderr) + self + end + + # @api private + # @return [String] + def failure_message + "expected block to #{description}, but #{positive_failure_reason}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected block to not #{description}, but #{negative_failure_reason}" + end + + # @api private + # @return [String] + def description + if @expected + "output #{description_of @expected} to #{@stream_capturer.name}" + else + "output to #{@stream_capturer.name}" + end + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + # @api private + # Indicates this matcher matches against a block. + # @return [True] + def supports_block_expectations? + true + end + + # @api private + # Indicates this matcher matches against a block only. + # @return [False] + def supports_value_expectations? + false + end + + private + + def captured? + @actual.length > 0 + end + + def positive_failure_reason + return "was not a block" unless Proc === @block + return "output #{actual_output_description}" if @expected + "did not" + end + + def negative_failure_reason + return "was not a block" unless Proc === @block + "output #{actual_output_description}" + end + + def actual_output_description + return "nothing" unless captured? + actual_formatted + end + end + + # @private + module NullCapture + def self.name + "some stream" + end + + def self.capture(_block) + raise "You must chain `to_stdout` or `to_stderr` off of the `output(...)` matcher." + end + end + + # @private + module CaptureStdout + def self.name + 'stdout' + end + + def self.capture(block) + captured_stream = StringIO.new + + original_stream = $stdout + $stdout = captured_stream + + block.call + + captured_stream.string + ensure + $stdout = original_stream + end + end + + # @private + module CaptureStderr + def self.name + 'stderr' + end + + def self.capture(block) + captured_stream = StringIO.new + + original_stream = $stderr + $stderr = captured_stream + + block.call + + captured_stream.string + ensure + $stderr = original_stream + end + end + + # @private + class CaptureStreamToTempfile < Struct.new(:name, :stream) + def capture(block) + # We delay loading tempfile until it is actually needed because + # we want to minimize stdlibs loaded so that users who use a + # portion of the stdlib can't have passing specs while forgetting + # to load it themselves. `CaptureStreamToTempfile` is rarely used + # and `tempfile` pulls in a bunch of things (delegate, tmpdir, + # thread, fileutils, etc), so it's worth delaying it until this point. + require 'tempfile' + + original_stream = stream.clone + captured_stream = Tempfile.new(name) + + begin + captured_stream.sync = true + stream.reopen(captured_stream) + block.call + captured_stream.rewind + captured_stream.read + ensure + stream.reopen(original_stream) + captured_stream.close + captured_stream.unlink + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb new file mode 100644 index 0000000..bbaaf62 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb @@ -0,0 +1,275 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `raise_error`. + # Not intended to be instantiated directly. + # rubocop:disable Metrics/ClassLength + # rubocop:disable Lint/RescueException + class RaiseError + include Composable + + # Used as a sentinel value to be able to tell when the user did not pass an + # argument. We can't use `nil` for that because we need to warn when `nil` is + # passed in a different way. It's an Object, not a Module, since Module's `===` + # does not evaluate to true when compared to itself. + # + # Note; this _is_ the default value supplied for expected_error_or_message, but + # because there are two method-calls involved, that default is actually supplied + # in the definition of the _matcher_ method, `RSpec::Matchers#raise_error` + UndefinedValue = Object.new.freeze + + def initialize(expected_error_or_message, expected_message, &block) + @block = block + @actual_error = nil + @warn_about_bare_error = UndefinedValue === expected_error_or_message + @warn_about_nil_error = expected_error_or_message.nil? + + case expected_error_or_message + when nil, UndefinedValue + @expected_error = Exception + @expected_message = expected_message + when String, Regexp + @expected_error = Exception + @expected_message = expected_error_or_message + else + @expected_error = expected_error_or_message + @expected_message = expected_message + end + end + + # @api public + # Specifies the expected error message. + def with_message(expected_message) + raise_message_already_set if @expected_message + @warn_about_bare_error = false + @expected_message = expected_message + self + end + + # rubocop:disable Metrics/MethodLength + # @private + def matches?(given_proc, negative_expectation=false, &block) + @given_proc = given_proc + @block ||= block + @raised_expected_error = false + @with_expected_message = false + @eval_block = false + @eval_block_passed = false + + return false unless Proc === given_proc + + begin + given_proc.call + rescue Exception => @actual_error + if values_match?(@expected_error, @actual_error) || + values_match?(@expected_error, actual_error_message) + @raised_expected_error = true + @with_expected_message = verify_message + end + end + + unless negative_expectation + warn_about_bare_error! if warn_about_bare_error? + warn_about_nil_error! if warn_about_nil_error? + eval_block if ready_to_eval_block? + end + + expectation_matched? + end + # rubocop:enable Metrics/MethodLength + + # @private + def does_not_match?(given_proc) + warn_for_negative_false_positives! + !matches?(given_proc, :negative_expectation) && Proc === given_proc + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + # @private + def expects_call_stack_jump? + true + end + + # @api private + # @return [String] + def failure_message + @eval_block ? actual_error_message : "expected #{expected_error}#{given_error}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected no #{expected_error}#{given_error}" + end + + # @api private + # @return [String] + def description + "raise #{expected_error}" + end + + private + + def actual_error_message + return nil unless @actual_error + + @actual_error.respond_to?(:original_message) ? @actual_error.original_message : @actual_error.message + end + + def expectation_matched? + error_and_message_match? && block_matches? + end + + def error_and_message_match? + @raised_expected_error && @with_expected_message + end + + def block_matches? + @eval_block ? @eval_block_passed : true + end + + def ready_to_eval_block? + @raised_expected_error && @with_expected_message && @block + end + + def eval_block + @eval_block = true + begin + @block[@actual_error] + @eval_block_passed = true + rescue Exception => err + @actual_error = err + end + end + + def verify_message + return true if @expected_message.nil? + values_match?(@expected_message, actual_error_message.to_s) + end + + def warn_for_negative_false_positives! + expression = if expecting_specific_exception? && @expected_message + "`expect { }.not_to raise_error(SpecificErrorClass, message)`" + elsif expecting_specific_exception? + "`expect { }.not_to raise_error(SpecificErrorClass)`" + elsif @expected_message + "`expect { }.not_to raise_error(message)`" + elsif @warn_about_nil_error + "`expect { }.not_to raise_error(nil)`" + end + + return unless expression + + warn_about_negative_false_positive! expression + end + + def handle_warning(message) + RSpec::Expectations.configuration.false_positives_handler.call(message) + end + + def warn_about_bare_error? + @warn_about_bare_error && @block.nil? + end + + def warn_about_nil_error? + @warn_about_nil_error + end + + def warn_about_bare_error! + handle_warning("Using the `raise_error` matcher without providing a specific " \ + "error or message risks false positives, since `raise_error` " \ + "will match when Ruby raises a `NoMethodError`, `NameError` or " \ + "`ArgumentError`, potentially allowing the expectation to pass " \ + "without even executing the method you are intending to call. " \ + "#{warning}"\ + "Instead consider providing a specific error class or message. " \ + "This message can be suppressed by setting: " \ + "`RSpec::Expectations.configuration.on_potential_false" \ + "_positives = :nothing`") + end + + def warn_about_nil_error! + handle_warning("Using the `raise_error` matcher with a `nil` error is probably " \ + "unintentional, it risks false positives, since `raise_error` " \ + "will match when Ruby raises a `NoMethodError`, `NameError` or " \ + "`ArgumentError`, potentially allowing the expectation to pass " \ + "without even executing the method you are intending to call. " \ + "#{warning}"\ + "Instead consider providing a specific error class or message. " \ + "This message can be suppressed by setting: " \ + "`RSpec::Expectations.configuration.on_potential_false" \ + "_positives = :nothing`") + end + + def warn_about_negative_false_positive!(expression) + handle_warning("Using #{expression} risks false positives, since literally " \ + "any other error would cause the expectation to pass, " \ + "including those raised by Ruby (e.g. `NoMethodError`, `NameError` " \ + "and `ArgumentError`), meaning the code you are intending to test " \ + "may not even get reached. Instead consider using " \ + "`expect { }.not_to raise_error` or `expect { }.to raise_error" \ + "(DifferentSpecificErrorClass)`. This message can be suppressed by " \ + "setting: `RSpec::Expectations.configuration.on_potential_false" \ + "_positives = :nothing`") + end + + def expected_error + case @expected_message + when nil + if RSpec::Support.is_a_matcher?(@expected_error) + "Exception with #{description_of(@expected_error)}" + else + description_of(@expected_error) + end + when Regexp + "#{@expected_error} with message matching #{description_of(@expected_message)}" + else + "#{@expected_error} with #{description_of(@expected_message)}" + end + end + + def format_backtrace(backtrace) + formatter = Matchers.configuration.backtrace_formatter + formatter.format_backtrace(backtrace) + end + + def given_error + return " but was not given a block" unless Proc === @given_proc + return " but nothing was raised" unless @actual_error + + backtrace = format_backtrace(@actual_error.backtrace) + [ + ", got #{description_of(@actual_error)} with backtrace:", + *backtrace + ].join("\n # ") + end + + def expecting_specific_exception? + @expected_error != Exception + end + + def raise_message_already_set + raise "`expect { }.to raise_error(message).with_message(message)` is not valid. " \ + 'The matcher only allows the expected message to be specified once' + end + + def warning + warning = "Actual error raised was #{description_of(@actual_error)}. " + warning if @actual_error + end + end + # rubocop:enable Lint/RescueException + # rubocop:enable Metrics/ClassLength + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb new file mode 100644 index 0000000..9adbe04 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb @@ -0,0 +1,200 @@ +RSpec::Support.require_rspec_support "method_signature_verifier" + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `respond_to`. + # Not intended to be instantiated directly. + class RespondTo < BaseMatcher + def initialize(*names) + @names = names + @expected_arity = nil + @expected_keywords = [] + @ignoring_method_signature_failure = false + @unlimited_arguments = nil + @arbitrary_keywords = nil + end + + # @api public + # Specifies the number of expected arguments. + # + # @example + # expect(obj).to respond_to(:message).with(3).arguments + def with(n) + @expected_arity = n + self + end + + # @api public + # Specifies keyword arguments, if any. + # + # @example + # expect(obj).to respond_to(:message).with_keywords(:color, :shape) + # @example with an expected number of arguments + # expect(obj).to respond_to(:message).with(3).arguments.and_keywords(:color, :shape) + def with_keywords(*keywords) + @expected_keywords = keywords + self + end + alias :and_keywords :with_keywords + + # @api public + # Specifies that the method accepts any keyword, i.e. the method has + # a splatted keyword parameter of the form **kw_args. + # + # @example + # expect(obj).to respond_to(:message).with_any_keywords + def with_any_keywords + @arbitrary_keywords = true + self + end + alias :and_any_keywords :with_any_keywords + + # @api public + # Specifies that the number of arguments has no upper limit, i.e. the + # method has a splatted parameter of the form *args. + # + # @example + # expect(obj).to respond_to(:message).with_unlimited_arguments + def with_unlimited_arguments + @unlimited_arguments = true + self + end + alias :and_unlimited_arguments :with_unlimited_arguments + + # @api public + # No-op. Intended to be used as syntactic sugar when using `with`. + # + # @example + # expect(obj).to respond_to(:message).with(3).arguments + def argument + self + end + alias :arguments :argument + + # @private + def matches?(actual) + find_failing_method_names(actual, :reject).empty? + end + + # @private + def does_not_match?(actual) + find_failing_method_names(actual, :select).empty? + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to respond to #{@failing_method_names.map { |name| description_of(name) }.join(', ')}#{with_arity}" + end + + # @api private + # @return [String] + def failure_message_when_negated + failure_message.sub(/to respond to/, 'not to respond to') + end + + # @api private + # @return [String] + def description + "respond to #{pp_names}#{with_arity}" + end + + # @api private + # Used by other matchers to suppress a check + def ignoring_method_signature_failure! + @ignoring_method_signature_failure = true + end + + private + + def find_failing_method_names(actual, filter_method) + @actual = actual + @failing_method_names = @names.__send__(filter_method) do |name| + @actual.respond_to?(name) && matches_arity?(actual, name) + end + end + + def matches_arity?(actual, name) + ArityCheck.new(@expected_arity, @expected_keywords, @arbitrary_keywords, @unlimited_arguments).matches?(actual, name) + rescue NameError + return true if @ignoring_method_signature_failure + raise ArgumentError, "The #{matcher_name} matcher requires that " \ + "the actual object define the method(s) in " \ + "order to check arity, but the method " \ + "`#{name}` is not defined. Remove the arity " \ + "check or define the method to continue." + end + + def with_arity + str = ''.dup + str << " with #{with_arity_string}" if @expected_arity + str << " #{str.length == 0 ? 'with' : 'and'} #{with_keywords_string}" if @expected_keywords && @expected_keywords.count > 0 + str << " #{str.length == 0 ? 'with' : 'and'} unlimited arguments" if @unlimited_arguments + str << " #{str.length == 0 ? 'with' : 'and'} any keywords" if @arbitrary_keywords + str + end + + def with_arity_string + "#{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}" + end + + def with_keywords_string + kw_str = case @expected_keywords.count + when 1 + @expected_keywords.first.inspect + when 2 + @expected_keywords.map(&:inspect).join(' and ') + else + "#{@expected_keywords[0...-1].map(&:inspect).join(', ')}, and #{@expected_keywords.last.inspect}" + end + + "keyword#{@expected_keywords.count == 1 ? '' : 's'} #{kw_str}" + end + + def pp_names + @names.length == 1 ? "##{@names.first}" : description_of(@names) + end + + # @private + class ArityCheck + def initialize(expected_arity, expected_keywords, arbitrary_keywords, unlimited_arguments) + expectation = Support::MethodSignatureExpectation.new + + if expected_arity.is_a?(Range) + expectation.min_count = expected_arity.min + expectation.max_count = expected_arity.max + else + expectation.min_count = expected_arity + end + + expectation.keywords = expected_keywords + expectation.expect_unlimited_arguments = unlimited_arguments + expectation.expect_arbitrary_keywords = arbitrary_keywords + @expectation = expectation + end + + def matches?(actual, name) + return true if @expectation.empty? + verifier_for(actual, name).with_expectation(@expectation).valid? + end + + def verifier_for(actual, name) + Support::StrictSignatureVerifier.new(method_signature_for(actual, name)) + end + + def method_signature_for(actual, name) + method_handle = Support.method_handle_for(actual, name) + + if name == :new && method_handle.owner === ::Class && ::Class === actual + Support::MethodSignature.new(actual.instance_method(:initialize)) + else + Support::MethodSignature.new(method_handle) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb new file mode 100644 index 0000000..a50967b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb @@ -0,0 +1,62 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `satisfy`. + # Not intended to be instantiated directly. + class Satisfy < BaseMatcher + def initialize(description=nil, &block) + @description = description + @block = block + end + + # @private + def matches?(actual, &block) + @block = block if block + @actual = actual + @block.call(actual) + end + + # @private + def description + @description ||= "satisfy #{block_representation}" + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to #{description}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} not to #{description}" + end + + private + + if RSpec::Support::RubyFeatures.ripper_supported? + def block_representation + if (block_snippet = extract_block_snippet) + "expression `#{block_snippet}`" + else + 'block' + end + end + + def extract_block_snippet + return nil unless @block + Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@block, matcher_name) + end + else + # :nocov: + def block_representation + 'block' + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb new file mode 100644 index 0000000..81f06c2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb @@ -0,0 +1,94 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Base class for the `end_with` and `start_with` matchers. + # Not intended to be instantiated directly. + class StartOrEndWith < BaseMatcher + def initialize(*expected) + @actual_does_not_have_ordered_elements = false + @expected = expected.length == 1 ? expected.first : expected + end + + # @api private + # @return [String] + def failure_message + super.tap do |msg| + if @actual_does_not_have_ordered_elements + msg << ", but it does not have ordered elements" + elsif !actual.respond_to?(:[]) + msg << ", but it cannot be indexed using #[]" + end + end + end + + # @api private + # @return [String] + def description + return super unless Hash === expected + english_name = EnglishPhrasing.split_words(self.class.matcher_name) + description_of_expected = surface_descriptions_in(expected).inspect + "#{english_name} #{description_of_expected}" + end + + private + + def match(_expected, actual) + return false unless actual.respond_to?(:[]) + + begin + return true if subsets_comparable? && subset_matches? + element_matches? + rescue ArgumentError + @actual_does_not_have_ordered_elements = true + return false + end + end + + def subsets_comparable? + # Structs support the Enumerable interface but don't really have + # the semantics of a subset of a larger set... + return false if Struct === expected + + expected.respond_to?(:length) + end + end + + # For RSpec 3.1, the base class was named `StartAndEndWith`. For SemVer reasons, + # we still provide this constant until 4.0. + # @deprecated Use StartOrEndWith instead. + # @private + StartAndEndWith = StartOrEndWith + + # @api private + # Provides the implementation for `start_with`. + # Not intended to be instantiated directly. + class StartWith < StartOrEndWith + private + + def subset_matches? + values_match?(expected, actual[0, expected.length]) + end + + def element_matches? + values_match?(expected, actual[0]) + end + end + + # @api private + # Provides the implementation for `end_with`. + # Not intended to be instantiated directly. + class EndWith < StartOrEndWith + private + + def subset_matches? + values_match?(expected, actual[-expected.length, expected.length]) + end + + def element_matches? + values_match?(expected, actual[-1]) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb new file mode 100644 index 0000000..e1bb4c5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb @@ -0,0 +1,138 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `throw_symbol`. + # Not intended to be instantiated directly. + class ThrowSymbol + include Composable + + def initialize(expected_symbol=nil, expected_arg=nil) + @expected_symbol = expected_symbol + @expected_arg = expected_arg + @caught_symbol = @caught_arg = nil + end + + # rubocop:disable Metrics/MethodLength + # @private + def matches?(given_proc) + @block = given_proc + return false unless Proc === given_proc + + begin + if @expected_symbol.nil? + given_proc.call + else + @caught_arg = catch :proc_did_not_throw_anything do + catch @expected_symbol do + given_proc.call + throw :proc_did_not_throw_anything, :nothing_thrown + end + end + + if @caught_arg == :nothing_thrown + @caught_arg = nil + else + @caught_symbol = @expected_symbol + end + end + + # Ruby 1.8 uses NameError with `symbol' + # Ruby 1.9 uses ArgumentError with :symbol + rescue NameError, ArgumentError => e + unless (match_data = e.message.match(/uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/)) + other_exception = e + raise + end + @caught_symbol = match_data.captures[1].to_sym + rescue => other_exception + raise + ensure + # rubocop:disable Lint/EnsureReturn + unless other_exception + if @expected_symbol.nil? + return !!@caught_symbol + else + if @expected_arg.nil? + return @caught_symbol == @expected_symbol + else + return (@caught_symbol == @expected_symbol) && values_match?(@expected_arg, @caught_arg) + end + end + end + # rubocop:enable Lint/EnsureReturn + end + end + # rubocop:enable Metrics/MethodLength + + def does_not_match?(given_proc) + !matches?(given_proc) && Proc === given_proc + end + + # @api private + # @return [String] + def failure_message + "expected #{expected} to be thrown, #{actual_result}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{expected('no Symbol')}#{' not' if @expected_symbol} to be thrown, #{actual_result}" + end + + # @api private + # @return [String] + def description + "throw #{expected}" + end + + # @api private + # Indicates this matcher matches against a block. + # @return [True] + def supports_block_expectations? + true + end + + # @api private + def supports_value_expectations? + false + end + + # @api private + def expects_call_stack_jump? + true + end + + private + + def actual_result + return "but was not a block" unless Proc === @block + "got #{caught}" + end + + def expected(symbol_desc='a Symbol') + throw_description(@expected_symbol || symbol_desc, @expected_arg) + end + + def caught + throw_description(@caught_symbol || 'nothing', @caught_arg) + end + + def throw_description(symbol, arg) + symbol_description = symbol.is_a?(String) ? symbol : description_of(symbol) + + arg_description = if arg + " with #{description_of arg}" + elsif @expected_arg && @caught_symbol == @expected_symbol + " with no argument" + else + "" + end + + symbol_description + arg_description + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb new file mode 100644 index 0000000..c443dc0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb @@ -0,0 +1,375 @@ +require 'rspec/matchers/built_in/count_expectation' + +RSpec::Support.require_rspec_support 'method_signature_verifier' + +module RSpec + module Matchers + module BuiltIn + # @private + # Object that is yielded to `expect` when one of the + # yield matchers is used. Provides information about + # the yield behavior of the object-under-test. + class YieldProbe + def self.probe(block, &callback) + probe = new(block, &callback) + return probe unless probe.has_block? + probe.probe + end + + attr_accessor :num_yields, :yielded_args + + def initialize(block, &callback) + @block = block + @callback = callback || Proc.new {} + @used = false + self.num_yields = 0 + self.yielded_args = [] + end + + def has_block? + Proc === @block + end + + def probe + assert_valid_expect_block! + @block.call(self) + assert_used! + self + end + + def to_proc + @used = true + + probe = self + callback = @callback + Proc.new do |*args| + probe.num_yields += 1 + probe.yielded_args << args + callback.call(*args) + nil # to indicate the block does not return a meaningful value + end + end + + def single_yield_args + yielded_args.first + end + + def yielded_once?(matcher_name) + case num_yields + when 1 then true + when 0 then false + else + raise "The #{matcher_name} matcher is not designed to be used with a " \ + 'method that yields multiple times. Use the yield_successive_args ' \ + 'matcher for that case.' + end + end + + def assert_used! + return if @used + raise 'You must pass the argument yielded to your expect block on ' \ + 'to the method-under-test as a block. It acts as a probe that ' \ + 'allows the matcher to detect whether or not the method-under-test ' \ + 'yields, and, if so, how many times, and what the yielded arguments ' \ + 'are.' + end + + if RUBY_VERSION.to_f > 1.8 + def assert_valid_expect_block! + block_signature = RSpec::Support::BlockSignature.new(@block) + return if RSpec::Support::StrictSignatureVerifier.new(block_signature, [self]).valid? + raise 'Your expect block must accept an argument to be used with this ' \ + 'matcher. Pass the argument as a block on to the method you are testing.' + end + else + # :nocov: + # On 1.8.7, `lambda { }.arity` and `lambda { |*a| }.arity` both return -1, + # so we can't distinguish between accepting no args and an arg splat. + # It's OK to skip, this, though; it just provides a nice error message + # when the user forgets to accept an arg in their block. They'll still get + # the `assert_used!` error message from above, which is sufficient. + def assert_valid_expect_block! + # nothing to do + end + # :nocov: + end + end + + # @api private + # Provides the implementation for `yield_control`. + # Not intended to be instantiated directly. + class YieldControl < BaseMatcher + include CountExpectation + # @private + def matches?(block) + @probe = YieldProbe.probe(block) + return false unless @probe.has_block? + expected_count_matches?(@probe.num_yields) + end + + # @private + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @api private + # @return [String] + def failure_message + 'expected given block to yield control' + failure_reason + end + + # @api private + # @return [String] + def failure_message_when_negated + 'expected given block not to yield control' + failure_reason + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def failure_reason + return ' but was not a block' unless @probe.has_block? + return "#{count_expectation_description} but did not yield" if @probe.num_yields == 0 + count_failure_reason('yielded') + end + end + + # @api private + # Provides the implementation for `yield_with_no_args`. + # Not intended to be instantiated directly. + class YieldWithNoArgs < BaseMatcher + # @private + def matches?(block) + @probe = YieldProbe.probe(block) + return false unless @probe.has_block? + @probe.yielded_once?(:yield_with_no_args) && @probe.single_yield_args.empty? + end + + # @private + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @private + def failure_message + "expected given block to yield with no arguments, but #{positive_failure_reason}" + end + + # @private + def failure_message_when_negated + "expected given block not to yield with no arguments, but #{negative_failure_reason}" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def positive_failure_reason + return 'was not a block' unless @probe.has_block? + return 'did not yield' if @probe.num_yields.zero? + "yielded with arguments: #{description_of @probe.single_yield_args}" + end + + def negative_failure_reason + return 'was not a block' unless @probe.has_block? + 'did' + end + end + + # @api private + # Provides the implementation for `yield_with_args`. + # Not intended to be instantiated directly. + class YieldWithArgs < BaseMatcher + def initialize(*args) + @expected = args + end + + # @private + def matches?(block) + @args_matched_when_yielded = true + @probe = YieldProbe.new(block) do + @actual = @probe.single_yield_args + @actual_formatted = actual_formatted + @args_matched_when_yielded &&= args_currently_match? + end + return false unless @probe.has_block? + @probe.probe + @probe.yielded_once?(:yield_with_args) && @args_matched_when_yielded + end + + # @private + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @private + def failure_message + "expected given block to yield with arguments, but #{positive_failure_reason}" + end + + # @private + def failure_message_when_negated + "expected given block not to yield with arguments, but #{negative_failure_reason}" + end + + # @private + def description + desc = 'yield with args' + desc = "#{desc}(#{expected_arg_description})" unless @expected.empty? + desc + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def positive_failure_reason + return 'was not a block' unless @probe.has_block? + return 'did not yield' if @probe.num_yields.zero? + @positive_args_failure + end + + def expected_arg_description + @expected.map { |e| description_of e }.join(', ') + end + + def negative_failure_reason + if !@probe.has_block? + 'was not a block' + elsif @args_matched_when_yielded && !@expected.empty? + 'yielded with expected arguments' \ + "\nexpected not: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: #{@actual_formatted}" + else + 'did' + end + end + + def args_currently_match? + if @expected.empty? # expect {...}.to yield_with_args + @positive_args_failure = 'yielded with no arguments' if @actual.empty? + return !@actual.empty? + end + + unless (match = all_args_match?) + @positive_args_failure = 'yielded with unexpected arguments' \ + "\nexpected: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: #{@actual_formatted}" + end + + match + end + + def all_args_match? + values_match?(@expected, @actual) + end + end + + # @api private + # Provides the implementation for `yield_successive_args`. + # Not intended to be instantiated directly. + class YieldSuccessiveArgs < BaseMatcher + def initialize(*args) + @expected = args + end + + # @private + def matches?(block) + @actual_formatted = [] + @actual = [] + args_matched_when_yielded = true + yield_count = 0 + + @probe = YieldProbe.probe(block) do |*arg_array| + arg_or_args = arg_array.size == 1 ? arg_array.first : arg_array + @actual_formatted << RSpec::Support::ObjectFormatter.format(arg_or_args) + @actual << arg_or_args + args_matched_when_yielded &&= values_match?(@expected[yield_count], arg_or_args) + yield_count += 1 + end + + return false unless @probe.has_block? + args_matched_when_yielded && yield_count == @expected.length + end + + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @private + def failure_message + 'expected given block to yield successively with arguments, ' \ + "but #{positive_failure_reason}" + end + + # @private + def failure_message_when_negated + 'expected given block not to yield successively with arguments, ' \ + "but #{negative_failure_reason}" + end + + # @private + def description + "yield successive args(#{expected_arg_description})" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def expected_arg_description + @expected.map { |e| description_of e }.join(', ') + end + + def positive_failure_reason + return 'was not a block' unless @probe.has_block? + + 'yielded with unexpected arguments' \ + "\nexpected: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: [#{@actual_formatted.join(", ")}]" + end + + def negative_failure_reason + return 'was not a block' unless @probe.has_block? + + 'yielded with expected arguments' \ + "\nexpected not: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: [#{@actual_formatted.join(", ")}]" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb new file mode 100644 index 0000000..e4816e9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb @@ -0,0 +1,171 @@ +RSpec::Support.require_rspec_support "fuzzy_matcher" + +module RSpec + module Matchers + # Mixin designed to support the composable matcher features + # of RSpec 3+. Mix it into your custom matcher classes to + # allow them to be used in a composable fashion. + # + # @api public + module Composable + # Creates a compound `and` expectation. The matcher will + # only pass if both sub-matchers pass. + # This can be chained together to form an arbitrarily long + # chain of matchers. + # + # @example + # expect(alphabet).to start_with("a").and end_with("z") + # expect(alphabet).to start_with("a") & end_with("z") + # + # @note The negative form (`expect(...).not_to matcher.and other`) + # is not supported at this time. + def and(matcher) + BuiltIn::Compound::And.new self, matcher + end + alias & and + + # Creates a compound `or` expectation. The matcher will + # pass if either sub-matcher passes. + # This can be chained together to form an arbitrarily long + # chain of matchers. + # + # @example + # expect(stoplight.color).to eq("red").or eq("green").or eq("yellow") + # expect(stoplight.color).to eq("red") | eq("green") | eq("yellow") + # + # @note The negative form (`expect(...).not_to matcher.or other`) + # is not supported at this time. + def or(matcher) + BuiltIn::Compound::Or.new self, matcher + end + alias | or + + # Delegates to `#matches?`. Allows matchers to be used in composable + # fashion and also supports using matchers in case statements. + def ===(value) + matches?(value) + end + + private + + # This provides a generic way to fuzzy-match an expected value against + # an actual value. It understands nested data structures (e.g. hashes + # and arrays) and is able to match against a matcher being used as + # the expected value or within the expected value at any level of + # nesting. + # + # Within a custom matcher you are encouraged to use this whenever your + # matcher needs to match two values, unless it needs more precise semantics. + # For example, the `eq` matcher _does not_ use this as it is meant to + # use `==` (and only `==`) for matching. + # + # @param expected [Object] what is expected + # @param actual [Object] the actual value + # + # @!visibility public + def values_match?(expected, actual) + expected = with_matchers_cloned(expected) + Support::FuzzyMatcher.values_match?(expected, actual) + end + + # Returns the description of the given object in a way that is + # aware of composed matchers. If the object is a matcher with + # a `description` method, returns the description; otherwise + # returns `object.inspect`. + # + # You are encouraged to use this in your custom matcher's + # `description`, `failure_message` or + # `failure_message_when_negated` implementation if you are + # supporting matcher arguments. + # + # @!visibility public + def description_of(object) + RSpec::Support::ObjectFormatter.format(object) + end + + # Transforms the given data structure (typically a hash or array) + # into a new data structure that, when `#inspect` is called on it, + # will provide descriptions of any contained matchers rather than + # the normal `#inspect` output. + # + # You are encouraged to use this in your custom matcher's + # `description`, `failure_message` or + # `failure_message_when_negated` implementation if you are + # supporting any arguments which may be a data structure + # containing matchers. + # + # @!visibility public + def surface_descriptions_in(item) + if Matchers.is_a_describable_matcher?(item) + DescribableItem.new(item) + elsif Hash === item + Hash[surface_descriptions_in(item.to_a)] + elsif Struct === item || unreadable_io?(item) + RSpec::Support::ObjectFormatter.format(item) + elsif should_enumerate?(item) + item.map { |subitem| surface_descriptions_in(subitem) } + else + item + end + end + + # @private + # Historically, a single matcher instance was only checked + # against a single value. Given that the matcher was only + # used once, it's been common to memoize some intermediate + # calculation that is derived from the `actual` value in + # order to reuse that intermediate result in the failure + # message. + # + # This can cause a problem when using such a matcher as an + # argument to another matcher in a composed matcher expression, + # since the matcher instance may be checked against multiple + # values and produce invalid results due to the memoization. + # + # To deal with this, we clone any matchers in `expected` via + # this method when using `values_match?`, so that any memoization + # does not "leak" between checks. + def with_matchers_cloned(object) + if Matchers.is_a_matcher?(object) + object.clone + elsif Hash === object + Hash[with_matchers_cloned(object.to_a)] + elsif should_enumerate?(object) + object.map { |subobject| with_matchers_cloned(subobject) } + else + object + end + end + + # @api private + # We should enumerate arrays as long as they are not recursive. + def should_enumerate?(item) + Array === item && item.none? { |subitem| subitem.equal?(item) } + end + + # @api private + def unreadable_io?(object) + return false unless IO === object + object.each {} # STDOUT is enumerable but raises an error + false + rescue IOError + true + end + module_function :surface_descriptions_in, :should_enumerate?, :unreadable_io? + + # Wraps an item in order to surface its `description` via `inspect`. + # @api private + DescribableItem = Struct.new(:item) do + # Inspectable version of the item description + def inspect + "(#{item.description})" + end + + # A pretty printed version of the item description. + def pretty_print(pp) + pp.text "(#{item.description})" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb new file mode 100644 index 0000000..4905dd8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb @@ -0,0 +1,546 @@ +RSpec::Support.require_rspec_support "with_keywords_when_needed" + +module RSpec + module Matchers + # Defines the custom matcher DSL. + module DSL + # Defines a matcher alias. The returned matcher's `description` will be overridden + # to reflect the phrasing of the new name, which will be used in failure messages + # when passed as an argument to another matcher in a composed matcher expression. + # + # @example + # RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to + # sum_to(3).description # => "sum to 3" + # a_list_that_sums_to(3).description # => "a list that sums to 3" + # + # @example + # RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description| + # description.sub("be sorted by", "a list sorted by") + # end + # + # be_sorted_by(:age).description # => "be sorted by age" + # a_list_sorted_by(:age).description # => "a list sorted by age" + # + # @param new_name [Symbol] the new name for the matcher + # @param old_name [Symbol] the original name for the matcher + # @param options [Hash] options for the aliased matcher + # @option options [Class] :klass the ruby class to use as the decorator. (Not normally used). + # @yield [String] optional block that, when given, is used to define the overridden + # logic. The yielded arg is the original description or failure message. If no + # block is provided, a default override is used based on the old and new names. + # @see RSpec::Matchers + def alias_matcher(new_name, old_name, options={}, &description_override) + description_override ||= lambda do |old_desc| + old_desc.gsub(EnglishPhrasing.split_words(old_name), EnglishPhrasing.split_words(new_name)) + end + klass = options.fetch(:klass) { AliasedMatcher } + + define_method(new_name) do |*args, &block| + matcher = __send__(old_name, *args, &block) + matcher.matcher_name = new_name if matcher.respond_to?(:matcher_name=) + klass.new(matcher, description_override) + end + ruby2_keywords new_name if respond_to?(:ruby2_keywords, true) + end + + # Defines a negated matcher. The returned matcher's `description` and `failure_message` + # will be overridden to reflect the phrasing of the new name, and the match logic will + # be based on the original matcher but negated. + # + # @example + # RSpec::Matchers.define_negated_matcher :exclude, :include + # include(1, 2).description # => "include 1 and 2" + # exclude(1, 2).description # => "exclude 1 and 2" + # + # @param negated_name [Symbol] the name for the negated matcher + # @param base_name [Symbol] the name of the original matcher that will be negated + # @yield [String] optional block that, when given, is used to define the overridden + # logic. The yielded arg is the original description or failure message. If no + # block is provided, a default override is used based on the old and new names. + # @see RSpec::Matchers + def define_negated_matcher(negated_name, base_name, &description_override) + alias_matcher(negated_name, base_name, :klass => AliasedNegatedMatcher, &description_override) + end + + # Defines a custom matcher. + # + # @param name [Symbol] the name for the matcher + # @yield [Object] block that is used to define the matcher. + # The block is evaluated in the context of your custom matcher class. + # When args are passed to your matcher, they will be yielded here, + # usually representing the expected value(s). + # @see RSpec::Matchers + def define(name, &declarations) + warn_about_block_args(name, declarations) + define_method name do |*expected, &block_arg| + RSpec::Matchers::DSL::Matcher.new(name, declarations, self, *expected, &block_arg) + end + end + alias_method :matcher, :define + + private + + if Proc.method_defined?(:parameters) + def warn_about_block_args(name, declarations) + declarations.parameters.each do |type, arg_name| + next unless type == :block + RSpec.warning("Your `#{name}` custom matcher receives a block argument (`#{arg_name}`), " \ + "but due to limitations in ruby, RSpec cannot provide the block. Instead, " \ + "use the `block_arg` method to access the block") + end + end + else + # :nocov: + def warn_about_block_args(*) + # There's no way to detect block params on 1.8 since the method reflection APIs don't expose it + end + # :nocov: + end + + RSpec.configure { |c| c.extend self } if RSpec.respond_to?(:configure) + + # Contains the methods that are available from within the + # `RSpec::Matchers.define` DSL for creating custom matchers. + module Macros + # Stores the block that is used to determine whether this matcher passes + # or fails. The block should return a boolean value. When the matcher is + # passed to `expect(...).to` and the block returns `true`, then the expectation + # passes. Similarly, when the matcher is passed to `expect(...).not_to` and the + # block returns `false`, then the expectation passes. + # + # @example + # + # RSpec::Matchers.define :be_even do + # match do |actual| + # actual.even? + # end + # end + # + # expect(4).to be_even # passes + # expect(3).not_to be_even # passes + # expect(3).to be_even # fails + # expect(4).not_to be_even # fails + # + # By default the match block will swallow expectation errors (e.g. + # caused by using an expectation such as `expect(1).to eq 2`), if you + # wish to allow these to bubble up, pass in the option + # `:notify_expectation_failures => true`. + # + # @param [Hash] options for defining the behavior of the match block. + # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`) + def match(options={}, &match_block) + define_user_override(:matches?, match_block) do |actual| + @actual = actual + RSpec::Support.with_failure_notifier(RAISE_NOTIFIER) do + begin + super(*actual_arg_for(match_block)) + rescue RSpec::Expectations::ExpectationNotMetError + raise if options[:notify_expectation_failures] + false + end + end + end + end + + # @private + RAISE_NOTIFIER = Proc.new { |err, _opts| raise err } + + # Use this to define the block for a negative expectation (`expect(...).not_to`) + # when the positive and negative forms require different handling. This + # is rarely necessary, but can be helpful, for example, when specifying + # asynchronous processes that require different timeouts. + # + # By default the match block will swallow expectation errors (e.g. + # caused by using an expectation such as `expect(1).to eq 2`), if you + # wish to allow these to bubble up, pass in the option + # `:notify_expectation_failures => true`. + # + # @param [Hash] options for defining the behavior of the match block. + # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`) + def match_when_negated(options={}, &match_block) + define_user_override(:does_not_match?, match_block) do |actual| + begin + @actual = actual + RSpec::Support.with_failure_notifier(RAISE_NOTIFIER) do + super(*actual_arg_for(match_block)) + end + rescue RSpec::Expectations::ExpectationNotMetError + raise if options[:notify_expectation_failures] + false + end + end + end + + # Use this instead of `match` when the block will raise an exception + # rather than returning false to indicate a failure. + # + # @example + # + # RSpec::Matchers.define :accept_as_valid do |candidate_address| + # match_unless_raises ValidationException do |validator| + # validator.validate(candidate_address) + # end + # end + # + # expect(email_validator).to accept_as_valid("person@company.com") + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def match_unless_raises(expected_exception=Exception, &match_block) + define_user_override(:matches?, match_block) do |actual| + @actual = actual + begin + super(*actual_arg_for(match_block)) + rescue expected_exception => @rescued_exception + false + else + true + end + end + end + + # Customizes the failure message to use when this matcher is + # asked to positively match. Only use this when the message + # generated by default doesn't suit your needs. + # + # @example + # + # RSpec::Matchers.define :have_strength do |expected| + # match { your_match_logic } + # + # failure_message do |actual| + # "Expected strength of #{expected}, but had #{actual.strength}" + # end + # end + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def failure_message(&definition) + define_user_override(__method__, definition) + end + + # Customize the failure message to use when this matcher is asked + # to negatively match. Only use this when the message generated by + # default doesn't suit your needs. + # + # @example + # + # RSpec::Matchers.define :have_strength do |expected| + # match { your_match_logic } + # + # failure_message_when_negated do |actual| + # "Expected not to have strength of #{expected}, but did" + # end + # end + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def failure_message_when_negated(&definition) + define_user_override(__method__, definition) + end + + # Customize the description to use for one-liners. Only use this when + # the description generated by default doesn't suit your needs. + # + # @example + # + # RSpec::Matchers.define :qualify_for do |expected| + # match { your_match_logic } + # + # description do + # "qualify for #{expected}" + # end + # end + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def description(&definition) + define_user_override(__method__, definition) + end + + # Tells the matcher to diff the actual and expected values in the failure + # message. + def diffable + define_method(:diffable?) { true } + end + + # Declares that the matcher can be used in a block expectation. + # Users will not be able to use your matcher in a block + # expectation without declaring this. + # (e.g. `expect { do_something }.to matcher`). + def supports_block_expectations + define_method(:supports_block_expectations?) { true } + end + + # Convenience for defining methods on this matcher to create a fluent + # interface. The trick about fluent interfaces is that each method must + # return self in order to chain methods together. `chain` handles that + # for you. If the method is invoked and the + # `include_chain_clauses_in_custom_matcher_descriptions` config option + # hash been enabled, the chained method name and args will be added to the + # default description and failure message. + # + # In the common case where you just want the chained method to store some + # value(s) for later use (e.g. in `match`), you can provide one or more + # attribute names instead of a block; the chained method will store its + # arguments in instance variables with those names, and the values will + # be exposed via getters. + # + # @example + # + # RSpec::Matchers.define :have_errors_on do |key| + # chain :with do |message| + # @message = message + # end + # + # match do |actual| + # actual.errors[key] == @message + # end + # end + # + # expect(minor).to have_errors_on(:age).with("Not old enough to participate") + def chain(method_name, *attr_names, &definition) + unless block_given? ^ attr_names.any? + raise ArgumentError, "You must pass either a block or some attribute names (but not both) to `chain`." + end + + definition = assign_attributes(attr_names) if attr_names.any? + + define_user_override(method_name, definition) do |*args, &block| + super(*args, &block) + @chained_method_clauses.push([method_name, args]) + self + end + end + + def assign_attributes(attr_names) + attr_reader(*attr_names) + private(*attr_names) + + lambda do |*attr_values| + attr_names.zip(attr_values) do |attr_name, attr_value| + instance_variable_set(:"@#{attr_name}", attr_value) + end + end + end + + # assign_attributes isn't defined in the private section below because + # that makes MRI 1.9.2 emit a warning about private attributes. + private :assign_attributes + + private + + # Does the following: + # + # - Defines the named method using a user-provided block + # in @user_method_defs, which is included as an ancestor + # in the singleton class in which we eval the `define` block. + # - Defines an overridden definition for the same method + # usign the provided `our_def` block. + # - Provides a default `our_def` block for the common case + # of needing to call the user's definition with `@actual` + # as an arg, but only if their block's arity can handle it. + # + # This compiles the user block into an actual method, allowing + # them to use normal method constructs like `return` + # (e.g. for an early guard statement), while allowing us to define + # an override that can provide the wrapped handling + # (e.g. assigning `@actual`, rescueing errors, etc) and + # can `super` to the user's definition. + def define_user_override(method_name, user_def, &our_def) + @user_method_defs.__send__(:define_method, method_name, &user_def) + our_def ||= lambda { super(*actual_arg_for(user_def)) } + define_method(method_name, &our_def) + end + + # Defines deprecated macro methods from RSpec 2 for backwards compatibility. + # @deprecated Use the methods from {Macros} instead. + module Deprecated + # @deprecated Use {Macros#match} instead. + def match_for_should(&definition) + RSpec.deprecate("`match_for_should`", :replacement => "`match`") + match(&definition) + end + + # @deprecated Use {Macros#match_when_negated} instead. + def match_for_should_not(&definition) + RSpec.deprecate("`match_for_should_not`", :replacement => "`match_when_negated`") + match_when_negated(&definition) + end + + # @deprecated Use {Macros#failure_message} instead. + def failure_message_for_should(&definition) + RSpec.deprecate("`failure_message_for_should`", :replacement => "`failure_message`") + failure_message(&definition) + end + + # @deprecated Use {Macros#failure_message_when_negated} instead. + def failure_message_for_should_not(&definition) + RSpec.deprecate("`failure_message_for_should_not`", :replacement => "`failure_message_when_negated`") + failure_message_when_negated(&definition) + end + end + end + + # Defines default implementations of the matcher + # protocol methods for custom matchers. You can + # override any of these using the {RSpec::Matchers::DSL::Macros Macros} methods + # from within an `RSpec::Matchers.define` block. + module DefaultImplementations + include BuiltIn::BaseMatcher::DefaultFailureMessages + + # @api private + # Used internally by objects returns by `should` and `should_not`. + def diffable? + false + end + + # The default description. + def description + english_name = EnglishPhrasing.split_words(name) + expected_list = EnglishPhrasing.list(expected) + "#{english_name}#{expected_list}#{chained_method_clause_sentences}" + end + + # Matchers do not support block expectations by default. You + # must opt-in. + def supports_block_expectations? + false + end + + def supports_value_expectations? + true + end + + # Most matchers do not expect call stack jumps. + def expects_call_stack_jump? + false + end + + private + + def chained_method_clause_sentences + return '' unless Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions? + + @chained_method_clauses.map do |(method_name, method_args)| + english_name = EnglishPhrasing.split_words(method_name) + arg_list = EnglishPhrasing.list(method_args) + " #{english_name}#{arg_list}" + end.join + end + end + + # The class used for custom matchers. The block passed to + # `RSpec::Matchers.define` will be evaluated in the context + # of the singleton class of an instance, and will have the + # {RSpec::Matchers::DSL::Macros Macros} methods available. + class Matcher + # Provides default implementations for the matcher protocol methods. + include DefaultImplementations + + # Allows expectation expressions to be used in the match block. + include RSpec::Matchers + + # Supports the matcher composability features of RSpec 3+. + include Composable + + # Makes the macro methods available to an `RSpec::Matchers.define` block. + extend Macros + extend Macros::Deprecated + + # Exposes the value being matched against -- generally the object + # object wrapped by `expect`. + attr_reader :actual + + # Exposes the exception raised during the matching by `match_unless_raises`. + # Could be useful to extract details for a failure message. + attr_reader :rescued_exception + + # The block parameter used in the expectation + attr_reader :block_arg + + # The name of the matcher. + attr_reader :name + + # @api private + def initialize(name, declarations, matcher_execution_context, *expected, &block_arg) + @name = name + @actual = nil + @expected_as_array = expected + @matcher_execution_context = matcher_execution_context + @chained_method_clauses = [] + @block_arg = block_arg + + klass = + class << self + # See `Macros#define_user_override` above, for an explanation. + include(@user_method_defs = Module.new) + self + end + RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *expected, &declarations) + end + + # Provides the expected value. This will return an array if + # multiple arguments were passed to the matcher; otherwise it + # will return a single value. + # @see #expected_as_array + def expected + if expected_as_array.size == 1 + expected_as_array[0] + else + expected_as_array + end + end + + # Returns the expected value as an an array. This exists primarily + # to aid in upgrading from RSpec 2.x, since in RSpec 2, `expected` + # always returned an array. + # @see #expected + attr_reader :expected_as_array + + # Adds the name (rather than a cryptic hex number) + # so we can identify an instance of + # the matcher in error messages (e.g. for `NoMethodError`) + def inspect + "#<#{self.class.name} #{name}>" + end + + if RUBY_VERSION.to_f >= 1.9 + # Indicates that this matcher responds to messages + # from the `@matcher_execution_context` as well. + # Also, supports getting a method object for such methods. + def respond_to_missing?(method, include_private=false) + super || @matcher_execution_context.respond_to?(method, include_private) + end + else # for 1.8.7 + # :nocov: + # Indicates that this matcher responds to messages + # from the `@matcher_execution_context` as well. + def respond_to?(method, include_private=false) + super || @matcher_execution_context.respond_to?(method, include_private) + end + # :nocov: + end + + private + + def actual_arg_for(block) + block.arity.zero? ? [] : [@actual] + end + + # Takes care of forwarding unhandled messages to the + # `@matcher_execution_context` (typically the current + # running `RSpec::Core::Example`). This is needed by + # rspec-rails so that it can define matchers that wrap + # Rails' test helper methods, but it's also a useful + # feature in its own right. + def method_missing(method, *args, &block) + if @matcher_execution_context.respond_to?(method) + @matcher_execution_context.__send__ method, *args, &block + else + super(method, *args, &block) + end + end + # The method_missing method should be refactored to pass kw args in RSpec 4 + # then this can be removed + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb new file mode 100644 index 0000000..05b69bd --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb @@ -0,0 +1,60 @@ +module RSpec + module Matchers + # Facilitates converting ruby objects to English phrases. + module EnglishPhrasing + # Converts a symbol into an English expression. + # + # split_words(:banana_creme_pie) #=> "banana creme pie" + # + def self.split_words(sym) + sym.to_s.tr('_', ' ') + end + + # @note The returned string has a leading space except + # when given an empty list. + # + # Converts an object (often a collection of objects) + # into an English list. + # + # list(['banana', 'kiwi', 'mango']) + # #=> " \"banana\", \"kiwi\", and \"mango\"" + # + # Given an empty collection, returns the empty string. + # + # list([]) #=> "" + # + def self.list(obj) + return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj || Hash === obj + items = Array(obj).map { |w| RSpec::Support::ObjectFormatter.format(w) } + case items.length + when 0 + "" + when 1 + " #{items[0]}" + when 2 + " #{items[0]} and #{items[1]}" + else + " #{items[0...-1].join(', ')}, and #{items[-1]}" + end + end + + if RUBY_VERSION == '1.8.7' + # Not sure why, but on travis on 1.8.7 we have gotten these warnings: + # lib/rspec/matchers/english_phrasing.rb:28: warning: default `to_a' will be obsolete + # So it appears that `Array` can trigger that (e.g. by calling `to_a` on the passed object?) + # So here we replace `Kernel#Array` with our own warning-free implementation for 1.8.7. + # @private + # rubocop:disable Naming/MethodName + # :nocov: + def self.Array(obj) + case obj + when Array then obj + else [obj] + end + end + # :nocov: + # rubocop:enable Naming/MethodName + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb new file mode 100644 index 0000000..bdd7cda --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb @@ -0,0 +1,42 @@ +require 'rspec/expectations' + +module RSpec + module Matchers + # Matchers for testing RSpec matchers. Include them with: + # + # require 'rspec/matchers/fail_matchers' + # RSpec.configure do |config| + # config.include RSpec::Matchers::FailMatchers + # end + # + module FailMatchers + # Matches if an expectation fails + # + # @example + # expect { some_expectation }.to fail + def fail(&block) + raise_error(RSpec::Expectations::ExpectationNotMetError, &block) + end + + # Matches if an expectation fails with the provided message + # + # @example + # expect { some_expectation }.to fail_with("some failure message") + # expect { some_expectation }.to fail_with(/some failure message/) + def fail_with(message) + raise_error(RSpec::Expectations::ExpectationNotMetError, message) + end + + # Matches if an expectation fails including the provided message + # + # @example + # expect { some_expectation }.to fail_including("portion of some failure message") + def fail_including(*snippets) + raise_error( + RSpec::Expectations::ExpectationNotMetError, + a_string_including(*snippets) + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb new file mode 100644 index 0000000..cbf3751 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb @@ -0,0 +1,41 @@ +module RSpec + module Matchers + class << self + # @private + attr_accessor :last_matcher, :last_expectation_handler + end + + # @api private + # Used by rspec-core to clear the state used to generate + # descriptions after an example. + def self.clear_generated_description + self.last_matcher = nil + self.last_expectation_handler = nil + end + + # @api private + # Generates an an example description based on the last expectation. + # Used by rspec-core's one-liner syntax. + def self.generated_description + return nil if last_expectation_handler.nil? + "#{last_expectation_handler.verb} #{last_description}" + end + + # @private + def self.last_description + last_matcher.respond_to?(:description) ? last_matcher.description : <<-MESSAGE +When you call a matcher in an example without a String, like this: + +specify { expect(object).to matcher } + +or this: + +it { is_expected.to matcher } + +RSpec expects the matcher to have a #description method. You should either +add a String to the example this matcher is being used in, or give it a +description method. Then you won't have to suffer this lengthy warning again. +MESSAGE + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb new file mode 100644 index 0000000..b957b4f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb @@ -0,0 +1,61 @@ +module RSpec + module Matchers + # Provides a base class with as little methods as possible, so that + # most methods can be delegated via `method_missing`. + # + # On Ruby 2.0+ BasicObject could be used for this purpose, but it + # introduce some extra complexity with constant resolution, so the + # BlankSlate pattern was prefered. + # @private + class BaseDelegator + kept_methods = [ + # Methods that raise warnings if removed. + :__id__, :__send__, :object_id, + + # Methods that are explicitly undefined in some subclasses. + :==, :===, + + # Methods we keep on purpose. + :class, :respond_to?, :__method__, :method, :dup, + :clone, :initialize_dup, :initialize_copy, :initialize_clone, + ] + instance_methods.each do |method| + unless kept_methods.include?(method.to_sym) + undef_method(method) + end + end + end + + # Provides the necessary plumbing to wrap a matcher with a decorator. + # @private + class MatcherDelegator < BaseDelegator + include Composable + attr_reader :base_matcher + + def initialize(base_matcher) + @base_matcher = base_matcher + end + + def method_missing(*args, &block) + base_matcher.__send__(*args, &block) + end + + if ::RUBY_VERSION.to_f > 1.8 + def respond_to_missing?(name, include_all=false) + super || base_matcher.respond_to?(name, include_all) + end + else + # :nocov: + def respond_to?(name, include_all=false) + super || base_matcher.respond_to?(name, include_all) + end + # :nocov: + end + + def initialize_copy(other) + @base_matcher = @base_matcher.clone + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb new file mode 100644 index 0000000..4a87f64 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb @@ -0,0 +1,105 @@ +module RSpec + module Matchers + # rspec-expectations can work with any matcher object that implements this protocol. + # + # @note This class is not loaded at runtime by rspec-expectations. It exists + # purely to provide documentation for the matcher protocol. + class MatcherProtocol + # @!group Required Methods + + # @!method matches?(actual) + # @param actual [Object] The object being matched against. + # @yield For an expression like `expect(x).to matcher do...end`, the `do/end` + # block binds to `to`. It passes that block, if there is one, on to this method. + # @return [Boolean] true if this matcher matches the provided object. + + # @!method failure_message + # This will only be called if {#matches?} returns false. + # @return [String] Explanation for the failure. + + # @!endgroup + + # @!group Optional Methods + + # @!method does_not_match?(actual) + # In a negative expectation such as `expect(x).not_to foo`, RSpec will + # call `foo.does_not_match?(x)` if this method is defined. If it's not + # defined it will fall back to using `!foo.matches?(x)`. This allows you + # to provide custom logic for the negative case. + # + # @param actual [Object] The object being matched against. + # @yield For an expression like `expect(x).not_to matcher do...end`, the `do/end` + # block binds to `not_to`. It passes that block, if there is one, on to this method. + # @return [Boolean] true if this matcher does not match the provided object. + + # @!method failure_message_when_negated + # This will only be called when a negative match fails. + # @return [String] Explanation for the failure. + # @note This method is listed as optional because matchers do not have to + # support negation. But if your matcher does support negation, this is a + # required method -- otherwise, you'll get a `NoMethodError`. + + # @!method description + # The description is used for two things: + # + # * When using RSpec's one-liner syntax + # (e.g. `it { is_expected.to matcher }`), the description + # is used to generate the example's doc string since you + # have not provided one. + # * In a composed matcher expression, the description is used + # as part of the failure message (and description) of the outer + # matcher. + # + # @return [String] Description of the matcher. + + # @!method supports_block_expectations? + # Indicates that this matcher can be used in a block expectation expression, + # such as `expect { foo }.to raise_error`. Generally speaking, this is + # only needed for matchers which operate on a side effect of a block, rather + # than on a particular object. + # @return [Boolean] true if this matcher can be used in block expressions. + # @note If not defined, RSpec assumes a value of `false` for this method. + + # @!method supports_value_expectations? + # Indicates that this matcher can be used in a value expectation expression, + # such as `expect(foo).to eq(bar)`. + # @return [Boolean] true if this matcher can be used in value expressions. + # @note If not defined, RSpec assumes a value of `true` for this method. + + # @!method expects_call_stack_jump? + # Indicates that when this matcher is used in a block expectation + # expression, it expects the block to use a ruby construct that causes + # a call stack jump (such as raising an error or throwing a symbol). + # + # This is used internally for compound block expressions, as matchers + # which expect call stack jumps must be treated with care to work properly. + # + # @return [Boolean] true if the matcher expects a call stack jump + # + # @note This method is very rarely used or needed. + # @note If not defined, RSpec assumes a value of `false` for this method. + + # @!method diffable? + # @return [Boolean] true if `actual` and `expected` can be diffed. + # Indicates that this matcher provides `actual` and `expected` attributes, + # and that the values returned by these can be usefully diffed, which can + # be included in the output. + + # @!method actual + # @return [String, Object] If an object (rather than a string) is provided, + # RSpec will use the `pp` library to convert it to multi-line output in + # order to diff. + # The actual value for the purposes of a diff. + # @note This method is required if `diffable?` returns true. + + # @!method expected + # @return [String, Object] If an object (rather than a string) is provided, + # RSpec will use the `pp` library to convert it to multi-line output in + # order to diff. + # The expected value for the purposes of a diff. + # @note This method is required if `diffable?` returns true. + + # @!endgroup + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb new file mode 100644 index 0000000..cd2264e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb @@ -0,0 +1,82 @@ +module RSpec + module Matchers + # @api private + # Handles list of expected and actual value pairs when there is a need + # to render multiple diffs. Also can handle one pair. + class MultiMatcherDiff + # @private + # Default diff label when there is only one matcher in diff + # output + DEFAULT_DIFF_LABEL = "Diff:".freeze + + # @private + # Maximum readable matcher description length + DESCRIPTION_MAX_LENGTH = 65 + + def initialize(expected_list) + @expected_list = expected_list + end + + # @api private + # Wraps provided expected value in instance of + # MultiMatcherDiff. If provided value is already an + # MultiMatcherDiff then it just returns it. + # @param [Any] expected value to be wrapped + # @param [Any] actual value + # @return [RSpec::Matchers::MultiMatcherDiff] + def self.from(expected, actual) + return expected if self === expected + new([[expected, DEFAULT_DIFF_LABEL, actual]]) + end + + # @api private + # Wraps provided matcher list in instance of + # MultiMatcherDiff. + # @param [Array] matchers list of matchers to wrap + # @return [RSpec::Matchers::MultiMatcherDiff] + def self.for_many_matchers(matchers) + new(matchers.map { |m| [m.expected, diff_label_for(m), m.actual] }) + end + + # @api private + # Returns message with diff(s) appended for provided differ + # factory and actual value if there are any + # @param [String] message original failure message + # @param [Proc] differ + # @return [String] + def message_with_diff(message, differ) + diff = diffs(differ) + message = "#{message}\n#{diff}" unless diff.empty? + message + end + + private + + class << self + private + + def diff_label_for(matcher) + "Diff for (#{truncated(RSpec::Support::ObjectFormatter.format(matcher))}):" + end + + def truncated(description) + return description if description.length <= DESCRIPTION_MAX_LENGTH + description[0...DESCRIPTION_MAX_LENGTH - 3] << "..." + end + end + + def diffs(differ) + @expected_list.map do |(expected, diff_label, actual)| + diff = differ.diff(actual, expected) + next if diff.strip.empty? + if diff == "\e[0m\n\e[0m" + "#{diff_label}\n" \ + " " + else + "#{diff_label}#{diff}" + end + end.compact.join("\n") + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document new file mode 100644 index 0000000..52a564f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +- +README.md +LICENSE.md +Changelog.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts new file mode 100644 index 0000000..9555b8e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts @@ -0,0 +1,6 @@ +--exclude features +--no-private +--markup markdown +- +Changelog.md +LICENSE.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md new file mode 100644 index 0000000..3925a20 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md @@ -0,0 +1,1343 @@ +### Development +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.7...3-13-maintenance) + +### 3.13.7 / 2025-10-31 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.6...rspec-mocks-v3.13.7) + +Bug Fixes: + +* Special case `to_h`, `to_hash` responses on null objects, prevents an issue with Rails. (Jon Rowe, rspec/rspec#275) + +### 3.13.6 / 2025-10-14 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.5...rspec-mocks-v3.13.6) + +Bug Fixes: + +* Work around possible infinite loop when stubbing `is_a?`. (Erin Paget, rspec/rspec#265) + +### 3.13.5 / 2025-05-27 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.4...rspec-mocks-v3.13.5) + +Bug Fixes: + +* Fix regression where a previous fix (rspec/rspec#214) would leave behind thread data + between tests. (Jon Rowe, rspec/rspec#219) +* Fix links in gemspec to point to monorepo / homepage. (Jon Rowe) + +### 3.13.4 / 2025-05-05 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.3...rspec-mocks-v3.13.4) + +Bug Fixes: + +* Fix regression where nested stubbed method calls would inadvertently not be counted. + (Jon Rowe, rspec/rspec#214) +* Fix regression where keyword arguments would not be passed through to nested stubbed + method calls. (Jon Rowe, rspec/rspec#214) + +### 3.13.3 / 2025-05-01 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.2...rspec-mocks-v3.13.3) + +Bug Fixes: + +* When stubbing methods using the `expect_any_instance_of` or `allow_any_instance_of` + ensure the stubbed method has the same visibility as the real method. + (Jon Rowe, rspec/rspec-mocks#1596) +* Prevent recursive calls to stubbed methods during stub invocation. + (James Dabbs, rspec/rspec#116, rspec/rspec#156) + +### 3.13.2 / 2024-10-02 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.13.1...v3.13.2) + +Bug Fixes: + +* Support keyword arguments in callables passed to `and_invoke`. (Jon Rowe, rspec/rspec-mocks#1595) + +### 3.13.1 / 2024-05-08 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.13.0...v3.13.1) + +Bug Fixes: + +* Use `RSpec::Support::Mutex` in `RSpec::Mocks::Proxy` to avoid issues from + stubbing `::Mutex#new`. (Eric Mueller, rspec/rspec-mocks#1575) + +### 3.13.0 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.7...v3.13.0) + +Enhancements: + +* Add an `array_excluding` matcher for arguments. (Zane Wolfgang Pickett, rspec/rspec-mocks#1528) + +### 3.12.7 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.6...v3.12.7) + +Bug Fixes: + +* Reduce allocations from "any_instance" style mocks. (Carlos Palhares, rspec/rspec-mocks#1479) + +### 3.12.6 / 2023-07-11 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.5...v3.12.6) + +Bug Fixes: + +* Fix an issue with `and_call_original` when using the `method_missing` fallback + with keyword arguments. (Igor Drozdov, rspec/rspec-mocks#1552) + +### 3.12.5 / 2023-03-30 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.4...v3.12.5) + +Bug Fixes: + +* Fix compatibility issue with Rails where active_support monkey patches `with` + when using any instance. (Lachlan Sylvester, rspec/rspec-mocks#1540) + +### 3.12.4 / 2023-03-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.3...v3.12.4) + +Bug Fixes: + +* Fix an issue with asserting that Array#reverse is never called. (Brad Trick, rspec/rspec-mocks#1533) +* Fix compatibility issue with Rails where active_support monkey patches `with`. + (Jean Boussier, rspec/rspec-mocks#1531, rspec/rspec-mocks#1534) + +### 3.12.3 / 2023-01-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.2...v3.12.3) + +Bug Fixes: + +* Fix keyword delegation in `send` for verifying doubles on Ruby 3. + (Charlie Honig, rspec/rspec-mocks#1485) + +### 3.12.2 / 2023-01-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.1...v3.12.2) + +Bug Fixes: + +* Fix implementation blocks for mocks using keyword arguments on Ruby 3.2.0. + (Adam Steel, rspec/rspec-mocks#1508) +* Fix keyword argument assertions when mocking using `with` on Ruby 3.2.0. + (Slava Kardakov, Benoit Tigeot, Phil Pirozhkov, Benoit Daloze, rspec/rspec-mocks#1514) + +### 3.12.1 / 2022-12-10 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.0...v3.12.1) + +Bug Fixes: + +* Remove empty diff marker when a diff only contains console codes. (Jon Rowe, rspec/rspec-mocks#1506) +* Show keyword vs hash diff marker when arguments are not `==` (Jon Rowe, rspec/rspec-mocks#1506) +* Change check to detect frozen objects to rescue errors rather than + pre-empting by checking `frozen?` due to some objects mis-behaving. + (Keegan Roth, rspec/rspec-mocks#1401) +* Prevent unfulfilled expectations using `expect_any_instance_of` across a class + inheritance boundary from raising rather than failing. (Jon Rowe, rspec/rspec-mocks#1496) +* Prevent a misleading error message when using `allow(...).not_to` with + unsupported matchers. (Phil Pirozhkov, rspec/rspec-mocks#1503) + +### 3.12.0 / 2022-10-26 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.2...v3.12.0) + +Enhancements: + +* Improve diff output when diffing keyword arguments against hashes. + (Jean Boussier, rspec/rspec-mocks#1461) + +### 3.11.2 / 2022-10-25 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.1...v3.11.2) + +Bug Fixes: + +* Use the original implementation of `Class.new` to detect overridden definitions + of `new` rather than the owner, fixing detection of "double aliased" methods + in Ruby 3 and above. (Benoit Daloze, rspec/rspec-mocks#1470, rspec/rspec-mocks#1476) +* Support keyword argument semantics when constraining argument expectations using + `with` on Ruby 3.0+ with `instance_double` (Andrii Malyshko, rspec/rspec-mocks#1473) + +### 3.11.1 / 2022-03-31 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.0...v3.11.1) + +Bug Fixes: + +* Add extra `ruby2_keywords` calls to properly designate methods using + `*args` to pass keyword around, fixes an issue with TruffleRuby. + (Benoit Daloze, rspec/rspec-mocks#1464) + +### 3.11.0 / 2022-02-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.3...v3.11.0) + +Enhancements: + +* Add `and_invoke` implementation for configuring responses to `receive` + (and `receive_messages`) with multiple callable objects. (Kyle Smith, rspec/rspec-mocks#1411) + +### 3.10.3 / 2022-01-28 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.2...v3.10.3) + +Bug Fixes: + +* Suppress warning by setting `$VERBOSE` to nil. (Nobuyoshi Nakada, rspec/rspec-mocks#1414) +* Support keyword argument semantics when constraining argument expectations using + `with` on Ruby 3.0+ (Yusuke Endoh, rspec/rspec-mocks#1394) + +### 3.10.2 / 2021-01-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.1...v3.10.2) + +Bug Fixes: + +* Support keyword arguments with `and_call_original` on Ruby 3.0. + (Bryan Powell, rspec/rspec-mocks#1385) +* `RSpec::Mocks::Constant#previously_defined?` is now always a boolean. + (Phil Pirozhkov, rspec/rspec-mocks#1397) +* Support keyword arguments on Ruby 3.0 when used with `expect_any_instance_of` + or `allow_any_instance_of` with `and_call_original`. + (Jess Hottenstein, rspec/rspec-mocks#1407) + +### 3.10.1 / 2020-12-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.0...v3.10.1) + +Bug Fixes: + +* Issue `ArgumentError` rather than `TypeError` when unsupported methods on + unsupported objects are attempted to be stubbed. (@zhisme, rspec/rspec-mocks#1357) + +### 3.10.0 / 2020-10-30 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.1...v3.10.0) + +Enhancements: +* Add the ability to set a custom error generator in `MessageExpectation`. + This will allow rspec-expectations to inject a custom failure message. + (Benoit Tigeot and Nicolas Zermati, rspec/rspec-mocks#1312) +* Return the result of the block passed to `RSpec::Mocks.with_temporary_scope` + when block run. (@expeehaa, rspec/rspec-mocks#1329) + +### 3.9.1 / 2019-12-31 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.0...v3.9.1) + +Bug Fixes: + +* Trigger `RSpec::Mocks.configuration.verifying_double_callbacks` when using + `allow_any_instance_of` or `expect_any_instance_of` (Daniel Orner, rspec/rspec-mocks#1309) + +### 3.9.0 / 2019-10-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.2...v3.9.0) + +Enhancements: + +* Improve thread safety of message expectations by using Mutex to prevent + deadlocking errors. (Ry Biesemeyer, rspec/rspec-mocks#1236) +* Add the ability to use `time` as an alias for `times`. For example: + `expect(Class).to receive(:method).exactly(1).time`. + (Pistos, Benoit Tigeot, rspec/rspec-mocks#1271) + +### 3.8.2 / 2019-10-02 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.1...v3.8.2) + +* Allow `array_including` argument matchers to be nested. + (Emmanuel Delmas, rspec/rspec-mocks#1291) + +### 3.8.1 / 2019-06-13 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.0...v3.8.1) + +Bug Fixes: + +* Ensure stubbing methods does not change their visibility. + (Kevin Boschert, rspec/rspec-mocks#1277) + +### 3.8.0 / 2018-08-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.7.0...v3.8.0) + +Bug Fixes: + +* Issue error when encountering invalid "counted" negative message expectations. + (Sergiy Yarinovskiy, rspec/rspec-mocks#1212) +* Ensure `allow_any_instance_of` and `expect_any_instance_of` can be temporarily + supressed. (Jon Rowe, rspec/rspec-mocks#1228) +* Ensure `expect_any_instance_of(double).to_not have_received(:some_method)` + fails gracefully (as its not supported) rather than issuing a `NoMethodError`. + (Maxim Krizhanovsky, rspec/rspec-mocks#1231) + +### 3.7.0 / 2017-10-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0...v3.7.0) + +Enhancements: + +* Improve compatibility with `--enable-frozen-string-literal` option + on Ruby 2.3+. (Pat Allan, rspec/rspec-mocks#1165) + +Bug Fixes: + +* Fix `hash_including` and `hash_excluding` so that they work against + subclasses of `Hash`. (Aaron Rosenberg, rspec/rspec-mocks#1167) + +### 3.6.0 / 2017-05-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0.beta2...v3.6.0) + +Bug Fixes: + +* Fix "instance variable @color not initialized" warning when using + rspec-mocks without rspec-core. (Myron Marston, rspec/rspec-mocks#1142) +* Restore aliased module methods properly when stubbing on 1.8.7. + (Samuel Giddins, rspec/rspec-mocks#1144) +* Allow a message chain expectation to be constrained by argument(s). + (Jon Rowe, rspec/rspec-mocks#1156) + +### 3.6.0.beta2 / 2016-12-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0.beta1...v3.6.0.beta2) + +Enhancements: + +* Add new `without_partial_double_verification { }` API that lets you + temporarily turn off partial double verification for an example. + (Jon Rowe, rspec/rspec-mocks#1104) + +### 3.6.0.beta1 / 2016-10-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0...v3.6.0.beta1) + +Bug Fixes: + +* Return the test double instance form `#freeze` (Alessandro Berardi, rspec/rspec-mocks#1109) +* Allow the special logic for stubbing `new` to work when `.method` has + been redefined. (Proby, rspec/rspec-mocks#1119) + +### 3.5.0 / 2016-07-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta4...v3.5.0) + +Enhancements: + +* Provides a nice string representation of + `RSpec::Mocks::MessageExpectation` (Myron Marston, rspec/rspec-mocks#1095) + +### 3.5.0.beta4 / 2016-06-05 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta3...v3.5.0.beta4) + +Enhancements: + +* Add `and_throw` to any instance handling. (Tobias Bühlmann, rspec/rspec-mocks#1068) + +### 3.5.0.beta3 / 2016-04-02 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta2...v3.5.0.beta3) + +Enhancements: + +* Issue warning when attempting to use unsupported + `allow(...).to receive(...).ordered`. (Jon Rowe, rspec/rspec-mocks#1000) +* Add `rspec/mocks/minitest_integration`, to properly integrate rspec-mocks + with minitest. (Myron Marston, rspec/rspec-mocks#1065) + +### 3.5.0.beta2 / 2016-03-10 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta1...v3.5.0.beta2) + +Enhancements: + +* Improve error message displayed when using `and_wrap_original` on pure test + doubles. (betesh, rspec/rspec-mocks#1063) + +Bug Fixes: + +* Fix issue that prevented `receive_message_chain(...).with(...)` working + correctly on "any instance" mocks. (Jon Rowe, rspec/rspec-mocks#1061) + +### 3.5.0.beta1 / 2016-02-06 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.4.1...v3.5.0.beta1) + +Bug Fixes: + +* Allow `any_instance_of(...).to receive(...)` to use `and_yield` multiple + times. (Kilian Cirera Sant, rspec/rspec-mocks#1054) +* Allow matchers which inherit from `rspec-mocks` matchers to be used for + `allow`. (Andrew Kozin, rspec/rspec-mocks#1056) +* Prevent stubbing `respond_to?` on partial doubles from causing infinite + recursion. (Jon Rowe, rspec/rspec-mocks#1013) +* Prevent aliased methods from disapearing after being mocked with + `any_instance` (regression from rspec/rspec-mocks#1043). (Joe Rafaniello, rspec/rspec-mocks#1060) + +### 3.4.1 / 2016-01-10 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.4.0...v3.4.1) + +Bug Fixes: + +* Fix `any_instance` to work properly on Ruby 2.3. (Joe Rafaniello, rspec/rspec-mocks#1043) + +### 3.4.0 / 2015-11-11 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.2...v3.4.0) + +Enhancements: + +* Make `expect(...).to have_received` work without relying upon + rspec-expectations. (Myron Marston, rspec/rspec-mocks#978) +* Add option for failing tests when expectations are set on `nil`. + (Liz Rush, rspec/rspec-mocks#983) + +Bug Fixes: + +* Fix `have_received { ... }` so that any block passed when the message + was received is forwarded to the `have_received` block. (Myron Marston, rspec/rspec-mocks#1006) +* Fix infinite loop in error generator when stubbing `respond_to?`. + (Alex Dowad, rspec/rspec-mocks#1022) +* Fix issue with using `receive` on subclasses (at a class level) with 1.8.7. + (Alex Dowad, rspec/rspec-mocks#1026) + +### 3.3.2 / 2015-07-15 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.1...v3.3.2) + +Bug Fixes: + +* Prevent thread deadlock errors during proxy creation (e.g. when using + `before_verifying_doubles` callbacks). (Jon Rowe, rspec/rspec-mocks#980, rspec/rspec-mocks#979) + +### 3.3.1 / 2015-06-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.0...v3.3.1) + +Bug Fixes: + +* Fix bug in `before_verifying_double` callback logic that caused it to be called + once for each class in the ancestor list when mocking or stubbing a class. Now + it is only called for the mocked or stubbed class, as you would expect. (Sam + Phippen, rspec/rspec-mocks#974) + +### 3.3.0 / 2015-06-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.2.1...v3.3.0) + +Enhancements: + +* When stubbing `new` on `MyClass` or `class_double(MyClass)`, use the + method signature from `MyClass#initialize` to verify arguments. + (Myron Marston, rspec/rspec-mocks#886) +* Use matcher descriptions when generating description of received arguments + for mock expectation failures. (Tim Wade, rspec/rspec-mocks#891) +* Avoid loading `stringio` unnecessarily. (Myron Marston, rspec/rspec-mocks#894) +* Verifying doubles failure messages now distinguish between class and instance + level methods. (Tim Wade, rspec/rspec-mocks#896, rspec/rspec-mocks#908) +* Improve mock expectation failure messages so that it combines both + number of times and the received arguments in the output. (John Ceh, rspec/rspec-mocks#918) +* Improve how test doubles are represented in failure messages. + (Siva Gollapalli, Myron Marston, rspec/rspec-mocks#932) +* Rename `RSpec::Mocks::Configuration#when_declaring_verifying_double` to + `RSpec::Mocks::Configuration#before_verifying_doubles` and utilise when + verifying partial doubles. (Jon Rowe, rspec/rspec-mocks#940) +* Use rspec-support's `ObjectFormatter` for improved formatting of + arguments in failure messages so that, for example, full time + precisions is displayed for time objects. (Gavin Miller, Myron Marston, rspec/rspec-mocks#955) + +Bug Fixes: + +* Ensure expectations that raise eagerly also raise during RSpec verification. + This means that if exceptions are caught inside test execution the test will + still fail. (Sam Phippen, rspec/rspec-mocks#884) +* Fix `have_received(msg).with(args).exactly(n).times` and + `receive(msg).with(args).exactly(n).times` failure messages + for when the message was received the wrong number of times with + the specified args, and also received additional times with other + arguments. Previously it confusingly listed the arguments as being + mis-matched (even when the double was allowed to receive with any + args) rather than listing the count. (John Ceh, rspec/rspec-mocks#918) +* Fix `any_args`/`anything` support so that we avoid calling `obj == anything` + on user objects that may have improperly implemented `==` in a way that + raises errors. (Myron Marston, rspec/rspec-mocks#924) +* Fix edge case involving stubbing the same method on a class and a subclass + which previously hit a `NoMethodError` internally in RSpec. (Myron Marston rspec/rspec-mocks#954) +* Fix edge case where the message received count would be incremented multiple + times for one failure. (Myron Marston, rspec/rspec-mocks#957) +* Fix failure messages for when spies received the expected message with + different arguments and also received another message. (Maurício Linhares, rspec/rspec-mocks#960) +* Silence whitespace-only diffs. (Myron Marston, rspec/rspec-mocks#969) + +### 3.2.1 / 2015-02-23 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.2.0...v3.2.1) + +Bug Fixes: + +* Add missing `rspec/support/differ` require so that rspec-mocks can be + used w/o rspec-expectations (which also loads the differ and hided the + fact we forgot to require it). (Myron Marston, rspec/rspec-mocks#893) +* Revert tracking of received arg mutation (added in 3.2.0 to provide an + error in a situation we can't support) as our implementation has side + effects on non-standard objects and there's no solution we could come + up with that always works. (Myron Marston, rspec/rspec-mocks#900) + +### 3.2.0 / 2015-02-03 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.3...v3.2.0) + +Enhancements: + +* Treat `any_args` as an arg splat, allowing it to match an arbitrary + number of args at any point in an arg list. (Myron Marston, rspec/rspec-mocks#786) +* Print diffs when arguments in mock expectations are mismatched. + (Sam Phippen, rspec/rspec-mocks#751) +* Support names for verified doubles (`instance_double`, `instance_spy`, + `class_double`, `class_spy`, `object_double`, `object_spy`). (Cezary + Baginski, rspec/rspec-mocks#826) +* Make `array_including` and `hash_including` argument matchers composable. + (Sam Phippen, rspec/rspec-mocks#819) +* Make `allow_any_instance_of(...).to receive(...).and_wrap_original` + work. (Ryan Fitzgerald, rspec/rspec-mocks#869) + +Bug Fixes: + +* Provide a clear error when users wrongly combine `no_args` with + additional arguments (e.g. `expect().to receive().with(no_args, 1)`). + (Myron Marston, rspec/rspec-mocks#786) +* Provide a clear error when users wrongly use `any_args` multiple times in the + same argument list (e.g. `expect().to receive().with(any_args, 1, any_args)`. + (Myron Marston, rspec/rspec-mocks#786) +* Prevent the error generator from using user object #description methods. + See [rspec/rspec-mocks#685](https://github.com/rspec/rspec-mocks/issues/685). + (Sam Phippen, rspec/rspec-mocks#751) +* Make verified doubles declared as `(instance|class)_double(SomeConst)` + work properly when `SomeConst` has previously been stubbed. + `(instance|class)_double("SomeClass")` already worked properly. + (Myron Marston, rspec/rspec-mocks#824) +* Add a matcher description for `receive`, `receive_messages` and + `receive_message_chain`. (Myron Marston, rspec/rspec-mocks#828) +* Validate invocation args for null object verified doubles. + (Myron Marston, rspec/rspec-mocks#829) +* Fix `RSpec::Mocks::Constant.original` when called with an invalid + constant to return an object indicating the constant name is invalid, + rather than blowing up. (Myron Marston, rspec/rspec-mocks#833) +* Make `extend RSpec::Mocks::ExampleMethods` on any object work properly + to add the rspec-mocks API to that object. Previously, `expect` would + be undefined. (Myron Marston, rspec/rspec-mocks#846) +* Fix `require 'rspec/mocks/standalone'` so that it only affects `main` + and not every object. It's really only intended to be used in a REPL + like IRB, but some gems have loaded it, thinking it needs to be loaded + when using rspec-mocks outside the context of rspec-core. + (Myron Marston, rspec/rspec-mocks#846) +* Prevent message expectations from being modified by customization methods + (e.g. `with`) after they have been invoked. (Sam Phippen and Melanie Gilman, rspec/rspec-mocks#837) +* Handle cases where a method stub cannot be removed due to something + external to RSpec monkeying with the method definition. This can + happen, for example, when you `file.reopen(io)` after previously + stubbing a method on the `file` object. (Myron Marston, rspec/rspec-mocks#853) +* Provide a clear error when received message args are mutated before + a `have_received(...).with(...)` expectation. (Myron Marston, rspec/rspec-mocks#868) + +### 3.1.3 / 2014-10-08 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.2...v3.1.3) + +Bug Fixes: + +* Correct received messages count when used with `have_received` matcher. + (Jon Rowe, rspec/rspec-mocks#793) +* Provide a clear error message when you use `allow_any_instance_of(...)` or + `expect_any_instance_of(...)` with the `have_received` matcher (they are + not intended to be used together and previously caused an odd internal + failure in rspec-mocks). (Jon Rowe, rspec/rspec-mocks#799). +* Fix verified double `with` verification so that it applies to method + stubs. (Myron Marston, rspec/rspec-mocks#790) + +### 3.1.2 / 2014-09-26 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.1...v3.1.2) + +Bug Fixes: + +* Provide a clear error message when you use `allow(...)` with the + `have_received` matcher (they are not intended to be used together + and previously caused an odd internal failure in rspec-mocks). (Jon Rowe, rspec/rspec-mocks#788). + +### 3.1.1 / 2014-09-18 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.0...v3.1.1) + +Bug Fixes: + +* Prevent included modules being detected as prepended modules on Ruby 2.0 + when using `any_instance_of(...)`. (Tony Novak, rspec/rspec-mocks#781) + +### 3.1.0 / 2014-09-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.4...v3.1.0) + +Enhancements: + +* Add spying methods (`spy`, `ìnstance_spy`, `class_spy` and `object_spy`) + which create doubles as null objects for use with spying in testing. (Sam + Phippen, rspec/rspec-mocks#671) +* `have_received` matcher will raise "does not implement" errors correctly when + used with verifying doubles and partial doubles. (Xavier Shay, rspec/rspec-mocks#722) +* Allow matchers to be used in place of keyword arguments in `with` + expectations. (Xavier Shay, rspec/rspec-mocks#726) +* Add `thrice` modifier to message expectation interface as a synonym + for `exactly(3).times`. (Dennis Taylor, rspec/rspec-mocks#753) +* Add more `thrice` synonyms e.g. `.at_least(:thrice)`, `.at_most(:thrice)`, + `receive(...).thrice` and `have_received(...).thrice`. (Jon Rowe, rspec/rspec-mocks#754) +* Add `and_wrap_original` modifier for partial doubles to mutate the + response from a method. (Jon Rowe, rspec/rspec-mocks#762) + +Bug Fixes: + +* Remove `any_number_of_times` from `any_instance` recorders that were + erroneously causing mention of the method in documentation. (Jon Rowe, rspec/rspec-mocks#760) +* Prevent included modules being detected as prepended modules on Ruby 2.0. + (Eugene Kenny, rspec/rspec-mocks#771) + +### 3.0.4 / 2014-08-14 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.3...v3.0.4) + +Bug Fixes: + +* Restore `kind_of(x)` to match using `arg.kind_of?(x)` (like RSpec 2) + rather than `x === arg`. (Jon Rowe, rspec/rspec-mocks#750) + +### 3.0.3 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.2...v3.0.3) + +Bug Fixes: + +* `have_received` matcher will raise "does not implement" errors correctly when + used with verifying doubles and partial doubles. (Xavier Shay, rspec/rspec-mocks#722) +* Make `double.as_null_object.dup` and `double.as_null_object.clone` + make the copies be null objects. (Myron Marston, rspec/rspec-mocks#732) +* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, rspec/rspec-mocks#739) + +### 3.0.2 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.1...v3.0.2) + +Bug Fixes: + +* Fix edge case that triggered "can't add a new key into hash during + iteration" during mock verification. (Sam Phippen, Myron Marston, rspec/rspec-mocks#711) +* Fix verifying doubles so that when they accidentally leak into another + example, they provide the same clear error message that normal doubles + do. (Myron Marston, rspec/rspec-mocks#718) +* Make `ordered` work with exact receive counts. (Sam Phippen, rspec/rspec-mocks#713) + +### 3.0.1 / 2014-06-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0...v3.0.1) + +Bug Fixes: + +* Fix `receive_message_chain(...)` so that it supports `with` just like + `stub_chain` did. (Jon Rowe, rspec/rspec-mocks#697) +* Fix regression in `expect_any_instance_of` so that it expects the + message on _any_ instance rather than on _every_ instance. + (Myron Marston, rspec/rspec-mocks#699) + +### 3.0.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.rc1...v3.0.0) + +Bug Fixes: + +* Fix module prepend detection to work properly on ruby 2.0 for a case + where a module is extended onto itself. (Myron Marston) +* Fix `transfer_nested_constants` option so that transferred constants + get properly reset at the end of the example. (Myron Marston) +* Fix `config.transfer_nested_constants = true` so that you don't + erroneously get errors when stubbing a constant that is not a module + or a class. (Myron Marston) +* Fix regression that caused `double(:class => SomeClass)` to later + trigger infinite recursion. (Myron Marston) +* Fix bug in `have_received(...).with(...).ordered` where it was not + taking the args into account when checking the order. (Myron Marston) +* Fix bug in `have_received(...).ordered` where it was wrongly + considering stubs when checking the order. (Myron Marston) +* Message expectation matchers now show descriptions from argument + matchers when their expectations aren't met. (Jon Rowe) +* Display warning when encountering `TypeError` during instance method + staging on 2.0.0-p195, suffers from https://bugs.ruby-lang.org/issues/8686 + too. (Cezar Halmagean). + +### 3.0.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta2...v3.0.0.rc1) + +Breaking Changes for 3.0.0: + +* Remove `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston) +* Remove `RSpec::Mocks::ConstantStubber`. (Jon Rowe) +* Make monkey-patch of Marshal to support dumping of stubbed objects opt-in. + (Xavier Shay) + +Enhancements: + +* Instead of crashing when cleaning up stub methods on a frozen object, it now + issues a warning explaining that it's impossible to clean up the stubs. + (Justin Coyne and Sam Phippen) +* Add meaningful descriptions to `anything`, `duck_type` and `instance_of` argument + matchers. (Jon Rowe) + +Bug Fixes: + +* Fix regression introduced in 3.0.0.beta2 that caused + `double.as_null_object.to_str` to return the double rather + than a string. (Myron Marston) +* Fix bug in `expect(dbl).to receive_message_chain(:foo, :bar)` where it was + not setting an expectation for the last message in the chain. + (Jonathan del Strother) +* Allow verifying partial doubles to have private methods stubbed. (Xavier Shay) +* Fix bug with allowing/expecting messages on Class objects which have had + their singleton class prepended to. (Jon Rowe) +* Fix an issue with 1.8.7 not running implementation blocks on partial doubles. + (Maurício Linhares) +* Prevent `StackLevelTooDeep` errors when stubbing an `any_instance` method that's + accessed in `inspect` by providing our own inspect output. (Jon Rowe) +* Fix bug in `any_instance` logic that did not allow you to mock or stub + private methods if `verify_partial_doubles` was configured. (Oren Dobzinski) +* Include useful error message when trying to observe an unimplemented method + on an any instance. (Xavier Shay) +* Fix `and_call_original` to work properly when multiple classes in an + inheritance hierarchy have been stubbed with the same method. (Myron Marston) +* Fix `any_instance` so that it updates existing instances that have + already been stubbed. (Myron Marston) +* Fix verified doubles so that their class name is included in failure + messages. (Myron Marston) +* Fix `expect_any_instance_of` so that when the message is received + on an individual instance that has been directly stubbed, it still + satisfies the expectation. (Sam Phippen, Myron Marston) +* Explicitly disallow using `any_instance` to mock or stub a method + that is defined on a module prepended onto the class. This triggered + `SystemStackError` before and is very hard to support so we are not + supporting it at this time. (Myron Marston) + +### 3.0.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta1...v3.0.0.beta2) + +Breaking Changes for 3.0.0: + +* Rename `RSpec::Mocks::Mock` to `RSpec::Mocks::Double`. (Myron Marston) +* Change how to integrate rspec-mocks in other test frameworks. You now + need to include `RSpec::Mocks::ExampleMethods` in your test context. + (Myron Marston) +* Prevent RSpec mocks' doubles and partial doubles from being used outside of + the per-test lifecycle (e.g. from a `before(:all)` hook). (Sam Phippen) +* Remove the `host` argument of `RSpec::Mocks.setup`. Instead + `RSpec::Mocks::ExampleMethods` should be included directly in the scope where + RSpec's mocking capabilities are used. (Sam Phippen) +* Make test doubles raise errors if you attempt to use them after they + get reset, to help surface issues when you accidentally retain + references to test doubles and attempt to reuse them in another + example. (Myron Marston) +* Remove support for `and_return { value }` and `and_return` without arguments. (Yuji Nakayama) + +Enhancements: + +* Add `receive_message_chain` which provides the functionality of the old + `stub_chain` for the new allow/expect syntax. Use it like so: `allow(...).to + receive_message_chain(:foo, :bar, :bazz)`. (Sam Phippen). +* Change argument matchers to use `===` as their primary matching + protocol, since their semantics mirror that of a case or rescue statement + (which uses `===` for matching). (Myron Marston) +* Add `RSpec::Mocks.with_temporary_scope`, which allows you to create + temporary rspec-mocks scopes in arbitrary places (such as a + `before(:all)` hook). (Myron Marston) +* Support keyword arguments when checking arity with verifying doubles. + (Xavier Shay) + +Bug Fixes: + +* Fix regression in 3.0.0.beta1 that caused `double("string_name" => :value)` + to stop working. (Xavier Shay) +* Fix the way rspec-mocks and rspec-core interact so that if users + define a `let` with the same name as one of the methods + from `RSpec::Mocks::ArgumentMatchers`, the user's `let` takes + precedence. (Michi Huber, Myron Marston) +* Fix verified doubles so that their methods match the visibility + (public, protected or private) of the interface they verify + against. (Myron Marston) +* Fix verified null object doubles so that they do not wrongly + report that they respond to anything. They only respond to methods + available on the interface they verify against. (Myron Marston) +* Fix deprecation warning for use of old `:should` syntax w/o explicit + config so that it no longer is silenced by an extension gem such + as rspec-rails when it calls `config.add_stub_and_should_receive_to`. + (Sam Phippen) +* Fix `expect` syntax so that it does not wrongly emit a "You're + overriding a previous implementation for this stub" warning when + you are not actually doing that. (Myron Marston) +* Fix `any_instance.unstub` when used on sub classes for whom the super + class has had `any_instance.stub` invoked on. (Jon Rowe) +* Fix regression in `stub_chain`/`receive_message_chain` that caused + it to raise an `ArgumentError` when passing args to the stubbed + methods. (Sam Phippen) +* Correct stub of undefined parent modules all the way down when stubbing a + nested constant. (Xavier Shay) +* Raise `VerifyingDoubleNotDefinedError` when a constant is not defined for + a verifying class double. (Maurício Linhares) +* Remove `Double#to_str`, which caused confusing `raise some_double` + behavior. (Maurício Linhares) + +### 3.0.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.4...v3.0.0.beta1) + +Breaking Changes for 3.0.0: + +* Raise an explicit error if `should_not_receive(...).and_return` is used. (Sam + Phippen) +* Remove 1.8.6 workarounds. (Jon Rowe) +* Remove `stub!` and `unstub!`. (Sam Phippen) +* Remove `mock(name, methods)` and `stub(name, methods)`, leaving + `double(name, methods)` for creating test doubles. (Sam Phippen, Michi Huber) +* Remove `any_number_of_times` since `should_receive(:msg).any_number_of_times` + is really a stub in a mock's clothing. (Sam Phippen) +* Remove support for re-using the same null-object test double in multiple + examples. Test doubles are designed to only live for one example. + (Myron Marston) +* Make `at_least(0)` raise an error. (Sam Phippen) +* Remove support for `require 'spec/mocks'` which had been kept + in place for backwards compatibility with RSpec 1. (Myron Marston) +* Blocks provided to `with` are always used as implementation. (Xavier Shay) +* The config option (added in 2.99) to yield the receiver to + `any_instance` implementation blocks now defaults to "on". (Sam Phippen) + +Enhancements: + +* Allow the `have_received` matcher to use a block to set further expectations + on arguments. (Tim Cowlishaw) +* Provide `instance_double` and `class_double` to create verifying doubles, + ported from `rspec-fire`. (Xavier Shay) +* `as_null_object` on a verifying double only responds to defined methods. + (Xavier Shay) +* Provide `object_double` to create verified doubles of specific object + instances. (Xavier Shay) +* Provide `verify_partial_doubles` configuration that provides `object_double` + like verification behaviour on partial doubles. (Xavier Shay) +* Improved performance of double creation, particularly those with many + attributes. (Xavier Shay) +* Default value of `transfer_nested_constants` option for constant stubbing can + be configured. (Xavier Shay) +* Messages can be allowed or expected on in bulk via + `receive_messages(:message => :value)`. (Jon Rowe) +* `allow(Klass.any_instance)` and `expect(Klass.any_instance)` now print a + warning. This is usually a mistake, and users usually want + `allow_any_instance_of` or `expect_any_instance_of` instead. (Sam Phippen) +* `instance_double` and `class_double` raise `ArgumentError` if the underlying + module is loaded and the arity of the method being invoked does not match the + arity of the method as it is actually implemented. (Andy Lindeman) +* Spies can now check their invocation ordering is correct. (Jon Rowe) + +Deprecations: + +* Using the old `:should` syntax without explicitly configuring it + is deprecated. It will continue to work but will emit a deprecation + warning in RSpec 3 if you do not explicitly enable it. (Sam Phippen) + +Bug Fixes: + +* Fix `and_call_original` to handle a complex edge case involving + singleton class ancestors. (Marc-André Lafortune, Myron Marston) +* When generating an error message for unexpected arguments, + use `#inspect` rather than `#description` if `#description` + returns `nil` or `''` so that you still get a useful message. + (Nick DeLuca) + +### 2.99.4 / 2015-06-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.3...v2.99.4) + +Bug Fixes: + +* Add missing deprecation for using `with` with no arguments e.g. `with()`. (Yousuke, rspec/rspec-mocks#970) + +### 2.99.3 / 2015-01-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.2...v2.99.3) + +Bug Fixes: + +* Fix regression that caused an error when a test double was deserialized from YAML. (Yuji Nakayama, rspec/rspec-mocks#777) + +### 2.99.2 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.1...v2.99.2) + +Enhancements: + +* Warn about upcoming change to `#===` matching and `DateTime#===` behaviour. + (Jon Rowe, rspec/rspec-mocks#735) + +### 2.99.1 / 2014-06-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0...v2.99.1) + +Bug Fixes: + +* Fix bug that caused errors at the end of each example + when a `double.as_null_object` had been frozen. (Yuji Nakayama, rspec/rspec-mocks#698) + +Deprecations: + +* Deprecate freezing a test double. (Yuji Nakayama, rspec/rspec-mocks#698) + +### 2.99.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.rc1...v2.99.0) + +No changes. Just taking it out of pre-release. + +### 2.99.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta2...v2.99.0.rc1) + +Deprecations: + +* Deprecate `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston) +* Deprecate `RSpec::Mocks::ConstantStubber`. (Jon Rowe) +* Deprecate `Marshal.dump` monkey-patch without opt-in. (Xavier Shay) + +### 2.99.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta1...v2.99.0.beta2) + +Deprecations: + +* Deprecate `RSpec::Mocks::Mock` in favor of `RSpec::Mocks::Double`. + (Myron Marston) +* Deprecate the `host` argument of `RSpec::Mocks.setup`. Instead + `RSpec::Mocks::ExampleMethods` should be included directly in the scope where + RSpec's mocking capabilities are used. (Sam Phippen) +* Deprecate using any of rspec-mocks' features outside the per-test + lifecycle (e.g. from a `before(:all)` hook). (Myron Marston) +* Deprecate re-using a test double in another example. (Myron Marston) +* Deprecate `and_return { value }` and `and_return` without arguments. (Yuji Nakayama) + +### 2.99.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.99.0.beta1) + +Deprecations + +* Expecting to use lambdas or other strong arity implementations for stub + methods with mis-matched arity is deprecated and support for them will be + removed in 3.0. Either provide the right amount of arguments or use a weak + arity implementation (methods with splats or procs). (Jon Rowe) +* Using the same test double instance in multiple examples is deprecated. Test + doubles are only meant to live for one example. The mocks and stubs have + always been reset between examples; however, in 2.x the `as_null_object` + state was not reset and some users relied on this to have a null object + double that is used for many examples. This behavior will be removed in 3.0. + (Myron Marston) +* Print a detailed warning when an `any_instance` implementation block is used + when the new `yield_receiver_to_any_instance_implementation_blocks` config + option is not explicitly set, as RSpec 3.0 will default to enabling this new + feature. (Sam Phippen) + +Enhancements: + +* Add a config option to yield the receiver to `any_instance` implementation + blocks. (Sam Phippen) + +### 2.14.6 / 2014-02-20 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.5...v2.14.6) + +Bug Fixes: + +* Ensure `any_instance` method stubs and expectations are torn down regardless of + expectation failures. (Sam Phippen) + +### 2.14.5 / 2014-02-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.14.5) + +Bug Fixes: + +* Fix regression that caused block implementations to not receive all + args on 1.8.7 if the block also receives a block, due to Proc#arity + reporting `1` no matter how many args the block receives if it + receives a block, too. (Myron Marston) + +### 2.14.4 / 2013-10-15 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.3...v2.14.4) + +Bug Fixes: + +* Fix issue where unstubing methods on "any instances" would not + remove stubs on existing instances (Jon Rowe) +* Fix issue with receive(:message) do ... end precedence preventing + the usage of modifications (`and_return` etc) (Jon Rowe) + +### 2.14.3 / 2013-08-08 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.2...v2.14.3) + +Bug Fixes: + +* Fix stubbing some instance methods for classes whose hierarchy includes + a prepended Module (Bradley Schaefer) + +### 2.14.2 / 2013-07-30 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.1...v2.14.2) + +Bug Fixes: + +* Fix `as_null_object` doubles so that they return `nil` from `to_ary` + (Jon Rowe). +* Fix regression in 2.14 that made `stub!` (with an implicit receiver) + return a test double rather than stub a method (Myron Marston). + +### 2.14.1 / 2013-07-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0...v2.14.1) + +Bug Fixes: + +* Restore `double.as_null_object` behavior from 2.13 and earlier: a + double's nullness persisted between examples in earlier examples. + While this is not an intended use case (test doubles are meant to live + for only one example), we don't want to break behavior users rely + on in a minor relase. This will be deprecated in 2.99 and removed + in 3.0. (Myron Marston) + +### 2.14.0 / 2013-07-06 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0.rc1...v2.14.0) + +Enhancements: + +* Document test spies in the readme. (Adarsh Pandit) +* Add an `array_including` matcher. (Sam Phippen) +* Add a syntax-agnostic API for mocking or stubbing a method. This is + intended for use by libraries such as rspec-rails that need to mock + or stub a method, and work regardless of the syntax the user has + configured (Paul Annesley, Myron Marston and Sam Phippen). + +Bug Fixes: + +* Fix `double` so that it sets up passed stubs correctly regardless of + the configured syntax (Paul Annesley). +* Allow a block implementation to be used in combination with + `and_yield`, `and_raise`, `and_return` or `and_throw`. This got fixed + in 2.13.1 but failed to get merged into master for the 2.14.0.rc1 + release (Myron Marston). +* `Marshal.dump` does not unnecessarily duplicate objects when rspec-mocks has + not been fully initialized. This could cause errors when using `spork` or + similar preloading gems (Andy Lindeman). + +### 2.14.0.rc1 / 2013-05-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.14.0.rc1) + +Enhancements: + +* Refactor internals so that the mock proxy methods and state are held + outside of the mocked object rather than inside it. This paves the way + for future syntax enhancements and removes the need for some hacky + work arounds for `any_instance` dup'ing and `YAML` serialization, + among other things. Note that the code now relies upon `__id__` + returning a unique, consistent value for any object you want to + mock or stub (Myron Marston). +* Add support for test spies. This allows you to verify a message + was received afterwards using the `have_received` matcher. + Note that you must first stub the method or use a null double. + (Joe Ferris and Joël Quenneville) +* Make `at_least` and `at_most` style receive expectations print that they were + expecting at least or at most some number of calls, rather than just the + number of calls given in the expectation (Sam Phippen) +* Make `with` style receive expectations print the args they were expecting, and + the args that they got (Sam Phippen) +* Fix some warnings seen under ruby 2.0.0p0 (Sam Phippen). +* Add a new `:expect` syntax for message expectations + (Myron Marston and Sam Phippen). + +Bug fixes + +* Fix `any_instance` so that a frozen object can be `dup`'d when methods + have been stubbed on that type using `any_instance` (Jon Rowe). +* Fix `and_call_original` so that it properly raises an `ArgumentError` + when the wrong number of args are passed (Jon Rowe). +* Fix `double` on 1.9.2 so you can wrap them in an Array + using `Array(my_double)` (Jon Rowe). +* Fix `stub_const` and `hide_const` to handle constants that redefine `send` + (Sam Phippen). +* Fix `Marshal.dump` extension so that it correctly handles nil. + (Luke Imhoff, Jon Rowe) +* Fix isolation of `allow_message_expectations_on_nil` (Jon Rowe) +* Use inspect to format actual arguments on expectations in failure messages (rspec/rspec-mocks#280, Ben Langfeld) +* Protect against improperly initialised test doubles (rspec/rspec-mocks#293) (Joseph Shraibman and Jon Rowe) + +Deprecations + +* Deprecate `stub` and `mock` as aliases for `double`. `double` is the + best term for creating a test double, and it reduces confusion to + have only one term (Michi Huber). +* Deprecate `stub!` and `unstub!` in favor of `stub` and `unstub` + (Jon Rowe). +* Deprecate `at_least(0).times` and `any_number_of_times` (Michi Huber). + +### 2.13.1 / 2013-04-06 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.13.1) + +Bug fixes + +* Allow a block implementation to be used in combination with + `and_yield`, `and_raise`, `and_return` or `and_throw` (Myron Marston). + +### 2.13.0 / 2013-02-23 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.2...v2.13.0) + +Bug fixes + +* Fix bug that caused weird behavior when a method that had + previously been stubbed with multiple return values (e.g. + `obj.stub(:foo).and_return(1, 2)`) was later mocked with a + single return value (e.g. `obj.should_receive(:foo).once.and_return(1)`). + (Myron Marston) +* Fix bug related to a mock expectation for a method that already had + multiple stubs with different `with` constraints. Previously, the + first stub was used, even though it may not have matched the passed + args. The fix defers this decision until the message is received so + that the proper stub response can be chosen based on the passed + arguments (Myron Marston). +* Do not call `nil?` extra times on a mocked object, in case `nil?` + itself is expected a set number of times (Myron Marston). +* Fix `missing_default_stub_error` message so array args are handled + properly (Myron Marston). +* Explicitly disallow `any_instance.unstub!` (Ryan Jones). +* Fix `any_instance` stubbing so that it works with `Delegator` + subclasses (Myron Marston). +* Fix `and_call_original` so that it works with `Delegator` subclasses + (Myron Marston). +* Fix `any_instance.should_not_receive` when `any_instance.should_receive` + is used on the same class in the same example. Previously it would + wrongly report a failure even when the message was not received + (Myron Marston). + +### 2.12.2 / 2013-01-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.1...v.2.12.2) + +Bug fixes + +* Fix `and_call_original` to work properly for methods defined + on a module extended onto an object instance (Myron Marston). +* Fix `stub_const` with an undefined constnat name to work properly + with constant strings that are prefixed with `::` -- and edge case + I missed in the bug fix in the 2.12.1 release (Myron Marston). +* Ensure method visibility on a partial mock is restored after reseting + method stubs, even on a singleton module (created via `extend self`) + when the method visibility differs between the instance and singleton + versions (Andy Lindeman). + +### 2.12.1 / 2012-12-21 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.0...v2.12.1) + +Bug fixes + +* Fix `any_instance` to support `and_call_original`. + (Myron Marston) +* Properly restore stubbed aliased methods on rubies + that report the incorrect owner (Myron Marston and Andy Lindeman). +* Fix `hide_const` and `stub_const` with a defined constnat name to + work properly with constant strings that are prefixed with `::` (Myron Marston). + +### 2.12.0 / 2012-11-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.3...v2.12.0) + +Enhancements + +* `and_raise` can accept an exception class and message, more closely + matching `Kernel#raise` (e.g., `foo.stub(:bar).and_raise(RuntimeError, "message")`) + (Bas Vodde) +* Add `and_call_original`, which will delegate the message to the + original method (Myron Marston). + +Deprecations: + +* Add deprecation warning when using `and_return` with `should_not_receive` + (Neha Kumari) + +### 2.11.3 / 2012-09-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.2...v2.11.3) + +Bug fixes + +* Fix `:transfer_nested_constants` option of `stub_const` so that it + doesn't blow up when there are inherited constants. (Myron Marston) +* `any_instance` stubs can be used on classes that override `Object#method`. + (Andy Lindeman) +* Methods stubbed with `any_instance` are unstubbed after the test finishes. + (Andy Lindeman) +* Fix confusing error message when calling a mocked class method an + extra time with the wrong arguments (Myron Marston). + +### 2.11.2 / 2012-08-11 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.1...v2.11.2) + +Bug fixes + +* Don't modify `dup` on classes that don't support `dup` (David Chelimsky) +* Fix `any_instance` so that it works properly with methods defined on + a superclass. (Daniel Eguzkiza) +* Fix `stub_const` so that it works properly for nested constants that + share a name with a top-level constant (e.g. "MyGem::Hash"). (Myron + Marston) + +### 2.11.1 / 2012-07-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.0...v2.11.1) + +Bug fixes + +* Fix `should_receive` so that when it is called on an `as_null_object` + double with no implementation, and there is a previous explicit stub + for the same method, the explicit stub remains (rather than being + overridden with the null object implementation--`return self`). (Myron + Marston) + +### 2.11.0 / 2012-07-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.1...v2.11.0) + +Enhancements + +* Expose ArgumentListMatcher as a formal API + * supports use by 3rd party mock frameworks like Surrogate +* Add `stub_const` API to stub constants for the duration of an + example (Myron Marston). + +Bug fixes + +* Fix regression of edge case behavior. `double.should_receive(:foo) { a }` + was causing a NoMethodError when `double.stub(:foo).and_return(a, b)` + had been setup before (Myron Marston). +* Infinite loop generated by using `any_instance` and `dup`. (Sidu Ponnappa @kaiwren) +* `double.should_receive(:foo).at_least(:once).and_return(a)` always returns a + even if `:foo` is already stubbed. +* Prevent infinite loop when interpolating a null double into a string + as an integer (`"%i" % double.as_null_object`). (Myron Marston) +* Fix `should_receive` so that null object behavior (e.g. returning + self) is preserved if no implementation is given (Myron Marston). +* Fix `and_raise` so that it raises `RuntimeError` rather than + `Exception` by default, just like ruby does. (Andrew Marshall) + +### 2.10.1 / 2012-05-05 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.0...v2.10.1) + +Bug fixes + +* fix regression of edge case behavior + (https://github.com/rspec/rspec-mocks/issues/132) + * fixed failure of `object.should_receive(:message).at_least(0).times.and_return value` + * fixed failure of `object.should_not_receive(:message).and_return value` + +### 2.10.0 / 2012-05-03 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.9.0...v2.10.0) + +Bug fixes + +* fail fast when an `exactly` or `at_most` expectation is exceeded + +### 2.9.0 / 2012-03-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0...v2.9.0) + +Enhancements + +* Support order constraints across objects (preethiramdev) + +Bug fixes + +* Allow a `as_null_object` to be passed to `with` +* Pass proc to block passed to stub (Aubrey Rhodes) +* Initialize child message expectation args to match any args (rspec/rspec-mocks#109 - + preethiramdev) + +### 2.8.0 / 2012-01-04 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc2...v2.8.0) + +No changes for this release. Just releasing with the other rspec gems. + +### 2.8.0.rc2 / 2011-12-19 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc1...v2.8.0.rc2) + +No changes for this release. Just releasing with the other rspec gems. + +### 2.8.0.rc1 / 2011-11-06 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.7.0...v2.8.0.rc1) + +Enhancements + +* Eliminate Ruby warnings (Matijs van Zuijlen) + +### 2.7.0 / 2011-10-16 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.6.0...v2.7.0) + +Enhancements + +* Use `__send__` rather than `send` (alextk) +* Add support for `any_instance.stub_chain` (Sidu Ponnappa) +* Add support for `any_instance` argument matching based on `with` (Sidu + Ponnappa and Andy Lindeman) + +Changes + +* Check for `failure_message_for_should` or `failure_message` instead of + `description` to detect a matcher (Tibor Claassen) + +Bug fixes + +* pass a hash to `any_instance.stub`. (Justin Ko) +* allow `to_ary` to be called without raising `NoMethodError` (Mikhail + Dieterle) +* `any_instance` properly restores private methods (Sidu Ponnappa) + +### 2.6.0 / 2011-05-12 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.5.0...v2.6.0) + +Enhancements + +* Add support for `any_instance.stub` and `any_instance.should_receive` (Sidu + Ponnappa and Andy Lindeman) + +Bug fixes + +* fix bug in which multiple chains with shared messages ending in hashes failed + to return the correct value + +### 2.5.0 / 2011-02-05 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.4.0...v2.5.0) + +Bug fixes + +* message expectation counts now work in combination with a stub (Damian + Nurzynski) +* fix failure message when message received with incorrect args (Josep M. + Bach) + +### 2.4.0 / 2011-01-02 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.3.0...v2.4.0) + +No functional changes in this release, which was made to align with the +rspec-core-2.4.0 release. + +### 2.3.0 / 2010-12-12 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.2.0...v2.3.0) + +Bug fixes + +* Fix our Marshal extension so that it does not interfere with objects that + have their own `@mock_proxy` instance variable. (Myron Marston) + +### 2.2.0 / 2010-11-28 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.1.0...v2.2.0) + +Enhancements + +* Added "rspec/mocks/standalone" for exploring the rspec-mocks in irb. + +Bug fix + +* Eliminate warning on splat args without parens (Gioele Barabucci) +* Fix bug where `obj.should_receive(:foo).with(stub.as_null_object)` would pass + with a false positive. + +### 2.1.0 / 2010-11-07 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.1...v2.1.0) + +Bug fixes + +* Fix serialization of stubbed object (Josep M Bach) + +### 2.0.0 / 2010-10-10 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0) + +### 2.0.0.rc / 2010-10-05 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0.rc) + +Enhancements + +* support passing a block to an expectation block (Nicolas Braem) + * `obj.should_receive(:msg) {|&block| ... }` + +Bug fixes + +* Fix YAML serialization of stub (Myron Marston) +* Fix rdoc rake task (Hans de Graaff) + +### 2.0.0.beta.22 / 2010-09-12 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.20...v2.0.0.beta.22) + +Bug fixes + +* fixed regression that broke `obj.stub_chain(:a, :b => :c)` +* fixed regression that broke `obj.stub_chain(:a, :b) { :c }` +* `respond_to?` always returns true when using `as_null_object` diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md new file mode 100644 index 0000000..dae02d8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md @@ -0,0 +1,25 @@ +The MIT License (MIT) +===================== + +* Copyright © 2012 David Chelimsky, Myron Marston +* Copyright © 2006 David Chelimsky, The RSpec Development Team +* Copyright © 2005 Steven Baker + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md new file mode 100644 index 0000000..e569fee --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md @@ -0,0 +1,465 @@ +# RSpec Mocks [![Build Status](https://github.com/rspec/rspec-mocks/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-mocks/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.svg)](https://codeclimate.com/github/rspec/rspec-mocks) +rspec-mocks is a test-double framework for rspec with support for method stubs, +fakes, and message expectations on generated test-doubles and real objects +alike. + +## Install + + gem install rspec # for rspec-core, rspec-expectations, rspec-mocks + gem install rspec-mocks # for rspec-mocks only + +Want to run against the `main` branch? You'll need to include the dependent +RSpec repos as well. Add the following to your `Gemfile`: + +```ruby +%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| + gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' +end +``` +## Contributing + +Once you've set up the environment, you'll need to cd into the working +directory of whichever repo you want to work in. From there you can run the +specs and cucumber features, and make patches. + +NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You +can treat each RSpec repo as an independent project. + +For information about contributing to RSpec, please refer to the following markdown files: +* [Build details](BUILD_DETAIL.md) +* [Code of Conduct](CODE_OF_CONDUCT.md) +* [Detailed contributing guide](CONTRIBUTING.md) +* [Development setup guide](DEVELOPMENT.md) + +## Test Doubles + +A test double is an object that stands in for another object in your system +during a code example. Use the `double` method, passing in an optional identifier, to create one: + +```ruby +book = double("book") +``` + +Most of the time you will want some confidence that your doubles resemble an +existing object in your system. Verifying doubles are provided for this +purpose. If the existing object is available, they will prevent you from adding +stubs and expectations for methods that do not exist or that have an invalid +number of parameters. + +```ruby +book = instance_double("Book", :pages => 250) +``` + +Verifying doubles have some clever tricks to enable you to both test in +isolation without your dependencies loaded while still being able to validate +them against real objects. More detail is available in [their +documentation](https://github.com/rspec/rspec-mocks/blob/main/features/verifying_doubles). + +Verifying doubles can also accept custom identifiers, just like double(), e.g.: + +```ruby +books = [] +books << instance_double("Book", :rspec_book, :pages => 250) +books << instance_double("Book", "(Untitled)", :pages => 5000) + +puts books.inspect # with names, it's clearer which were actually added +``` + +## Method Stubs + +A method stub is an implementation that returns a pre-determined value. Method +stubs can be declared on test doubles or real objects using the same syntax. +rspec-mocks supports 3 forms for declaring method stubs: + +```ruby +allow(book).to receive(:title) { "The RSpec Book" } +allow(book).to receive(:title).and_return("The RSpec Book") +allow(book).to receive_messages( + :title => "The RSpec Book", + :subtitle => "Behaviour-Driven Development with RSpec, Cucumber, and Friends") +``` + +You can also use this shortcut, which creates a test double and declares a +method stub in one statement: + +```ruby +book = double("book", :title => "The RSpec Book") +``` + +The first argument is a name, which is used for documentation and appears in +failure messages. If you don't care about the name, you can leave it out, +making the combined instantiation/stub declaration very terse: + +```ruby +double(:foo => 'bar') +``` + +This is particularly nice when providing a list of test doubles to a method +that iterates through them: + +```ruby +order.calculate_total_price(double(:price => 1.99), double(:price => 2.99)) +``` + +### Stubbing a chain of methods + +You can use `receive_message_chain` in place of `receive` to stub a chain of messages: + +```ruby +allow(double).to receive_message_chain("foo.bar") { :baz } +allow(double).to receive_message_chain(:foo, :bar => :baz) +allow(double).to receive_message_chain(:foo, :bar) { :baz } + +# Given any of the above forms: +double.foo.bar # => :baz +``` + +Chains can be arbitrarily long, which makes it quite painless to violate the Law of Demeter in violent ways, so you should consider any use of `receive_message_chain` a code smell. Even though not all code smells indicate real problems (think fluent interfaces), `receive_message_chain` still results in brittle examples. For example, if you write `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the implementation calls `foo.baz.bar`, the stub will not work. + +## Consecutive return values + +When a stub might be invoked more than once, you can provide additional +arguments to `and_return`. The invocations cycle through the list. The last +value is returned for any subsequent invocations: + +```ruby +allow(die).to receive(:roll).and_return(1, 2, 3) +die.roll # => 1 +die.roll # => 2 +die.roll # => 3 +die.roll # => 3 +die.roll # => 3 +``` + +To return an array in a single invocation, declare an array: + +```ruby +allow(team).to receive(:players).and_return([double(:name => "David")]) +``` + +## Message Expectations + +A message expectation is an expectation that the test double will receive a +message some time before the example ends. If the message is received, the +expectation is satisfied. If not, the example fails. + +```ruby +validator = double("validator") +expect(validator).to receive(:validate) { "02134" } +zipcode = Zipcode.new("02134", validator) +zipcode.valid? +``` + +## Test Spies + +Verifies the given object received the expected message during the course of +the test. For a message to be verified, the given object must be setup to spy +on it, either by having it explicitly stubbed or by being a null object double +(e.g. `double(...).as_null_object`). Convenience methods are provided to easily +create null object doubles for this purpose: + +```ruby +spy("invitation") # => same as `double("invitation").as_null_object` +instance_spy("Invitation") # => same as `instance_double("Invitation").as_null_object` +class_spy("Invitation") # => same as `class_double("Invitation").as_null_object` +object_spy("Invitation") # => same as `object_double("Invitation").as_null_object` +``` + +Verifying messages received in this way implements the Test Spy pattern. + +```ruby +invitation = spy('invitation') + +user.accept_invitation(invitation) + +expect(invitation).to have_received(:accept) + +# You can also use other common message expectations. For example: +expect(invitation).to have_received(:accept).with(mailer) +expect(invitation).to have_received(:accept).twice +expect(invitation).to_not have_received(:accept).with(mailer) + +# One can specify a return value on the spy the same way one would a double. +invitation = spy('invitation', :accept => true) +expect(invitation).to have_received(:accept).with(mailer) +expect(invitation.accept).to eq(true) +``` + +Note that `have_received(...).with(...)` is unable to work properly when +passed arguments are mutated after the spy records the received message. +For example, this does not work properly: + +```ruby +greeter = spy("greeter") + +message = "Hello" +greeter.greet_with(message) +message << ", World" + +expect(greeter).to have_received(:greet_with).with("Hello") +``` + +## Nomenclature + +### Mock Objects and Test Stubs + +The names Mock Object and Test Stub suggest specialized Test Doubles. i.e. +a Test Stub is a Test Double that only supports method stubs, and a Mock +Object is a Test Double that supports message expectations and method +stubs. + +There is a lot of overlapping nomenclature here, and there are many +variations of these patterns (fakes, spies, etc). Keep in mind that most of +the time we're talking about method-level concepts that are variations of +method stubs and message expectations, and we're applying to them to _one_ +generic kind of object: a Test Double. + +### Test-Specific Extension + +a.k.a. Partial Double, a Test-Specific Extension is an extension of a +real object in a system that is instrumented with test-double like +behaviour in the context of a test. This technique is very common in Ruby +because we often see class objects acting as global namespaces for methods. +For example, in Rails: + +```ruby +person = double("person") +allow(Person).to receive(:find) { person } +``` + +In this case we're instrumenting Person to return the person object we've +defined whenever it receives the `find` message. We can also set a message +expectation so that the example fails if `find` is not called: + +```ruby +person = double("person") +expect(Person).to receive(:find) { person } +``` + +RSpec replaces the method we're stubbing or mocking with its own +test-double-like method. At the end of the example, RSpec verifies any message +expectations, and then restores the original methods. + +## Expecting Arguments + +```ruby +expect(double).to receive(:msg).with(*args) +expect(double).to_not receive(:msg).with(*args) +``` + +You can set multiple expectations for the same message if you need to: + +```ruby +expect(double).to receive(:msg).with("A", 1, 3) +expect(double).to receive(:msg).with("B", 2, 4) +``` + +## Argument Matchers + +Arguments that are passed to `with` are compared with actual arguments +received using ===. In cases in which you want to specify things about the +arguments rather than the arguments themselves, you can use any of the +matchers that ship with rspec-expectations. They don't all make syntactic +sense (they were primarily designed for use with RSpec::Expectations), but +you are free to create your own custom RSpec::Matchers. + +rspec-mocks also adds some keyword Symbols that you can use to +specify certain kinds of arguments: + +```ruby +expect(double).to receive(:msg).with(no_args) +expect(double).to receive(:msg).with(any_args) +expect(double).to receive(:msg).with(1, any_args) # any args acts like an arg splat and can go anywhere +expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric +expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false +expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp +expect(double).to receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all +expect(double).to receive(:msg).with(1, duck_type(:abs, :div), "b") #2nd argument can be object that responds to #abs and #div +expect(double).to receive(:msg).with(hash_including(:a => 5)) # first arg is a hash with a: 5 as one of the key-values +expect(double).to receive(:msg).with(array_including(5)) # first arg is an array with 5 as one of the key-values +expect(double).to receive(:msg).with(hash_excluding(:a => 5)) # first arg is a hash without a: 5 as one of the key-values +expect(double).to receive(:msg).with(start_with('a')) # any matcher, custom or from rspec-expectations +expect(double).to receive(:msg).with(satisfy { |data| data.dig(:a, :b, :c) == 5 }) # assert anything you want +``` + +## Receive Counts + +```ruby +expect(double).to receive(:msg).once +expect(double).to receive(:msg).twice +expect(double).to receive(:msg).exactly(n).time +expect(double).to receive(:msg).exactly(n).times +expect(double).to receive(:msg).at_least(:once) +expect(double).to receive(:msg).at_least(:twice) +expect(double).to receive(:msg).at_least(n).time +expect(double).to receive(:msg).at_least(n).times +expect(double).to receive(:msg).at_most(:once) +expect(double).to receive(:msg).at_most(:twice) +expect(double).to receive(:msg).at_most(n).time +expect(double).to receive(:msg).at_most(n).times +``` + +## Ordering + +```ruby +expect(double).to receive(:msg).ordered +expect(double).to receive(:other_msg).ordered + # This will fail if the messages are received out of order +``` + +This can include the same message with different arguments: + +```ruby +expect(double).to receive(:msg).with("A", 1, 3).ordered +expect(double).to receive(:msg).with("B", 2, 4).ordered +``` + +## Setting Responses + +Whether you are setting a message expectation or a method stub, you can +tell the object precisely how to respond. The most generic way is to pass +a block to `receive`: + +```ruby +expect(double).to receive(:msg) { value } +``` + +When the double receives the `msg` message, it evaluates the block and returns +the result. + +```ruby +expect(double).to receive(:msg).and_return(value) +expect(double).to receive(:msg).exactly(3).times.and_return(value1, value2, value3) + # returns value1 the first time, value2 the second, etc +expect(double).to receive(:msg).and_raise(error) + # `error` can be an instantiated object (e.g. `StandardError.new(some_arg)`) or a class (e.g. `StandardError`) + # if it is a class, it must be instantiable with no args +expect(double).to receive(:msg).and_throw(:msg) +expect(double).to receive(:msg).and_yield(values, to, yield) +expect(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time) + # for methods that yield to a block multiple times +``` + +Any of these responses can be applied to a stub as well + +```ruby +allow(double).to receive(:msg).and_return(value) +allow(double).to receive(:msg).and_return(value1, value2, value3) +allow(double).to receive(:msg).and_raise(error) +allow(double).to receive(:msg).and_throw(:msg) +allow(double).to receive(:msg).and_yield(values, to, yield) +allow(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time) +``` + +## Arbitrary Handling + +Once in a while you'll find that the available expectations don't solve the +particular problem you are trying to solve. Imagine that you expect the message +to come with an Array argument that has a specific length, but you don't care +what is in it. You could do this: + +```ruby +expect(double).to receive(:msg) do |arg| + expect(arg.size).to eq 7 +end +``` + +If the method being stubbed itself takes a block, and you need to yield to it +in some special way, you can use this: + +```ruby +expect(double).to receive(:msg) do |&arg| + begin + arg.call + ensure + # cleanup + end +end +``` + +## Delegating to the Original Implementation + +When working with a partial mock object, you may occasionally +want to set a message expectation without interfering with how +the object responds to the message. You can use `and_call_original` +to achieve this: + +```ruby +expect(Person).to receive(:find).and_call_original +Person.find # => executes the original find method and returns the result +``` + +## Combining Expectation Details + +Combining the message name with specific arguments, receive counts and responses +you can get quite a bit of detail in your expectations: + +```ruby +expect(double).to receive(:<<).with("illegal value").once.and_raise(ArgumentError) +``` + +While this is a good thing when you really need it, you probably don't really +need it! Take care to specify only the things that matter to the behavior of +your code. + +## Stubbing and Hiding Constants + +See the [mutating constants +README](https://github.com/rspec/rspec-mocks/blob/main/features/mutating_constants/README.md) +for info on this feature. + +## Use `before(:example)`, not `before(:context)` + +Stubs in `before(:context)` are not supported. The reason is that all stubs and mocks get cleared out after each example, so any stub that is set in `before(:context)` would work in the first example that happens to run in that group, but not for any others. + +Instead of `before(:context)`, use `before(:example)`. + +## Settings mocks or stubs on any instance of a class + +rspec-mocks provides two methods, `allow_any_instance_of` and +`expect_any_instance_of`, that will allow you to stub or mock any instance +of a class. They are used in place of `allow` or `expect`: + +```ruby +allow_any_instance_of(Widget).to receive(:name).and_return("Wibble") +expect_any_instance_of(Widget).to receive(:name).and_return("Wobble") +``` + +These methods add the appropriate stub or expectation to all instances of +`Widget`. + +This feature is sometimes useful when working with legacy code, though in +general we discourage its use for a number of reasons: + +* The `rspec-mocks` API is designed for individual object instances, but this + feature operates on entire classes of objects. As a result there are some + semantically confusing edge cases. For example in + `expect_any_instance_of(Widget).to receive(:name).twice` it isn't clear + whether each specific instance is expected to receive `name` twice, or if two + receives total are expected. (It's the former.) +* Using this feature is often a design smell. It may be + that your test is trying to do too much or that the object under test is too + complex. +* It is the most complicated feature of `rspec-mocks`, and has historically + received the most bug reports. (None of the core team actively use it, + which doesn't help.) + + +## Further Reading + +There are many different viewpoints about the meaning of mocks and stubs. If +you are interested in learning more, here is some recommended reading: + +* Mock Objects: http://www.mockobjects.com/ +* Endo-Testing: http://www.ccs.neu.edu/research/demeter/related-work/extreme-programming/MockObjectsFinal.PDF +* Mock Roles, Not Objects: http://www.jmock.org/oopsla2004.pdf +* Test Double: http://www.martinfowler.com/bliki/TestDouble.html +* Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html +* Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html + +## Also see + +* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) +* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) +* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations) +* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb new file mode 100644 index 0000000..297779e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb @@ -0,0 +1,133 @@ +require 'rspec/support' +RSpec::Support.require_rspec_support 'caller_filter' +RSpec::Support.require_rspec_support 'warnings' +RSpec::Support.require_rspec_support 'ruby_features' + +RSpec::Support.define_optimized_require_for_rspec(:mocks) { |f| require_relative f } + +%w[ + instance_method_stasher + method_double + argument_matchers + example_methods + proxy + test_double + argument_list_matcher + message_expectation + order_group + error_generator + space + mutate_const + targets + syntax + configuration + verifying_double + version +].each { |name| RSpec::Support.require_rspec_mocks name } + +# Share the top-level RSpec namespace, because we are a core supported +# extension. +module RSpec + # Contains top-level utility methods. While this contains a few + # public methods, these are not generally meant to be called from + # a test or example. They exist primarily for integration with + # test frameworks (such as rspec-core). + module Mocks + # Performs per-test/example setup. This should be called before + # an test or example begins. + def self.setup + @space_stack << (@space = space.new_scope) + end + + # Verifies any message expectations that were set during the + # test or example. This should be called at the end of an example. + def self.verify + space.verify_all + end + + # Cleans up all test double state (including any methods that were + # redefined on partial doubles). This _must_ be called after + # each example, even if an error was raised during the example. + def self.teardown + space.reset_all + @space_stack.pop + @space = @space_stack.last || @root_space + end + + # Adds an allowance (stub) on `subject` + # + # @param subject the subject to which the message will be added + # @param message a symbol, representing the message that will be + # added. + # @param opts a hash of options, :expected_from is used to set the + # original call site + # @yield an optional implementation for the allowance + # + # @example Defines the implementation of `foo` on `bar`, using the passed block + # x = 0 + # RSpec::Mocks.allow_message(bar, :foo) { x += 1 } + def self.allow_message(subject, message, opts={}, &block) + space.proxy_for(subject).add_stub(message, opts, &block) + end + + # Sets a message expectation on `subject`. + # @param subject the subject on which the message will be expected + # @param message a symbol, representing the message that will be + # expected. + # @param opts a hash of options, :expected_from is used to set the + # original call site + # @yield an optional implementation for the expectation + # + # @example Expect the message `foo` to receive `bar`, then call it + # RSpec::Mocks.expect_message(bar, :foo) + # bar.foo + def self.expect_message(subject, message, opts={}, &block) + space.proxy_for(subject).add_message_expectation(message, opts, &block) + end + + # Call the passed block and verify mocks after it has executed. This allows + # mock usage in arbitrary places, such as a `before(:all)` hook. + # + # @return [Object] the return value from the block + def self.with_temporary_scope + setup + + begin + result = yield + verify + result + ensure + teardown + end + end + + class << self + # @private + attr_reader :space + end + @space_stack = [] + @root_space = @space = RSpec::Mocks::RootSpace.new + + # @private + IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored' + + # To speed up boot time a bit, delay loading optional or rarely + # used features until their first use. + autoload :AnyInstance, "rspec/mocks/any_instance" + autoload :ExpectChain, "rspec/mocks/message_chain" + autoload :StubChain, "rspec/mocks/message_chain" + autoload :MarshalExtension, "rspec/mocks/marshal_extension" + + # Namespace for mock-related matchers. + module Matchers + # @private + # just a "tag" for rspec-mock matchers detection + module Matcher; end + + autoload :HaveReceived, "rspec/mocks/matchers/have_received" + autoload :Receive, "rspec/mocks/matchers/receive" + autoload :ReceiveMessageChain, "rspec/mocks/matchers/receive_message_chain" + autoload :ReceiveMessages, "rspec/mocks/matchers/receive_messages" + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb new file mode 100644 index 0000000..41eae81 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb @@ -0,0 +1,11 @@ +%w[ + any_instance/chain + any_instance/error_generator + any_instance/stub_chain + any_instance/stub_chain_chain + any_instance/expect_chain_chain + any_instance/expectation_chain + any_instance/message_chains + any_instance/recorder + any_instance/proxy +].each { |f| RSpec::Support.require_rspec_mocks(f) } diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb new file mode 100644 index 0000000..74d864b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb @@ -0,0 +1,111 @@ +module RSpec + module Mocks + # @private + module AnyInstance + # @private + class Chain + def initialize(recorder, *args, &block) + @recorder = recorder + @expectation_args = args + @expectation_block = block + @argument_list_matcher = ArgumentListMatcher::MATCH_ALL + end + + # @private + # + # Provides convenience methods for recording customizations on message + # expectations. + module Customizations + # @macro [attach] record + # @method $1(*args, &block) + # Records the `$1` message for playback against an instance that + # invokes a method stubbed or mocked using `any_instance`. + # + # @see RSpec::Mocks::MessageExpectation#$1 + # + def self.record(method_name) + define_method(method_name) do |*args, &block| + record(method_name, *args, &block) + end + end + + record :and_return + record :and_raise + record :and_throw + record :and_yield + record :and_call_original + record :and_wrap_original + record :with + record :once + record :twice + record :thrice + record :exactly + record :times + record :time + record :never + record :at_least + record :at_most + end + + include Customizations + + # @private + def playback!(instance) + message_expectation = create_message_expectation_on(instance) + messages.inject(message_expectation) do |object, message| + object.__send__(*message.first, &message.last) + end + end + + # @private + def constrained_to_any_of?(*constraints) + constraints.any? do |constraint| + messages.any? do |message| + message.first.first == constraint + end + end + end + + # @private + def matches_args?(*args) + @argument_list_matcher.args_match?(*args) + end + + # @private + def expectation_fulfilled! + @expectation_fulfilled = true + end + + def never + AnyInstance.error_generator.raise_double_negation_error("expect_any_instance_of(MyClass)") if negated? + super + end + + def with(*args, &block) + @argument_list_matcher = ArgumentListMatcher.new(*args) + super + end + + private + + def negated? + messages.any? { |(message, *_), _| message == :never } + end + + def messages + @messages ||= [] + end + + def last_message + messages.last.first.first unless messages.empty? + end + + def record(rspec_method_name, *args, &block) + verify_invocation_order(rspec_method_name, *args, &block) + messages << [args.unshift(rspec_method_name), block] + self + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb new file mode 100644 index 0000000..d1046cb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb @@ -0,0 +1,31 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class ErrorGenerator < ::RSpec::Mocks::ErrorGenerator + def raise_second_instance_received_message_error(unfulfilled_expectations) + __raise "Exactly one instance should have received the following " \ + "message(s) but didn't: #{unfulfilled_expectations.sort.join(', ')}" + end + + def raise_does_not_implement_error(klass, method_name) + __raise "#{klass} does not implement ##{method_name}" + end + + def raise_message_already_received_by_other_instance_error(method_name, object_inspect, invoked_instance) + __raise "The message '#{method_name}' was received by #{object_inspect} " \ + "but has already been received by #{invoked_instance}" + end + + def raise_not_supported_with_prepend_error(method_name, problem_mod) + __raise "Using `any_instance` to stub a method (#{method_name}) that has been " \ + "defined on a prepended module (#{problem_mod}) is not supported." + end + end + + def self.error_generator + @error_generator ||= ErrorGenerator.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb new file mode 100644 index 0000000..c467ba9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb @@ -0,0 +1,31 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class ExpectChainChain < StubChain + def initialize(*args) + super + @expectation_fulfilled = false + end + + def expectation_fulfilled? + @expectation_fulfilled + end + + def playback!(instance) + super.tap { @expectation_fulfilled = true } + end + + private + + def create_message_expectation_on(instance) + ::RSpec::Mocks::ExpectChain.expect_chain_on(instance, *@expectation_args, &@expectation_block) + end + + def invocation_order + EmptyInvocationOrder + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb new file mode 100644 index 0000000..edf8548 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb @@ -0,0 +1,50 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class ExpectationChain < Chain + def expectation_fulfilled? + @expectation_fulfilled || constrained_to_any_of?(:never) + end + + def initialize(*args, &block) + @expectation_fulfilled = false + super + end + + private + + def verify_invocation_order(_rspec_method_name, *_args, &_block) + end + end + + # @private + class PositiveExpectationChain < ExpectationChain + private + + def create_message_expectation_on(instance) + proxy = ::RSpec::Mocks.space.proxy_for(instance) + method_name, opts = @expectation_args + opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE) + + me = proxy.add_message_expectation(method_name, opts, &@expectation_block) + if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks? + me.and_yield_receiver_to_implementation + end + + me + end + + ExpectationInvocationOrder = + { + :and_return => [:with, nil], + :and_raise => [:with, nil], + }.freeze + + def invocation_order + ExpectationInvocationOrder + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb new file mode 100644 index 0000000..7f4d770 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb @@ -0,0 +1,83 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class MessageChains + def initialize + @chains_by_method_name = Hash.new { |h, k| h[k] = [] } + end + + # @private + def [](method_name) + @chains_by_method_name[method_name] + end + + # @private + def add(method_name, chain) + @chains_by_method_name[method_name] << chain + chain + end + + # @private + def remove_stub_chains_for!(method_name) + @chains_by_method_name[method_name].reject! do |chain| + StubChain === chain + end + end + + # @private + def has_expectation?(method_name) + @chains_by_method_name[method_name].find do |chain| + ExpectationChain === chain + end + end + + # @private + def each_unfulfilled_expectation_matching(method_name, *args) + @chains_by_method_name[method_name].each do |chain| + yield chain if !chain.expectation_fulfilled? && chain.matches_args?(*args) + end + end + + # @private + def all_expectations_fulfilled? + @chains_by_method_name.all? do |_method_name, chains| + chains.all? { |chain| chain.expectation_fulfilled? } + end + end + + # @private + def unfulfilled_expectations + @chains_by_method_name.map do |method_name, chains| + method_name.to_s if ExpectationChain === chains.last && !chains.last.expectation_fulfilled? + end.compact + end + + # @private + def received_expected_message!(method_name) + @chains_by_method_name[method_name].each do |chain| + chain.expectation_fulfilled! + end + end + + # @private + def playback!(instance, method_name) + raise_if_second_instance_to_receive_message(instance) + @chains_by_method_name[method_name].each do |chain| + chain.playback!(instance) + end + end + + private + + def raise_if_second_instance_to_receive_message(instance) + @instance_with_expectation ||= instance if ExpectationChain === instance + return unless ExpectationChain === instance + return if @instance_with_expectation.equal?(instance) + + AnyInstance.error_generator.raise_second_instance_received_message_error(unfulfilled_expectations) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb new file mode 100644 index 0000000..54ded05 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb @@ -0,0 +1,125 @@ +module RSpec + module Mocks + module AnyInstance + # @private + # The `AnyInstance::Recorder` is responsible for redefining the klass's + # instance method in order to add any stubs/expectations the first time + # the method is called. It's not capable of updating a stub on an instance + # that's already been previously stubbed (either directly, or via + # `any_instance`). + # + # This proxy sits in front of the recorder and delegates both to it + # and to the `RSpec::Mocks::Proxy` for each already mocked or stubbed + # instance of the class, in order to propagates changes to the instances. + # + # Note that unlike `RSpec::Mocks::Proxy`, this proxy class is stateless + # and is not persisted in `RSpec::Mocks.space`. + # + # Proxying for the message expectation fluent interface (typically chained + # off of the return value of one of these methods) is provided by the + # `FluentInterfaceProxy` class below. + class Proxy + def initialize(recorder, target_proxies) + @recorder = recorder + @target_proxies = target_proxies + end + + def klass + @recorder.klass + end + + def stub(method_name_or_method_map, &block) + if Hash === method_name_or_method_map + method_name_or_method_map.each do |method_name, return_value| + stub(method_name).and_return(return_value) + end + else + perform_proxying(__method__, [method_name_or_method_map], block) do |proxy| + proxy.add_stub(method_name_or_method_map, &block) + end + end + end + + def unstub(method_name) + perform_proxying(__method__, [method_name], nil) do |proxy| + proxy.remove_stub_if_present(method_name) + end + end + + def stub_chain(*chain, &block) + perform_proxying(__method__, chain, block) do |proxy| + Mocks::StubChain.stub_chain_on(proxy.object, *chain, &block) + end + end + + def expect_chain(*chain, &block) + perform_proxying(__method__, chain, block) do |proxy| + Mocks::ExpectChain.expect_chain_on(proxy.object, *chain, &block) + end + end + + def should_receive(method_name, &block) + perform_proxying(__method__, [method_name], block) do |proxy| + # Yeah, this is a bit odd...but if we used `add_message_expectation` + # then it would act like `expect_every_instance_of(klass).to receive`. + # The any_instance recorder takes care of validating that an instance + # received the message. + proxy.add_stub(method_name, &block) + end + end + + def should_not_receive(method_name, &block) + perform_proxying(__method__, [method_name], block) do |proxy| + proxy.add_message_expectation(method_name, &block).never + end + end + + private + + def perform_proxying(method_name, args, block, &target_proxy_block) + recorder_value = @recorder.__send__(method_name, *args, &block) + proxy_values = @target_proxies.map(&target_proxy_block) + FluentInterfaceProxy.new([recorder_value] + proxy_values) + end + end + + unless defined?(BasicObject) + class BasicObject + # Remove all methods except those expected to be defined on BasicObject + (instance_methods.map(&:to_sym) - [:__send__, :"!", :instance_eval, :==, :instance_exec, :"!=", :equal?, :__id__, :__binding__, :object_id]).each do |method| + undef_method method + end + end + end + + # @private + # Delegates messages to each of the given targets in order to + # provide the fluent interface that is available off of message + # expectations when dealing with `any_instance`. + # + # `targets` will typically contain 1 of the `AnyInstance::Recorder` + # return values and N `MessageExpectation` instances (one per instance + # of the `any_instance` klass). + class FluentInterfaceProxy < BasicObject + def initialize(targets) + @targets = targets + end + + if ::RUBY_VERSION.to_f > 1.8 + def respond_to_missing?(method_name, include_private=false) + super || @targets.first.respond_to?(method_name, include_private) + end + else + def respond_to?(method_name, include_private=false) + super || @targets.first.respond_to?(method_name, include_private) + end + end + + def method_missing(*args, &block) + return_values = @targets.map { |t| t.__send__(*args, &block) } + FluentInterfaceProxy.new(return_values) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb new file mode 100644 index 0000000..0eb8245 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb @@ -0,0 +1,299 @@ +module RSpec + module Mocks + module AnyInstance + # Given a class `TheClass`, `TheClass.any_instance` returns a `Recorder`, + # which records stubs and message expectations for later playback on + # instances of `TheClass`. + # + # Further constraints are stored in instances of [Chain](Chain). + # + # @see AnyInstance + # @see Chain + class Recorder + # @private + attr_reader :message_chains, :stubs, :klass + + def initialize(klass) + @message_chains = MessageChains.new + @stubs = Hash.new { |hash, key| hash[key] = [] } + @observed_methods = [] + @played_methods = {} + @backed_up_method_owner = {} + @klass = klass + @expectation_set = false + + return unless RSpec::Mocks.configuration.verify_partial_doubles? + RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| + block.call(ObjectReference.for(klass)) + end + end + + # Initializes the recording a stub to be played back against any + # instance of this object that invokes the submitted method. + # + # @see Methods#stub + def stub(method_name, &block) + observe!(method_name) + message_chains.add(method_name, StubChain.new(self, method_name, &block)) + end + + # Initializes the recording a stub chain to be played back against any + # instance of this object that invokes the method matching the first + # argument. + # + # @see Methods#stub_chain + def stub_chain(*method_names_and_optional_return_values, &block) + normalize_chain(*method_names_and_optional_return_values) do |method_name, args| + observe!(method_name) + message_chains.add(method_name, StubChainChain.new(self, *args, &block)) + end + end + + # @private + def expect_chain(*method_names_and_optional_return_values, &block) + @expectation_set = true + normalize_chain(*method_names_and_optional_return_values) do |method_name, args| + observe!(method_name) + message_chains.add(method_name, ExpectChainChain.new(self, *args, &block)) + end + end + + # Initializes the recording a message expectation to be played back + # against any instance of this object that invokes the submitted + # method. + # + # @see Methods#should_receive + def should_receive(method_name, &block) + @expectation_set = true + observe!(method_name) + message_chains.add(method_name, PositiveExpectationChain.new(self, method_name, &block)) + end + + # The opposite of `should_receive` + # + # @see Methods#should_not_receive + def should_not_receive(method_name, &block) + should_receive(method_name, &block).never + end + + # Removes any previously recorded stubs, stub_chains or message + # expectations that use `method_name`. + # + # @see Methods#unstub + def unstub(method_name) + unless @observed_methods.include?(method_name.to_sym) + AnyInstance.error_generator.raise_method_not_stubbed_error(method_name) + end + message_chains.remove_stub_chains_for!(method_name) + stubs[method_name].clear + stop_observing!(method_name) unless message_chains.has_expectation?(method_name) + end + + # @api private + # + # Used internally to verify that message expectations have been + # fulfilled. + def verify + return unless @expectation_set + return if message_chains.all_expectations_fulfilled? + + AnyInstance.error_generator.raise_second_instance_received_message_error(message_chains.unfulfilled_expectations) + end + + # @private + def stop_all_observation! + @observed_methods.each { |method_name| restore_method!(method_name) } + end + + # @private + def playback!(instance, method_name) + RSpec::Mocks.space.ensure_registered(instance) + message_chains.playback!(instance, method_name) + @played_methods[method_name] = instance + received_expected_message!(method_name) if message_chains.has_expectation?(method_name) + end + + # @private + def instance_that_received(method_name) + @played_methods[method_name] + end + + # @private + def build_alias_method_name(method_name) + "__#{method_name}_without_any_instance__" + end + + # @private + def already_observing?(method_name) + @observed_methods.include?(method_name) || super_class_observing?(method_name) + end + + # @private + def notify_received_message(_object, message, args, _blk) + has_expectation = false + + message_chains.each_unfulfilled_expectation_matching(message, *args) do |expectation| + has_expectation = true + expectation.expectation_fulfilled! + end + + return unless has_expectation + + restore_method!(message) + mark_invoked!(message) + end + + protected + + def stop_observing!(method_name) + restore_method!(method_name) + @observed_methods.delete(method_name) + super_class_observers_for(method_name).each do |ancestor| + ::RSpec::Mocks.space. + any_instance_recorder_for(ancestor).stop_observing!(method_name) + end + end + + private + + def ancestor_is_an_observer?(ancestor, method_name) + return if ancestor == @klass + + ::RSpec::Mocks.space. + any_instance_recorder_for(ancestor).already_observing?(method_name) + end + + def super_class_observers_for(method_name) + @klass.ancestors.select do |ancestor| + ancestor_is_an_observer?(ancestor, method_name) + end + end + + def super_class_observing?(method_name) + @klass.ancestors.any? do |ancestor| + ancestor_is_an_observer?(ancestor, method_name) + end + end + + def normalize_chain(*args) + args.shift.to_s.split('.').map { |s| s.to_sym }.reverse.each { |a| args.unshift a } + yield args.first, args + end + + def received_expected_message!(method_name) + message_chains.received_expected_message!(method_name) + restore_method!(method_name) + mark_invoked!(method_name) + end + + def restore_method!(method_name) + if public_protected_or_private_method_defined?(build_alias_method_name(method_name)) + restore_original_method!(method_name) + else + remove_dummy_method!(method_name) + end + end + + def restore_original_method!(method_name) + return unless @klass.instance_method(method_name).owner == @klass + + alias_method_name = build_alias_method_name(method_name) + @klass.class_exec(@backed_up_method_owner) do |backed_up_method_owner| + remove_method method_name + + # A @klass can have methods implemented (see Method#owner) in @klass + # or inherited from a superclass. In ruby 2.2 and earlier, we can copy + # a method regardless of the 'owner' and restore it to @klass after + # because a call to 'super' from @klass's copied method would end up + # calling the original class's superclass's method. + # + # With the commit below, available starting in 2.3.0, ruby changed + # this behavior and a call to 'super' from the method copied to @klass + # will call @klass's superclass method, which is the original + # implementer of this method! This leads to very strange errors + # if @klass's copied method calls 'super', since it would end up + # calling itself, the original method implemented in @klass's + # superclass. + # + # For ruby 2.3 and above, we need to only restore methods that + # @klass originally owned. + # + # https://github.com/ruby/ruby/commit/c8854d2ca4be9ee6946e6d17b0e17d9ef130ee81 + if RUBY_VERSION < "2.3" || backed_up_method_owner[method_name.to_sym] == self + alias_method method_name, alias_method_name + end + remove_method alias_method_name + end + end + + def remove_dummy_method!(method_name) + @klass.class_exec do + remove_method method_name + end + end + + def backup_method!(method_name) + return unless public_protected_or_private_method_defined?(method_name) + + alias_method_name = build_alias_method_name(method_name) + @backed_up_method_owner[method_name.to_sym] ||= @klass.instance_method(method_name).owner + @klass.class_exec do + alias_method alias_method_name, method_name + end + end + + def public_protected_or_private_method_defined?(method_name) + MethodReference.method_defined_at_any_visibility?(@klass, method_name) + end + + def observe!(method_name) + allow_no_prepended_module_definition_of(method_name) + + if RSpec::Mocks.configuration.verify_partial_doubles? && !Mocks.configuration.temporarily_suppress_partial_double_verification + unless public_protected_or_private_method_defined?(method_name) + AnyInstance.error_generator.raise_does_not_implement_error(@klass, method_name) + end + end + + stop_observing!(method_name) if already_observing?(method_name) + @observed_methods << method_name + backup_method!(method_name) + recorder = self + method_was_private = @klass.private_method_defined?(method_name) + @klass.__send__(:define_method, method_name) do |*args, &blk| + recorder.playback!(self, method_name) + __send__(method_name, *args, &blk) + end + @klass.__send__(:private, method_name) if method_was_private + @klass.__send__(:ruby2_keywords, method_name) if @klass.respond_to?(:ruby2_keywords, true) + end + + def mark_invoked!(method_name) + backup_method!(method_name) + recorder = self + @klass.__send__(:define_method, method_name) do |*_args, &_blk| + invoked_instance = recorder.instance_that_received(method_name) + inspect = "#<#{self.class}:#{object_id} #{instance_variables.map { |name| "#{name}=#{instance_variable_get name}" }.join(', ')}>" + AnyInstance.error_generator.raise_message_already_received_by_other_instance_error( + method_name, inspect, invoked_instance + ) + end + end + + if Support::RubyFeatures.module_prepends_supported? + def allow_no_prepended_module_definition_of(method_name) + prepended_modules = RSpec::Mocks::Proxy.prepended_modules_of(@klass) + problem_mod = prepended_modules.find { |mod| mod.method_defined?(method_name) } + return unless problem_mod + + AnyInstance.error_generator.raise_not_supported_with_prepend_error(method_name, problem_mod) + end + else + def allow_no_prepended_module_definition_of(_method_name) + # nothing to do; prepends aren't supported on this version of ruby + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb new file mode 100644 index 0000000..c4c0ab7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb @@ -0,0 +1,51 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class StubChain < Chain + # @private + def expectation_fulfilled? + true + end + + private + + def create_message_expectation_on(instance) + proxy = ::RSpec::Mocks.space.proxy_for(instance) + method_name, opts = @expectation_args + opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE) + + stub = proxy.add_stub(method_name, opts, &@expectation_block) + @recorder.stubs[stub.message] << stub + + if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks? + stub.and_yield_receiver_to_implementation + end + + stub + end + + InvocationOrder = + { + :and_return => [:with, nil], + :and_raise => [:with, nil], + :and_yield => [:with, :and_yield, nil], + :and_throw => [:with, nil], + :and_call_original => [:with, nil], + :and_wrap_original => [:with, nil] + }.freeze + + EmptyInvocationOrder = {}.freeze + + def invocation_order + InvocationOrder + end + + def verify_invocation_order(rspec_method_name, *_args, &_block) + return if invocation_order.fetch(rspec_method_name, [nil]).include?(last_message) + raise NoMethodError, "Undefined method #{rspec_method_name}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb new file mode 100644 index 0000000..495511c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb @@ -0,0 +1,23 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class StubChainChain < StubChain + def initialize(*args) + super + @expectation_fulfilled = false + end + + private + + def create_message_expectation_on(instance) + ::RSpec::Mocks::StubChain.stub_chain_on(instance, *@expectation_args, &@expectation_block) + end + + def invocation_order + EmptyInvocationOrder + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb new file mode 100644 index 0000000..f8adcd9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb @@ -0,0 +1,117 @@ +# We intentionally do not use the `RSpec::Support.require...` methods +# here so that this file can be loaded individually, as documented +# below. +require 'rspec/mocks/argument_matchers' +require 'rspec/support/fuzzy_matcher' + +module RSpec + module Mocks + # Wrapper for matching arguments against a list of expected values. Used by + # the `with` method on a `MessageExpectation`: + # + # expect(object).to receive(:message).with(:a, 'b', 3) + # object.message(:a, 'b', 3) + # + # Values passed to `with` can be literal values or argument matchers that + # match against the real objects .e.g. + # + # expect(object).to receive(:message).with(hash_including(:a => 'b')) + # + # Can also be used directly to match the contents of any `Array`. This + # enables 3rd party mocking libs to take advantage of rspec's argument + # matching without using the rest of rspec-mocks. + # + # require 'rspec/mocks/argument_list_matcher' + # include RSpec::Mocks::ArgumentMatchers + # + # arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b')) + # arg_list_matcher.args_match?(123, :a => 'b') + # + # This class is immutable. + # + # @see ArgumentMatchers + class ArgumentListMatcher + # @private + attr_reader :expected_args + + # @api public + # @param [Array] expected_args a list of expected literals and/or argument matchers + # + # Initializes an `ArgumentListMatcher` with a collection of literal + # values and/or argument matchers. + # + # @see ArgumentMatchers + # @see #args_match? + def initialize(*expected_args) + @expected_args = expected_args + ensure_expected_args_valid! + end + ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true) + + # @api public + # @param [Array] actual_args + # + # Matches each element in the `expected_args` against the element in the same + # position of the arguments passed to `new`. + # + # @see #initialize + def args_match?(*actual_args) + expected_args = resolve_expected_args_based_on(actual_args) + + return false if expected_args.size != actual_args.size + + if RUBY_VERSION >= "3" + # If the expectation was set with keywords, while the actual method was called with a positional hash argument, they don't match. + # If the expectation was set without keywords, e.g., with({a: 1}), then it fine to call it with either foo(a: 1) or foo({a: 1}). + # This corresponds to Ruby semantics, as if the method was def foo(options). + if Hash === expected_args.last && Hash === actual_args.last + if !Hash.ruby2_keywords_hash?(actual_args.last) && Hash.ruby2_keywords_hash?(expected_args.last) + return false + end + end + end + + Support::FuzzyMatcher.values_match?(expected_args, actual_args) + end + ruby2_keywords :args_match? if respond_to?(:ruby2_keywords, true) + + # @private + # Resolves abstract arg placeholders like `no_args` and `any_args` into + # a more concrete arg list based on the provided `actual_args`. + def resolve_expected_args_based_on(actual_args) + return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args + + any_args_index = expected_args.index { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } + return expected_args unless any_args_index + + replace_any_args_with_splat_of_anything(any_args_index, actual_args.count) + end + + private + + def replace_any_args_with_splat_of_anything(before_count, actual_args_count) + any_args_count = actual_args_count - expected_args.count + 1 + after_count = expected_args.count - before_count - 1 + + any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE } + expected_args.first(before_count) + any_args + expected_args.last(after_count) + end + + def ensure_expected_args_valid! + if expected_args.count { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } > 1 + raise ArgumentError, "`any_args` can only be passed to " \ + "`with` once but you have passed it multiple times." + elsif expected_args.count > 1 && expected_args.any? { |a| ArgumentMatchers::NoArgsMatcher::INSTANCE == a } + raise ArgumentError, "`no_args` can only be passed as a " \ + "singleton argument to `with` (i.e. `with(no_args)`), " \ + "but you have passed additional arguments." + end + end + + # Value that will match all argument lists. + # + # @private + MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb new file mode 100644 index 0000000..5452508 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb @@ -0,0 +1,366 @@ +# This cannot take advantage of our relative requires, since this file is a +# dependency of `rspec/mocks/argument_list_matcher.rb`. See comment there for +# details. +require 'rspec/support/matcher_definition' + +module RSpec + module Mocks + # ArgumentMatchers are placeholders that you can include in message + # expectations to match arguments against a broader check than simple + # equality. + # + # With the exception of `any_args` and `no_args`, they all match against + # the arg in same position in the argument list. + # + # @see ArgumentListMatcher + module ArgumentMatchers + # Acts like an arg splat, matching any number of args at any point in an arg list. + # + # @example + # expect(object).to receive(:message).with(1, 2, any_args) + # + # # matches any of these: + # object.message(1, 2) + # object.message(1, 2, 3) + # object.message(1, 2, 3, 4) + def any_args + AnyArgsMatcher::INSTANCE + end + + # Matches any argument at all. + # + # @example + # expect(object).to receive(:message).with(anything) + def anything + AnyArgMatcher::INSTANCE + end + + # Matches no arguments. + # + # @example + # expect(object).to receive(:message).with(no_args) + def no_args + NoArgsMatcher::INSTANCE + end + + # Matches if the actual argument responds to the specified messages. + # + # @example + # expect(object).to receive(:message).with(duck_type(:hello)) + # expect(object).to receive(:message).with(duck_type(:hello, :goodbye)) + def duck_type(*args) + DuckTypeMatcher.new(*args) + end + + # Matches a boolean value. + # + # @example + # expect(object).to receive(:message).with(boolean()) + def boolean + BooleanMatcher::INSTANCE + end + + # Matches a hash that includes the specified key(s) or key/value pairs. + # Ignores any additional keys. + # + # @example + # expect(object).to receive(:message).with(hash_including(:key => val)) + # expect(object).to receive(:message).with(hash_including(:key)) + # expect(object).to receive(:message).with(hash_including(:key, :key2 => val2)) + def hash_including(*args) + HashIncludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args)) + end + + # Matches a hash that doesn't include the specified key(s) or key/value. + # + # @example + # expect(object).to receive(:message).with(hash_excluding(:key => val)) + # expect(object).to receive(:message).with(hash_excluding(:key)) + # expect(object).to receive(:message).with(hash_excluding(:key, :key2 => :val2)) + def hash_excluding(*args) + HashExcludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args)) + end + + # Matches an array that includes the specified items at least once. + # Ignores duplicates and additional values + # + # @example + # expect(object).to receive(:message).with(array_including(1,2,3)) + # expect(object).to receive(:message).with(array_including([1,2,3])) + def array_including(*args) + actually_an_array = Array === args.first && args.count == 1 ? args.first : args + ArrayIncludingMatcher.new(actually_an_array) + end + + # Matches an array that excludes the specified items. + # + # @example + # expect(object).to receive(:message).with(array_excluding(1,2,3)) + # expect(object).to receive(:message).with(array_excluding([1,2,3])) + def array_excluding(*args) + actually_an_array = Array === args.first && args.count == 1 ? args.first : args + ArrayExcludingMatcher.new(actually_an_array) + end + + alias_method :hash_not_including, :hash_excluding + + # Matches if `arg.instance_of?(klass)` + # + # @example + # expect(object).to receive(:message).with(instance_of(Thing)) + def instance_of(klass) + InstanceOf.new(klass) + end + + alias_method :an_instance_of, :instance_of + + # Matches if `arg.kind_of?(klass)` + # + # @example + # expect(object).to receive(:message).with(kind_of(Thing)) + def kind_of(klass) + KindOf.new(klass) + end + + alias_method :a_kind_of, :kind_of + + # @private + def self.anythingize_lonely_keys(*args) + hash = Hash === args.last ? args.delete_at(-1) : {} + args.each { | arg | hash[arg] = AnyArgMatcher::INSTANCE } + hash + end + + # Intended to be subclassed by stateless, immutable argument matchers. + # Provides a `::INSTANCE` constant for accessing a global + # singleton instance of the matcher. There is no need to construct + # multiple instance since there is no state. It also facilities the + # special case logic we need for some of these matchers, by making it + # easy to do comparisons like: `[klass::INSTANCE] == args` rather than + # `args.count == 1 && klass === args.first`. + # + # @private + class SingletonMatcher + private_class_method :new + + def self.inherited(subklass) + subklass.const_set(:INSTANCE, subklass.send(:new)) + end + end + + # @private + class AnyArgsMatcher < SingletonMatcher + def description + "*(any args)" + end + end + + # @private + class AnyArgMatcher < SingletonMatcher + def ===(_other) + true + end + + def description + "anything" + end + end + + # @private + class NoArgsMatcher < SingletonMatcher + def description + "no args" + end + end + + # @private + class BooleanMatcher < SingletonMatcher + def ===(value) + true == value || false == value + end + + def description + "boolean" + end + end + + # @private + class BaseHashMatcher + def initialize(expected) + @expected = expected + end + + def ===(predicate, actual) + @expected.__send__(predicate) do |k, v| + actual.key?(k) && Support::FuzzyMatcher.values_match?(v, actual[k]) + end + rescue NoMethodError + false + end + + def description(name) + "#{name}(#{formatted_expected_hash.inspect.sub(/^\{/, "").sub(/\}$/, "")})" + end + + private + + def formatted_expected_hash + Hash[ + @expected.map do |k, v| + k = RSpec::Support.rspec_description_for_object(k) + v = RSpec::Support.rspec_description_for_object(v) + + [k, v] + end + ] + end + end + + # @private + class HashIncludingMatcher < BaseHashMatcher + def ===(actual) + super(:all?, actual) + end + + def description + super("hash_including") + end + end + + # @private + class HashExcludingMatcher < BaseHashMatcher + def ===(actual) + super(:none?, actual) + end + + def description + super("hash_not_including") + end + end + + # @private + class ArrayIncludingMatcher + def initialize(expected) + @expected = expected + end + + def ===(actual) + actual = actual.uniq + return true if (actual & @expected).count >= @expected.count + + @expected.uniq.all? do |expected_element| + actual.any? do |actual_element| + RSpec::Support::FuzzyMatcher.values_match?(expected_element, actual_element) + end + end + rescue NoMethodError + false + end + + def description + "array_including(#{formatted_expected_values})" + end + + private + + def formatted_expected_values + @expected.map do |x| + RSpec::Support.rspec_description_for_object(x) + end.join(", ") + end + end + + # @private + class ArrayExcludingMatcher + def initialize(unexpected) + @unexpected = unexpected.uniq + end + + def ===(actual) + actual = actual.uniq + return false unless (actual & @unexpected).empty? + + actual.none? do |actual_element| + @unexpected.any? do |unexpected_element| + RSpec::Support::FuzzyMatcher.values_match?(unexpected_element, actual_element) + end + end + rescue NoMethodError + false + end + + def description + "array_excluding(#{formatted_unexpected_values})" + end + + private + + def formatted_unexpected_values + @unexpected.map do |x| + RSpec::Support.rspec_description_for_object(x) + end.join(", ") + end + end + + # @private + class DuckTypeMatcher + def initialize(*methods_to_respond_to) + @methods_to_respond_to = methods_to_respond_to + end + + def ===(value) + @methods_to_respond_to.all? { |message| value.respond_to?(message) } + end + + def description + "duck_type(#{@methods_to_respond_to.map(&:inspect).join(', ')})" + end + end + + # @private + class InstanceOf + def initialize(klass) + @klass = klass + end + + def ===(actual) + actual.instance_of?(@klass) + end + + def description + "an_instance_of(#{@klass.name})" + end + end + + # @private + class KindOf + def initialize(klass) + @klass = klass + end + + def ===(actual) + actual.kind_of?(@klass) + end + + def description + "kind of #{@klass.name}" + end + end + + matcher_namespace = name + '::' + ::RSpec::Support.register_matcher_definition do |object| + # This is the best we have for now. We should tag all of our matchers + # with a module or something so we can test for it directly. + # + # (Note Module#parent in ActiveSupport is defined in a similar way.) + begin + object.class.name.include?(matcher_namespace) + rescue NoMethodError + # Some objects, like BasicObject, don't implement standard + # reflection methods. + false + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb new file mode 100644 index 0000000..8496bdc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb @@ -0,0 +1,212 @@ +module RSpec + module Mocks + # Provides configuration options for rspec-mocks. + class Configuration + def initialize + @allow_message_expectations_on_nil = nil + @yield_receiver_to_any_instance_implementation_blocks = true + @verify_doubled_constant_names = false + @transfer_nested_constants = false + @verify_partial_doubles = false + @temporarily_suppress_partial_double_verification = false + @color = false + end + + # Sets whether RSpec will warn, ignore, or fail a test when + # expectations are set on nil. + # By default, when this flag is not set, warning messages are issued when + # expectations are set on nil. This is to prevent false-positives and to + # catch potential bugs early on. + # When set to `true`, warning messages are suppressed. + # When set to `false`, it will raise an error. + # + # @example + # RSpec.configure do |config| + # config.mock_with :rspec do |mocks| + # mocks.allow_message_expectations_on_nil = false + # end + # end + attr_accessor :allow_message_expectations_on_nil + + def yield_receiver_to_any_instance_implementation_blocks? + @yield_receiver_to_any_instance_implementation_blocks + end + + # Sets whether or not RSpec will yield the receiving instance of a + # message to blocks that are used for any_instance stub implementations. + # When set, the first yielded argument will be the receiving instance. + # Defaults to `true`. + # + # @example + # RSpec.configure do |rspec| + # rspec.mock_with :rspec do |mocks| + # mocks.yield_receiver_to_any_instance_implementation_blocks = false + # end + # end + attr_writer :yield_receiver_to_any_instance_implementation_blocks + + # Adds `stub` and `should_receive` to the given + # modules or classes. This is usually only necessary + # if you application uses some proxy classes that + # "strip themselves down" to a bare minimum set of + # methods and remove `stub` and `should_receive` in + # the process. + # + # @example + # RSpec.configure do |rspec| + # rspec.mock_with :rspec do |mocks| + # mocks.add_stub_and_should_receive_to Delegator + # end + # end + # + def add_stub_and_should_receive_to(*modules) + modules.each do |mod| + Syntax.enable_should(mod) + end + end + + # Provides the ability to set either `expect`, + # `should` or both syntaxes. RSpec uses `expect` + # syntax by default. This is needed if you want to + # explicitly enable `should` syntax and/or explicitly + # disable `expect` syntax. + # + # @example + # RSpec.configure do |rspec| + # rspec.mock_with :rspec do |mocks| + # mocks.syntax = [:expect, :should] + # end + # end + # + def syntax=(*values) + syntaxes = values.flatten + if syntaxes.include?(:expect) + Syntax.enable_expect + else + Syntax.disable_expect + end + + if syntaxes.include?(:should) + Syntax.enable_should + else + Syntax.disable_should + end + end + + # Returns an array with a list of syntaxes + # that are enabled. + # + # @example + # unless RSpec::Mocks.configuration.syntax.include?(:expect) + # raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax" + # end + # + def syntax + syntaxes = [] + syntaxes << :should if Syntax.should_enabled? + syntaxes << :expect if Syntax.expect_enabled? + syntaxes + end + + def verify_doubled_constant_names? + !!@verify_doubled_constant_names + end + + # When this is set to true, an error will be raised when + # `instance_double` or `class_double` is given the name of an undefined + # constant. You probably only want to set this when running your entire + # test suite, with all production code loaded. Setting this for an + # isolated unit test will prevent you from being able to isolate it! + attr_writer :verify_doubled_constant_names + + # Provides a way to perform customisations when verifying doubles. + # + # @example + # RSpec::Mocks.configuration.before_verifying_doubles do |ref| + # ref.some_method! + # end + def before_verifying_doubles(&block) + verifying_double_callbacks << block + end + alias :when_declaring_verifying_double :before_verifying_doubles + + # @api private + # Returns an array of blocks to call when verifying doubles + def verifying_double_callbacks + @verifying_double_callbacks ||= [] + end + + def transfer_nested_constants? + !!@transfer_nested_constants + end + + # Sets the default for the `transfer_nested_constants` option when + # stubbing constants. + attr_writer :transfer_nested_constants + + # When set to true, partial mocks will be verified the same as object + # doubles. Any stubs will have their arguments checked against the original + # method, and methods that do not exist cannot be stubbed. + def verify_partial_doubles=(val) + @verify_partial_doubles = !!val + end + + def verify_partial_doubles? + @verify_partial_doubles + end + + # @private + # Used to track whether we are temporarily suppressing verifying partial + # doubles with `without_partial_double_verification { ... }` + attr_accessor :temporarily_suppress_partial_double_verification + + if ::RSpec.respond_to?(:configuration) + def color? + ::RSpec.configuration.color_enabled? + end + else + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + attr_writer :color + + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + def color? + @color + end + end + + # Monkey-patch `Marshal.dump` to enable dumping of mocked or stubbed + # objects. By default this will not work since RSpec mocks works by + # adding singleton methods that cannot be serialized. This patch removes + # these singleton methods before serialization. Setting to falsey removes + # the patch. + # + # This method is idempotent. + def patch_marshal_to_support_partial_doubles=(val) + if val + RSpec::Mocks::MarshalExtension.patch! + else + RSpec::Mocks::MarshalExtension.unpatch! + end + end + + # @api private + # Resets the configured syntax to the default. + def reset_syntaxes_to_default + self.syntax = [:should, :expect] + RSpec::Mocks::Syntax.warn_about_should! + end + end + + # Mocks specific configuration, as distinct from `RSpec.configuration` + # which is core RSpec configuration. + def self.configuration + @configuration ||= Configuration.new + end + + configuration.reset_syntaxes_to_default + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb new file mode 100644 index 0000000..44d2e63 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb @@ -0,0 +1,390 @@ +RSpec::Support.require_rspec_support "object_formatter" + +module RSpec + module Mocks + # Raised when a message expectation is not satisfied. + MockExpectationError = Class.new(Exception) + + # Raised when a test double is used after it has been torn + # down (typically at the end of an rspec-core example). + ExpiredTestDoubleError = Class.new(MockExpectationError) + + # Raised when doubles or partial doubles are used outside of the per-test lifecycle. + OutsideOfExampleError = Class.new(StandardError) + + # Raised when an expectation customization method (e.g. `with`, + # `and_return`) is called on a message expectation which has already been + # invoked. + MockExpectationAlreadyInvokedError = Class.new(Exception) + + # Raised for situations that RSpec cannot support due to mutations made + # externally on arguments that RSpec is holding onto to use for later + # comparisons. + # + # @deprecated We no longer raise this error but the constant remains until + # RSpec 4 for SemVer reasons. + CannotSupportArgMutationsError = Class.new(StandardError) + + # @private + UnsupportedMatcherError = Class.new(StandardError) + # @private + NegationUnsupportedError = Class.new(StandardError) + # @private + VerifyingDoubleNotDefinedError = Class.new(StandardError) + + # @private + class ErrorGenerator + attr_writer :opts + + def initialize(target=nil) + @target = target + end + + # @private + def opts + @opts ||= {} + end + + # @private + def raise_unexpected_message_error(message, args) + __raise "#{intro} received unexpected message :#{message} with #{format_args(args)}" + end + + # @private + def raise_unexpected_message_args_error(expectation, args_for_multiple_calls, source_id=nil) + __raise error_message(expectation, args_for_multiple_calls), nil, source_id + end + + # @private + def raise_missing_default_stub_error(expectation, args_for_multiple_calls) + __raise( + error_message(expectation, args_for_multiple_calls) + + "\n Please stub a default value first if message might be received with other args as well. \n" + ) + end + + # @private + def raise_similar_message_args_error(expectation, args_for_multiple_calls, backtrace_line=nil) + __raise error_message(expectation, args_for_multiple_calls), backtrace_line + end + + def default_error_message(expectation, expected_args, actual_args) + "#{intro} received #{expectation.message.inspect} #{unexpected_arguments_message(expected_args, actual_args)}".dup + end + + # rubocop:disable Metrics/ParameterLists + # @private + def raise_expectation_error(message, expected_received_count, argument_list_matcher, + actual_received_count, expectation_count_type, args, + backtrace_line=nil, source_id=nil) + expected_part = expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) + received_part = received_part_of_expectation_error(actual_received_count, args) + __raise "(#{intro(:unwrapped)}).#{message}#{format_args(args)}\n #{expected_part}\n #{received_part}", backtrace_line, source_id + end + # rubocop:enable Metrics/ParameterLists + + # @private + def raise_unimplemented_error(doubled_module, method_name, object) + message = case object + when InstanceVerifyingDouble + "the %s class does not implement the instance method: %s".dup << + if ObjectMethodReference.for(doubled_module, method_name).implemented? + ". Perhaps you meant to use `class_double` instead?" + else + "" + end + when ClassVerifyingDouble + "the %s class does not implement the class method: %s".dup << + if InstanceMethodReference.for(doubled_module, method_name).implemented? + ". Perhaps you meant to use `instance_double` instead?" + else + "" + end + else + "%s does not implement: %s" + end + + __raise message % [doubled_module.description, method_name] + end + + # @private + def raise_non_public_error(method_name, visibility) + raise NoMethodError, "%s method `%s' called on %s" % [ + visibility, method_name, intro + ] + end + + # @private + def raise_invalid_arguments_error(verifier) + __raise verifier.error_message + end + + # @private + def raise_expired_test_double_error + raise ExpiredTestDoubleError, + "#{intro} was originally created in one example but has leaked into " \ + "another example and can no longer be used. rspec-mocks' doubles are " \ + "designed to only last for one example, and you need to create a new " \ + "one in each example you wish to use it for." + end + + # @private + def describe_expectation(verb, message, expected_received_count, _actual_received_count, args) + "#{verb} #{message}#{format_args(args)} #{count_message(expected_received_count)}" + end + + # @private + def raise_out_of_order_error(message) + __raise "#{intro} received :#{message} out of order" + end + + # @private + def raise_missing_block_error(args_to_yield) + __raise "#{intro} asked to yield |#{arg_list(args_to_yield)}| but no block was passed" + end + + # @private + def raise_wrong_arity_error(args_to_yield, signature) + __raise "#{intro} yielded |#{arg_list(args_to_yield)}| to block with #{signature.description}" + end + + # @private + def raise_only_valid_on_a_partial_double(method) + __raise "#{intro} is a pure test double. `#{method}` is only " \ + "available on a partial double." + end + + # @private + def raise_expectation_on_unstubbed_method(method) + __raise "#{intro} expected to have received #{method}, but that " \ + "object is not a spy or method has not been stubbed." + end + + # @private + def raise_expectation_on_mocked_method(method) + __raise "#{intro} expected to have received #{method}, but that " \ + "method has been mocked instead of stubbed or spied." + end + + # @private + def raise_double_negation_error(wrapped_expression) + __raise "Isn't life confusing enough? You've already set a " \ + "negative message expectation and now you are trying to " \ + "negate it again with `never`. What does an expression like " \ + "`#{wrapped_expression}.not_to receive(:msg).never` even mean?" + end + + # @private + def raise_verifying_double_not_defined_error(ref) + notify(VerifyingDoubleNotDefinedError.new( + "#{ref.description.inspect} is not a defined constant. " \ + "Perhaps you misspelt it? " \ + "Disable check with `verify_doubled_constant_names` configuration option." + )) + end + + # @private + def raise_have_received_disallowed(type, reason) + __raise "Using #{type}(...) with the `have_received` " \ + "matcher is not supported#{reason}." + end + + # @private + def raise_cant_constrain_count_for_negated_have_received_error(count_constraint) + __raise "can't use #{count_constraint} when negative" + end + + # @private + def raise_method_not_stubbed_error(method_name) + __raise "The method `#{method_name}` was not stubbed or was already unstubbed" + end + + # @private + def raise_already_invoked_error(message, calling_customization) + error_message = "The message expectation for #{intro}.#{message} has already been invoked " \ + "and cannot be modified further (e.g. using `#{calling_customization}`). All message expectation " \ + "customizations must be applied before it is used for the first time." + + notify MockExpectationAlreadyInvokedError.new(error_message) + end + + def raise_expectation_on_nil_error(method_name) + __raise expectation_on_nil_message(method_name) + end + + def expectation_on_nil_message(method_name) + "An expectation of `:#{method_name}` was set on `nil`. " \ + "To allow expectations on `nil` and suppress this message, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `true`. " \ + "To disallow expectations on `nil`, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `false`" + end + + # @private + def intro(unwrapped=false) + case @target + when TestDouble then TestDoubleFormatter.format(@target, unwrapped) + when Class then + formatted = "#{@target.inspect} (class)" + return formatted if unwrapped + "#<#{formatted}>" + when NilClass then "nil" + else @target.inspect + end + end + + # @private + def method_call_args_description(args, generic_prefix=" with arguments: ", matcher_prefix=" with ") + case args.first + when ArgumentMatchers::AnyArgsMatcher then "#{matcher_prefix}any arguments" + when ArgumentMatchers::NoArgsMatcher then "#{matcher_prefix}no arguments" + else + if yield + "#{generic_prefix}#{format_args(args)}" + else + "" + end + end + end + + private + + def received_part_of_expectation_error(actual_received_count, args) + "received: #{count_message(actual_received_count)}" + + method_call_args_description(args) do + actual_received_count > 0 && args.length > 0 + end + end + + def expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) + "expected: #{count_message(expected_received_count, expectation_count_type)}" + + method_call_args_description(argument_list_matcher.expected_args) do + argument_list_matcher.expected_args.length > 0 + end + end + + def unexpected_arguments_message(expected_args_string, actual_args_string) + "with unexpected arguments\n expected: #{expected_args_string}\n got: #{actual_args_string}" + end + + def error_message(expectation, args_for_multiple_calls) + expected_args = format_args(expectation.expected_args) + actual_args = format_received_args(args_for_multiple_calls) + + if RSpec::Support::RubyFeatures.distincts_kw_args_from_positional_hash? + expected_hash = expectation.expected_args.last + actual_hash = args_for_multiple_calls.last.last + if Hash === expected_hash && Hash === actual_hash && + (Hash.ruby2_keywords_hash?(expected_hash) != Hash.ruby2_keywords_hash?(actual_hash)) + + actual_description = Hash.ruby2_keywords_hash?(actual_hash) ? " (keyword arguments)" : " (options hash)" + expected_description = Hash.ruby2_keywords_hash?(expected_hash) ? " (keyword arguments)" : " (options hash)" + + if actual_description != expected_description + actual_args += actual_description + expected_args += expected_description + end + end + end + + message = default_error_message(expectation, expected_args, actual_args) + + if args_for_multiple_calls.one? + diff = diff_message(expectation.expected_args, args_for_multiple_calls.first) + if RSpec::Mocks.configuration.color? + message << "\nDiff:#{diff}" unless diff.gsub(/\e\[\d+m/, '').strip.empty? + else + message << "\nDiff:#{diff}" unless diff.strip.empty? + end + end + + message + end + + def diff_message(expected_args, actual_args) + formatted_expected_args = expected_args.map do |x| + RSpec::Support.rspec_description_for_object(x) + end + + formatted_expected_args, actual_args = unpack_string_args(formatted_expected_args, actual_args) + + differ.diff(actual_args, formatted_expected_args) + end + + def unpack_string_args(formatted_expected_args, actual_args) + if [formatted_expected_args, actual_args].all? { |x| list_of_exactly_one_string?(x) } + [formatted_expected_args.first, actual_args.first] + else + [formatted_expected_args, actual_args] + end + end + + def list_of_exactly_one_string?(args) + Array === args && args.count == 1 && String === args.first + end + + def differ + RSpec::Support::Differ.new(:color => RSpec::Mocks.configuration.color?) + end + + def __raise(message, backtrace_line=nil, source_id=nil) + message = opts[:message] unless opts[:message].nil? + exception = RSpec::Mocks::MockExpectationError.new(message) + prepend_to_backtrace(exception, backtrace_line) if backtrace_line + notify exception, :source_id => source_id + end + + if RSpec::Support::Ruby.jruby? + def prepend_to_backtrace(exception, line) + raise exception + rescue RSpec::Mocks::MockExpectationError => with_backtrace + with_backtrace.backtrace.unshift(line) + end + else + def prepend_to_backtrace(exception, line) + exception.set_backtrace(caller.unshift line) + end + end + + def notify(*args) + RSpec::Support.notify_failure(*args) + end + + def format_args(args) + return "(no args)" if args.empty? + "(#{arg_list(args)})" + end + + def arg_list(args) + args.map { |arg| RSpec::Support::ObjectFormatter.format(arg) }.join(", ") + end + + def format_received_args(args_for_multiple_calls) + grouped_args(args_for_multiple_calls).map do |args_for_one_call, index| + "#{format_args(args_for_one_call)}#{group_count(index, args_for_multiple_calls)}" + end.join("\n ") + end + + def count_message(count, expectation_count_type=nil) + return "at least #{times(count.abs)}" if count < 0 || expectation_count_type == :at_least + return "at most #{times(count)}" if expectation_count_type == :at_most + times(count) + end + + def times(count) + "#{count} time#{'s' unless count == 1}" + end + + def grouped_args(args) + Hash[args.group_by { |x| x }.map { |k, v| [k, v.count] }] + end + + def group_count(index, args) + " (#{times(index)})" if args.size > 1 || index > 1 + end + end + + # @private + def self.error_generator + @error_generator ||= ErrorGenerator.new + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb new file mode 100644 index 0000000..5531b28 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb @@ -0,0 +1,434 @@ +RSpec::Support.require_rspec_mocks 'object_reference' + +module RSpec + module Mocks + # Contains methods intended to be used from within code examples. + # Mix this in to your test context (such as a test framework base class) + # to use rspec-mocks with your test framework. If you're using rspec-core, + # it'll take care of doing this for you. + module ExampleMethods + include RSpec::Mocks::ArgumentMatchers + + # @overload double() + # @overload double(name) + # @param name [String/Symbol] name or description to be used in failure messages + # @overload double(stubs) + # @param stubs (Hash) hash of message/return-value pairs + # @overload double(name, stubs) + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs (Hash) hash of message/return-value pairs + # @return (Double) + # + # Constructs an instance of [RSpec::Mocks::Double](RSpec::Mocks::Double) configured + # with an optional name, used for reporting in failure messages, and an optional + # hash of message/return-value pairs. + # + # @example + # book = double("book", :title => "The RSpec Book") + # book.title #=> "The RSpec Book" + # + # card = double("card", :suit => "Spades", :rank => "A") + # card.suit #=> "Spades" + # card.rank #=> "A" + # + def double(*args) + ExampleMethods.declare_double(Double, *args) + end + + # @overload instance_double(doubled_class) + # @param doubled_class [String, Class] + # @overload instance_double(doubled_class, name) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload instance_double(doubled_class, stubs) + # @param doubled_class [String, Class] + # @param stubs [Hash] hash of message/return-value pairs + # @overload instance_double(doubled_class, name, stubs) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return InstanceVerifyingDouble + # + # Constructs a test double against a specific class. If the given class + # name has been loaded, only instance methods defined on the class are + # allowed to be stubbed. In all other ways it behaves like a + # [double](double). + def instance_double(doubled_class, *args) + ref = ObjectReference.for(doubled_class) + ExampleMethods.declare_verifying_double(InstanceVerifyingDouble, ref, *args) + end + + # @overload class_double(doubled_class) + # @param doubled_class [String, Module] + # @overload class_double(doubled_class, name) + # @param doubled_class [String, Module] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload class_double(doubled_class, stubs) + # @param doubled_class [String, Module] + # @param stubs [Hash] hash of message/return-value pairs + # @overload class_double(doubled_class, name, stubs) + # @param doubled_class [String, Module] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ClassVerifyingDouble + # + # Constructs a test double against a specific class. If the given class + # name has been loaded, only class methods defined on the class are + # allowed to be stubbed. In all other ways it behaves like a + # [double](double). + def class_double(doubled_class, *args) + ref = ObjectReference.for(doubled_class) + ExampleMethods.declare_verifying_double(ClassVerifyingDouble, ref, *args) + end + + # @overload object_double(object_or_name) + # @param object_or_name [String, Object] + # @overload object_double(object_or_name, name) + # @param object_or_name [String, Object] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload object_double(object_or_name, stubs) + # @param object_or_name [String, Object] + # @param stubs [Hash] hash of message/return-value pairs + # @overload object_double(object_or_name, name, stubs) + # @param object_or_name [String, Object] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ObjectVerifyingDouble + # + # Constructs a test double against a specific object. Only the methods + # the object responds to are allowed to be stubbed. If a String argument + # is provided, it is assumed to reference a constant object which is used + # for verification. In all other ways it behaves like a [double](double). + def object_double(object_or_name, *args) + ref = ObjectReference.for(object_or_name, :allow_direct_object_refs) + ExampleMethods.declare_verifying_double(ObjectVerifyingDouble, ref, *args) + end + + # @overload spy() + # @overload spy(name) + # @param name [String/Symbol] name or description to be used in failure messages + # @overload spy(stubs) + # @param stubs (Hash) hash of message/return-value pairs + # @overload spy(name, stubs) + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs (Hash) hash of message/return-value pairs + # @return (Double) + # + # Constructs a test double that is optimized for use with + # `have_received`. With a normal double one has to stub methods in order + # to be able to spy them. A spy automatically spies on all methods. + def spy(*args) + double(*args).as_null_object + end + + # @overload instance_spy(doubled_class) + # @param doubled_class [String, Class] + # @overload instance_spy(doubled_class, name) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload instance_spy(doubled_class, stubs) + # @param doubled_class [String, Class] + # @param stubs [Hash] hash of message/return-value pairs + # @overload instance_spy(doubled_class, name, stubs) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return InstanceVerifyingDouble + # + # Constructs a test double that is optimized for use with `have_received` + # against a specific class. If the given class name has been loaded, only + # instance methods defined on the class are allowed to be stubbed. With + # a normal double one has to stub methods in order to be able to spy + # them. An instance_spy automatically spies on all instance methods to + # which the class responds. + def instance_spy(*args) + instance_double(*args).as_null_object + end + + # @overload object_spy(object_or_name) + # @param object_or_name [String, Object] + # @overload object_spy(object_or_name, name) + # @param object_or_name [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload object_spy(object_or_name, stubs) + # @param object_or_name [String, Object] + # @param stubs [Hash] hash of message/return-value pairs + # @overload object_spy(object_or_name, name, stubs) + # @param object_or_name [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ObjectVerifyingDouble + # + # Constructs a test double that is optimized for use with `have_received` + # against a specific object. Only instance methods defined on the object + # are allowed to be stubbed. With a normal double one has to stub + # methods in order to be able to spy them. An object_spy automatically + # spies on all methods to which the object responds. + def object_spy(*args) + object_double(*args).as_null_object + end + + # @overload class_spy(doubled_class) + # @param doubled_class [String, Module] + # @overload class_spy(doubled_class, name) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload class_spy(doubled_class, stubs) + # @param doubled_class [String, Module] + # @param stubs [Hash] hash of message/return-value pairs + # @overload class_spy(doubled_class, name, stubs) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ClassVerifyingDouble + # + # Constructs a test double that is optimized for use with `have_received` + # against a specific class. If the given class name has been loaded, + # only class methods defined on the class are allowed to be stubbed. + # With a normal double one has to stub methods in order to be able to spy + # them. An class_spy automatically spies on all class methods to which the + # class responds. + def class_spy(*args) + class_double(*args).as_null_object + end + + # Disables warning messages about expectations being set on nil. + # + # By default warning messages are issued when expectations are set on + # nil. This is to prevent false-positives and to catch potential bugs + # early on. + # @deprecated Use {RSpec::Mocks::Configuration#allow_message_expectations_on_nil} instead. + def allow_message_expectations_on_nil + RSpec::Mocks.space.proxy_for(nil).warn_about_expectations = false + end + + # Stubs the named constant with the given value. + # Like method stubs, the constant will be restored + # to its original value (or lack of one, if it was + # undefined) when the example completes. + # + # @param constant_name [String] The fully qualified name of the constant. The current + # constant scoping at the point of call is not considered. + # @param value [Object] The value to make the constant refer to. When the + # example completes, the constant will be restored to its prior state. + # @param options [Hash] Stubbing options. + # @option options :transfer_nested_constants [Boolean, Array] Determines + # what nested constants, if any, will be transferred from the original value + # of the constant to the new value of the constant. This only works if both + # the original and new values are modules (or classes). + # @return [Object] the stubbed value of the constant + # + # @example + # stub_const("MyClass", Class.new) # => Replaces (or defines) MyClass with a new class object. + # stub_const("SomeModel::PER_PAGE", 5) # => Sets SomeModel::PER_PAGE to 5. + # + # class CardDeck + # SUITS = [:Spades, :Diamonds, :Clubs, :Hearts] + # NUM_CARDS = 52 + # end + # + # stub_const("CardDeck", Class.new) + # CardDeck::SUITS # => uninitialized constant error + # CardDeck::NUM_CARDS # => uninitialized constant error + # + # stub_const("CardDeck", Class.new, :transfer_nested_constants => true) + # CardDeck::SUITS # => our suits array + # CardDeck::NUM_CARDS # => 52 + # + # stub_const("CardDeck", Class.new, :transfer_nested_constants => [:SUITS]) + # CardDeck::SUITS # => our suits array + # CardDeck::NUM_CARDS # => uninitialized constant error + def stub_const(constant_name, value, options={}) + ConstantMutator.stub(constant_name, value, options) + end + + # Hides the named constant with the given value. The constant will be + # undefined for the duration of the test. + # + # Like method stubs, the constant will be restored to its original value + # when the example completes. + # + # @param constant_name [String] The fully qualified name of the constant. + # The current constant scoping at the point of call is not considered. + # + # @example + # hide_const("MyClass") # => MyClass is now an undefined constant + def hide_const(constant_name) + ConstantMutator.hide(constant_name) + end + + # Verifies that the given object received the expected message during the + # course of the test. On a spy objects or as null object doubles this + # works for any method, on other objects the method must have + # been stubbed beforehand in order for messages to be verified. + # + # Stubbing and verifying messages received in this way implements the + # Test Spy pattern. + # + # @param method_name [Symbol] name of the method expected to have been + # called. + # + # @example + # invitation = double('invitation', accept: true) + # user.accept_invitation(invitation) + # expect(invitation).to have_received(:accept) + # + # # You can also use most message expectations: + # expect(invitation).to have_received(:accept).with(mailer).once + # + # @note `have_received(...).with(...)` is unable to work properly when + # passed arguments are mutated after the spy records the received message. + def have_received(method_name, &block) + Matchers::HaveReceived.new(method_name, &block) + end + + # Turns off the verifying of partial doubles for the duration of the + # block, this is useful in situations where methods are defined at run + # time and you wish to define stubs for them but not turn off partial + # doubles for the entire run suite. (e.g. view specs in rspec-rails). + def without_partial_double_verification + original_state = Mocks.configuration.temporarily_suppress_partial_double_verification + Mocks.configuration.temporarily_suppress_partial_double_verification = true + yield + ensure + Mocks.configuration.temporarily_suppress_partial_double_verification = original_state + end + + # @method expect + # Used to wrap an object in preparation for setting a mock expectation + # on it. + # + # @example + # expect(obj).to receive(:foo).with(5).and_return(:return_value) + # + # @note This method is usually provided by rspec-expectations. However, + # if you use rspec-mocks without rspec-expectations, there's a definition + # of it that is made available here. If you disable the `:expect` syntax + # this method will be undefined. + + # @method allow + # Used to wrap an object in preparation for stubbing a method + # on it. + # + # @example + # allow(dbl).to receive(:foo).with(5).and_return(:return_value) + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method expect_any_instance_of + # Used to wrap a class in preparation for setting a mock expectation + # on instances of it. + # + # @example + # expect_any_instance_of(MyClass).to receive(:foo) + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method allow_any_instance_of + # Used to wrap a class in preparation for stubbing a method + # on instances of it. + # + # @example + # allow_any_instance_of(MyClass).to receive(:foo) + # + # @note This is only available when you have enabled the `expect` syntax. + + # @method receive + # Used to specify a message that you expect or allow an object + # to receive. The object returned by `receive` supports the same + # fluent interface that `should_receive` and `stub` have always + # supported, allowing you to constrain the arguments or number of + # times, and configure how the object should respond to the message. + # + # @example + # expect(obj).to receive(:hello).with("world").exactly(3).times + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method receive_messages + # Shorthand syntax used to setup message(s), and their return value(s), + # that you expect or allow an object to receive. The method takes a hash + # of messages and their respective return values. Unlike with `receive`, + # you cannot apply further customizations using a block or the fluent + # interface. + # + # @example + # allow(obj).to receive_messages(:speak => "Hello World") + # allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow") + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method receive_message_chain + # @overload receive_message_chain(method1, method2) + # @overload receive_message_chain("method1.method2") + # @overload receive_message_chain(method1, method_to_value_hash) + # + # stubs/mocks a chain of messages on an object or test double. + # + # ## Warning: + # + # Chains can be arbitrarily long, which makes it quite painless to + # violate the Law of Demeter in violent ways, so you should consider any + # use of `receive_message_chain` a code smell. Even though not all code smells + # indicate real problems (think fluent interfaces), `receive_message_chain` still + # results in brittle examples. For example, if you write + # `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the + # implementation calls `foo.baz.bar`, the stub will not work. + # + # @example + # allow(double).to receive_message_chain("foo.bar") { :baz } + # allow(double).to receive_message_chain(:foo, :bar => :baz) + # allow(double).to receive_message_chain(:foo, :bar) { :baz } + # + # # Given any of ^^ these three forms ^^: + # double.foo.bar # => :baz + # + # # Common use in Rails/ActiveRecord: + # allow(Article).to receive_message_chain("recent.published") { [Article.new] } + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @private + def self.included(klass) + klass.class_exec do + # This gets mixed in so that if `RSpec::Matchers` is included in + # `klass` later, its definition of `expect` will take precedence. + include ExpectHost unless method_defined?(:expect) + end + end + + # @private + def self.extended(object) + # This gets extended in so that if `RSpec::Matchers` is included in + # `klass` later, its definition of `expect` will take precedence. + object.extend ExpectHost unless object.respond_to?(:expect) + end + + # @private + def self.declare_verifying_double(type, ref, *args) + if RSpec::Mocks.configuration.verify_doubled_constant_names? && + !ref.defined? + + RSpec::Mocks.error_generator.raise_verifying_double_not_defined_error(ref) + end + + RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| + block.call(ref) + end + + declare_double(type, ref, *args) + end + + # @private + def self.declare_double(type, *args) + args << {} unless Hash === args.last + type.new(*args) + end + + # This module exists to host the `expect` method for cases where + # rspec-mocks is used w/o rspec-expectations. + module ExpectHost + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb new file mode 100644 index 0000000..12edec2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb @@ -0,0 +1,146 @@ +module RSpec + module Mocks + # @private + class InstanceMethodStasher + def initialize(object, method) + @object = object + @method = method + @klass = (class << object; self; end) + + @original_method = nil + @method_is_stashed = false + end + + attr_reader :original_method + + if RUBY_VERSION.to_f < 1.9 + # @private + def method_is_stashed? + @method_is_stashed + end + + # @private + def stash + return if !method_defined_directly_on_klass? || @method_is_stashed + + @klass.__send__(:alias_method, stashed_method_name, @method) + @method_is_stashed = true + end + + # @private + def stashed_method_name + "obfuscated_by_rspec_mocks__#{@method}" + end + + # @private + def restore + return unless @method_is_stashed + + if @klass.__send__(:method_defined?, @method) + @klass.__send__(:undef_method, @method) + end + @klass.__send__(:alias_method, @method, stashed_method_name) + @klass.__send__(:remove_method, stashed_method_name) + @method_is_stashed = false + end + else + + # @private + def method_is_stashed? + !!@original_method + end + + # @private + def stash + return unless method_defined_directly_on_klass? + @original_method ||= ::RSpec::Support.method_handle_for(@object, @method) + @klass.__send__(:undef_method, @method) + end + + # @private + def restore + return unless @original_method + + if @klass.__send__(:method_defined?, @method) + @klass.__send__(:undef_method, @method) + end + + handle_restoration_failures do + @klass.__send__(:define_method, @method, @original_method) + end + + @original_method = nil + end + end + + if RUBY_DESCRIPTION.include?('2.0.0p247') || RUBY_DESCRIPTION.include?('2.0.0p195') + # ruby 2.0.0-p247 and 2.0.0-p195 both have a bug that we can't work around :(. + # https://bugs.ruby-lang.org/issues/8686 + def handle_restoration_failures + yield + rescue TypeError + RSpec.warn_with( + "RSpec failed to properly restore a partial double (#{@object.inspect}) " \ + "to its original state due to a known bug in MRI 2.0.0-p195 & p247 " \ + "(https://bugs.ruby-lang.org/issues/8686). This object may remain " \ + "screwed up for the rest of this process. Please upgrade to 2.0.0-p353 or above.", + :call_site => nil, :use_spec_location_as_call_site => true + ) + end + else + def handle_restoration_failures + # No known reasons for restoration to fail on other rubies. + yield + end + end + + private + + # @private + def method_defined_directly_on_klass? + method_defined_on_klass? && method_owned_by_klass? + end + + # @private + def method_defined_on_klass?(klass=@klass) + MethodReference.method_defined_at_any_visibility?(klass, @method) + end + + def method_owned_by_klass? + owner = @klass.instance_method(@method).owner + + # On Ruby 2.0.0+ the owner of a method on a class which has been + # `prepend`ed may actually be an instance, e.g. + # `#`, rather than the expected `MyClass`. + owner = owner.class unless Module === owner + + # On some 1.9s (e.g. rubinius) aliased methods + # can report the wrong owner. Example: + # class MyClass + # class << self + # alias alternate_new new + # end + # end + # + # MyClass.owner(:alternate_new) returns `Class` when incorrect, + # but we need to consider the owner to be `MyClass` because + # it is not actually available on `Class` but is on `MyClass`. + # Hence, we verify that the owner actually has the method defined. + # If the given owner does not have the method defined, we assume + # that the method is actually owned by @klass. + # + # On 1.8, aliased methods can also report the wrong owner. Example: + # module M + # def a; end + # module_function :a + # alias b a + # module_function :b + # end + # The owner of M.b is the raw Module object, instead of the expected + # singleton class of the module + return true if RUBY_VERSION < '1.9' && owner == @object + owner == @klass || !(method_defined_on_klass?(owner)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb new file mode 100644 index 0000000..cfa9c1a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb @@ -0,0 +1,41 @@ +module RSpec + module Mocks + # Support for `patch_marshal_to_support_partial_doubles` configuration. + # + # @private + class MarshalExtension + def self.patch! + return if Marshal.respond_to?(:dump_with_rspec_mocks) + + Marshal.instance_eval do + class << self + def dump_with_rspec_mocks(object, *rest) + if !::RSpec::Mocks.space.registered?(object) || NilClass === object + dump_without_rspec_mocks(object, *rest) + else + dump_without_rspec_mocks(object.dup, *rest) + end + end + + alias_method :dump_without_rspec_mocks, :dump + undef_method :dump + alias_method :dump, :dump_with_rspec_mocks + end + end + end + + def self.unpatch! + return unless Marshal.respond_to?(:dump_with_rspec_mocks) + + Marshal.instance_eval do + class << self + undef_method :dump_with_rspec_mocks + undef_method :dump + alias_method :dump, :dump_without_rspec_mocks + undef_method :dump_without_rspec_mocks + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb new file mode 100644 index 0000000..81e6427 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb @@ -0,0 +1,20 @@ +module RSpec + module Mocks + module Matchers + # @private + class ExpectationCustomization + attr_accessor :block + + def initialize(method_name, args, block) + @method_name = method_name + @args = args + @block = block + end + + def playback_onto(expectation) + expectation.__send__(@method_name, *@args, &@block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb new file mode 100644 index 0000000..cf4852b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb @@ -0,0 +1,134 @@ +module RSpec + module Mocks + module Matchers + # @private + class HaveReceived + include Matcher + + COUNT_CONSTRAINTS = %w[exactly at_least at_most times time once twice thrice] + ARGS_CONSTRAINTS = %w[with] + CONSTRAINTS = COUNT_CONSTRAINTS + ARGS_CONSTRAINTS + %w[ordered] + + def initialize(method_name, &block) + @method_name = method_name + @block = block + @constraints = [] + @subject = nil + end + + def matcher_name + "have_received" + end + + def matches?(subject, &block) + @block ||= block + @subject = subject + @expectation = expect + mock_proxy.ensure_implemented(@method_name) + + expected_messages_received_in_order? + end + + def does_not_match?(subject) + @subject = subject + ensure_count_unconstrained + @expectation = expect.never + mock_proxy.ensure_implemented(@method_name) + expected_messages_received_in_order? + end + + def failure_message + capture_failure_message + end + + def failure_message_when_negated + capture_failure_message + end + + def description + (@expectation ||= expect).description_for("have received") + end + + CONSTRAINTS.each do |expectation| + define_method expectation do |*args| + @constraints << [expectation, *args] + self + end + end + + def setup_expectation(subject, &block) + notify_failure_message unless matches?(subject, &block) + end + + def setup_negative_expectation(subject, &block) + notify_failure_message unless does_not_match?(subject, &block) + end + + def setup_allowance(_subject, &_block) + disallow("allow", " as it would have no effect") + end + + def setup_any_instance_allowance(_subject, &_block) + disallow("allow_any_instance_of") + end + + def setup_any_instance_expectation(_subject, &_block) + disallow("expect_any_instance_of") + end + + def setup_any_instance_negative_expectation(_subject, &_block) + disallow("expect_any_instance_of") + end + + private + + def disallow(type, reason="") + RSpec::Mocks.error_generator.raise_have_received_disallowed(type, reason) + end + + def expect + expectation = mock_proxy.build_expectation(@method_name) + apply_constraints_to expectation + expectation + end + + def apply_constraints_to(expectation) + @constraints.each do |constraint| + expectation.send(*constraint) + end + end + + def ensure_count_unconstrained + return unless count_constraint + RSpec::Mocks.error_generator.raise_cant_constrain_count_for_negated_have_received_error(count_constraint) + end + + def count_constraint + @constraints.map(&:first).find do |constraint| + COUNT_CONSTRAINTS.include?(constraint) + end + end + + def capture_failure_message + RSpec::Support.with_failure_notifier(Proc.new { |err, _opt| return err.message }) do + notify_failure_message + end + end + + def notify_failure_message + mock_proxy.check_for_unexpected_arguments(@expectation) + @expectation.generate_error + end + + def expected_messages_received_in_order? + mock_proxy.replay_received_message_on @expectation, &@block + @expectation.expected_messages_received? && @expectation.ensure_expected_ordering_received! + end + + def mock_proxy + RSpec::Mocks.space.proxy_for(@subject) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb new file mode 100644 index 0000000..ee95830 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb @@ -0,0 +1,134 @@ +RSpec::Support.require_rspec_mocks 'matchers/expectation_customization' + +module RSpec + module Mocks + module Matchers + # @private + class Receive + include Matcher + + def initialize(message, block) + @message = message + @block = block + @recorded_customizations = [] + end + + def matcher_name + "receive" + end + + def description + describable.description_for("receive") + end + + def setup_expectation(subject, &block) + warn_if_any_instance("expect", subject) + @describable = setup_mock_proxy_method_substitute(subject, :add_message_expectation, block) + end + alias matches? setup_expectation + + def setup_negative_expectation(subject, &block) + # ensure `never` goes first for cases like `never.and_return(5)`, + # where `and_return` is meant to raise an error + @recorded_customizations.unshift ExpectationCustomization.new(:never, [], nil) + + warn_if_any_instance("expect", subject) + + setup_expectation(subject, &block) + end + alias does_not_match? setup_negative_expectation + + def setup_allowance(subject, &block) + warn_if_any_instance("allow", subject) + setup_mock_proxy_method_substitute(subject, :add_stub, block) + end + + def setup_any_instance_expectation(subject, &block) + setup_any_instance_method_substitute(subject, :should_receive, block) + end + + def setup_any_instance_negative_expectation(subject, &block) + setup_any_instance_method_substitute(subject, :should_not_receive, block) + end + + def setup_any_instance_allowance(subject, &block) + setup_any_instance_method_substitute(subject, :stub, block) + end + + own_methods = (instance_methods - superclass.instance_methods) + MessageExpectation.public_instance_methods(false).each do |method| + next if own_methods.include?(method) + + define_method(method) do |*args, &block| + @recorded_customizations << ExpectationCustomization.new(method, args, block) + self + end + ruby2_keywords(method) if respond_to?(:ruby2_keywords, true) + end + + private + + def describable + @describable ||= DefaultDescribable.new(@message) + end + + def warn_if_any_instance(expression, subject) + return unless AnyInstance::Proxy === subject + + RSpec.warning( + "`#{expression}(#{subject.klass}.any_instance).to` " \ + "is probably not what you meant, it does not operate on " \ + "any instance of `#{subject.klass}`. " \ + "Use `#{expression}_any_instance_of(#{subject.klass}).to` instead." + ) + end + + def setup_mock_proxy_method_substitute(subject, method, block) + proxy = ::RSpec::Mocks.space.proxy_for(subject) + setup_method_substitute(proxy, method, block) + end + + def setup_any_instance_method_substitute(subject, method, block) + proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) + setup_method_substitute(proxy, method, block) + end + + def setup_method_substitute(host, method, block, *args) + args << @message.to_sym + block = move_block_to_last_customization(block) + + expectation = host.__send__(method, *args, &(@block || block)) + + @recorded_customizations.each do |customization| + customization.playback_onto(expectation) + end + expectation + end + + def move_block_to_last_customization(block) + last = @recorded_customizations.last + return block unless last + + last.block ||= block + nil + end + + # MessageExpectation objects are able to describe themselves in detail. + # We use this as a fall back when a MessageExpectation is not available. + # @private + class DefaultDescribable + def initialize(message) + @message = message + end + + # This is much simpler for the `any_instance` case than what the + # user may want, but I'm not up for putting a bunch of effort + # into full descriptions for `any_instance` expectations at this point :(. + def description_for(verb) + "#{verb} #{@message}" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb new file mode 100644 index 0000000..fdc89f9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb @@ -0,0 +1,82 @@ +RSpec::Support.require_rspec_mocks 'matchers/expectation_customization' + +module RSpec + module Mocks + module Matchers + # @private + class ReceiveMessageChain + include Matcher + + def initialize(chain, &block) + @chain = chain + @block = block + @recorded_customizations = [] + end + + [:with, :and_return, :and_invoke, :and_throw, :and_raise, :and_yield, :and_call_original].each do |msg| + define_method(msg) do |*args, &block| + @recorded_customizations << ExpectationCustomization.new(msg, args, block) + self + end + end + + def matcher_name + "receive_message_chain" + end + + def description + "receive message chain #{formatted_chain}" + end + + def setup_allowance(subject, &block) + chain = StubChain.stub_chain_on(subject, *@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_any_instance_allowance(subject, &block) + proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) + chain = proxy.stub_chain(*@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_any_instance_expectation(subject, &block) + proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) + chain = proxy.expect_chain(*@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_expectation(subject, &block) + chain = ExpectChain.expect_chain_on(subject, *@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_negative_expectation(*_args) + raise NegationUnsupportedError, + "`expect(...).not_to receive_message_chain` is not supported " \ + "since it doesn't really make sense. What would it even mean?" + end + + alias matches? setup_expectation + alias does_not_match? setup_negative_expectation + + private + + def replay_customizations(chain) + @recorded_customizations.each do |customization| + customization.playback_onto(chain) + end + end + + def formatted_chain + @formatted_chain ||= @chain.map do |part| + if Hash === part + part.keys.first.to_s + else + part.to_s + end + end.join(".") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb new file mode 100644 index 0000000..6bf9047 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb @@ -0,0 +1,77 @@ +module RSpec + module Mocks + module Matchers + # @private + class ReceiveMessages + include Matcher + + def initialize(message_return_value_hash) + @message_return_value_hash = message_return_value_hash + @backtrace_line = CallerFilter.first_non_rspec_line + end + + def matcher_name + "receive_messages" + end + + def description + "receive messages: #{@message_return_value_hash.inspect}" + end + + def setup_expectation(subject) + warn_about_block if block_given? + each_message_on(proxy_on(subject)) do |host, message, return_value| + host.add_simple_expectation(message, return_value, @backtrace_line) + end + end + alias matches? setup_expectation + + def setup_negative_expectation(_subject) + raise NegationUnsupportedError, + "`expect(...).to_not receive_messages` is not supported since it " \ + "doesn't really make sense. What would it even mean?" + end + alias does_not_match? setup_negative_expectation + + def setup_allowance(subject) + warn_about_block if block_given? + each_message_on(proxy_on(subject)) do |host, message, return_value| + host.add_simple_stub(message, return_value) + end + end + + def setup_any_instance_expectation(subject) + warn_about_block if block_given? + each_message_on(any_instance_of(subject)) do |host, message, return_value| + host.should_receive(message).and_return(return_value) + end + end + + def setup_any_instance_allowance(subject) + warn_about_block if block_given? + any_instance_of(subject).stub(@message_return_value_hash) + end + + def warn_about_block + raise "Implementation blocks aren't supported with `receive_messages`" + end + + private + + def proxy_on(subject) + ::RSpec::Mocks.space.proxy_for(subject) + end + + def any_instance_of(subject) + ::RSpec::Mocks.space.any_instance_proxy_for(subject) + end + + def each_message_on(host) + @message_return_value_hash.each do |message, value| + yield host, message, value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb new file mode 100644 index 0000000..907d14b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb @@ -0,0 +1,87 @@ +module RSpec + module Mocks + # @private + class MessageChain + attr_reader :object, :chain, :block + + def initialize(object, *chain, &blk) + @object = object + @chain, @block = format_chain(*chain, &blk) + end + + # @api private + def setup_chain + if chain.length > 1 + if (matching_stub = find_matching_stub) + chain.shift + chain_on(matching_stub.invoke(nil), *chain, &@block) + elsif (matching_expectation = find_matching_expectation) + chain.shift + chain_on(matching_expectation.invoke_without_incrementing_received_count(nil), *chain, &@block) + else + next_in_chain = Double.new + expectation(object, chain.shift) { next_in_chain } + chain_on(next_in_chain, *chain, &@block) + end + else + expectation(object, chain.shift, &@block) + end + end + + private + + def chain_on(object, *chain, &block) + initialize(object, *chain, &block) + setup_chain + end + + def format_chain(*chain, &blk) + if Hash === chain.last + hash = chain.pop + hash.each do |k, v| + chain << k + blk = Proc.new { v } + end + end + return chain.join('.').split('.'), blk + end + + def find_matching_stub + ::RSpec::Mocks.space.proxy_for(object). + __send__(:find_matching_method_stub, chain.first.to_sym) + end + + def find_matching_expectation + ::RSpec::Mocks.space.proxy_for(object). + __send__(:find_matching_expectation, chain.first.to_sym) + end + end + + # @private + class ExpectChain < MessageChain + # @api private + def self.expect_chain_on(object, *chain, &blk) + new(object, *chain, &blk).setup_chain + end + + private + + def expectation(object, message, &return_block) + ::RSpec::Mocks.expect_message(object, message, {}, &return_block) + end + end + + # @private + class StubChain < MessageChain + def self.stub_chain_on(object, *chain, &blk) + new(object, *chain, &blk).setup_chain + end + + private + + def expectation(object, message, &return_block) + ::RSpec::Mocks.allow_message(object, message, {}, &return_block) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb new file mode 100644 index 0000000..a478db7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb @@ -0,0 +1,856 @@ +RSpec::Support.require_rspec_support 'mutex' + +module RSpec + module Mocks + # A message expectation that only allows concrete return values to be set + # for a message. While this same effect can be achieved using a standard + # MessageExpectation, this version is much faster and so can be used as an + # optimization. + # + # @private + class SimpleMessageExpectation + def initialize(message, response, error_generator, backtrace_line=nil) + @message, @response, @error_generator, @backtrace_line = message.to_sym, response, error_generator, backtrace_line + @received = false + end + + def invoke(*_) + @received = true + @response + end + + def matches?(message, *_) + @message == message.to_sym + end + + def called_max_times? + false + end + + def verify_messages_received + return if @received + @error_generator.raise_expectation_error( + @message, 1, ArgumentListMatcher::MATCH_ALL, 0, nil, [], @backtrace_line + ) + end + + def unadvise(_) + end + end + + # Represents an individual method stub or message expectation. The methods + # defined here can be used to configure how it behaves. The methods return + # `self` so that they can be chained together to form a fluent interface. + class MessageExpectation + # @!group Configuring Responses + + # @overload and_return(value) + # @overload and_return(first_value, second_value) + # + # Tells the object to return a value when it receives the message. Given + # more than one value, the first value is returned the first time the + # message is received, the second value is returned the next time, etc, + # etc. + # + # If the message is received more times than there are values, the last + # value is returned for every subsequent call. + # + # @return [nil] No further chaining is supported after this. + # @example + # allow(counter).to receive(:count).and_return(1) + # counter.count # => 1 + # counter.count # => 1 + # + # allow(counter).to receive(:count).and_return(1,2,3) + # counter.count # => 1 + # counter.count # => 2 + # counter.count # => 3 + # counter.count # => 3 + # counter.count # => 3 + # # etc + def and_return(first_value, *values, &_block) + raise_already_invoked_error_if_necessary(__method__) + if negative? + raise "`and_return` is not supported with negative message expectations" + end + + if block_given? + raise ArgumentError, "Implementation blocks aren't supported with `and_return`" + end + + values.unshift(first_value) + @expected_received_count = [@expected_received_count, values.size].max unless ignoring_args? || (@expected_received_count == 0 && @at_least) + self.terminal_implementation_action = AndReturnImplementation.new(values) + + nil + end + + # Tells the object to invoke a Proc when it receives the message. Given + # more than one value, the result of the first Proc is returned the first + # time the message is received, the result of the second Proc is returned + # the next time, etc, etc. + # + # If the message is received more times than there are Procs, the result of + # the last Proc is returned for every subsequent call. + # + # @return [nil] No further chaining is supported after this. + # @example + # allow(api).to receive(:get_foo).and_invoke(-> { raise ApiTimeout }) + # api.get_foo # => raises ApiTimeout + # api.get_foo # => raises ApiTimeout + # + # allow(api).to receive(:get_foo).and_invoke(-> { raise ApiTimeout }, -> { raise ApiTimeout }, -> { :a_foo }) + # api.get_foo # => raises ApiTimeout + # api.get_foo # => raises ApiTimeout + # api.get_foo # => :a_foo + # api.get_foo # => :a_foo + # api.get_foo # => :a_foo + # # etc + def and_invoke(first_proc, *procs, &_block) + raise_already_invoked_error_if_necessary(__method__) + if negative? + raise "`and_invoke` is not supported with negative message expectations" + end + + if block_given? + raise ArgumentError, "Implementation blocks aren't supported with `and_invoke`" + end + + procs.unshift(first_proc) + if procs.any? { |p| !p.respond_to?(:call) } + raise ArgumentError, "Arguments to `and_invoke` must be callable." + end + + @expected_received_count = [@expected_received_count, procs.size].max unless ignoring_args? || (@expected_received_count == 0 && @at_least) + self.terminal_implementation_action = AndInvokeImplementation.new(procs) + + nil + end + + # Tells the object to delegate to the original unmodified method + # when it receives the message. + # + # @note This is only available on partial doubles. + # + # @return [nil] No further chaining is supported after this. + # @example + # expect(counter).to receive(:increment).and_call_original + # original_count = counter.count + # counter.increment + # expect(counter.count).to eq(original_count + 1) + def and_call_original + block = lambda do |original, *args, &b| + original.call(*args, &b) + end + block = block.ruby2_keywords if block.respond_to?(:ruby2_keywords) + + wrap_original(__method__, &block) + end + + # Decorates the stubbed method with the supplied block. The original + # unmodified method is passed to the block along with any method call + # arguments so you can delegate to it, whilst still being able to + # change what args are passed to it and/or change the return value. + # + # @note This is only available on partial doubles. + # + # @return [nil] No further chaining is supported after this. + # @example + # expect(api).to receive(:large_list).and_wrap_original do |original_method, *args, &block| + # original_method.call(*args, &block).first(10) + # end + def and_wrap_original(&block) + wrap_original(__method__, &block) + end + + # @overload and_raise + # @overload and_raise(ExceptionClass) + # @overload and_raise(ExceptionClass, message) + # @overload and_raise(exception_instance) + # + # Tells the object to raise an exception when the message is received. + # + # @return [nil] No further chaining is supported after this. + # @note + # When you pass an exception class, the MessageExpectation will raise + # an instance of it, creating it with `exception` and passing `message` + # if specified. If the exception class initializer requires more than + # one parameters, you must pass in an instance and not the class, + # otherwise this method will raise an ArgumentError exception. + # + # @example + # allow(car).to receive(:go).and_raise + # allow(car).to receive(:go).and_raise(OutOfGas) + # allow(car).to receive(:go).and_raise(OutOfGas, "At least 2 oz of gas needed to drive") + # allow(car).to receive(:go).and_raise(OutOfGas.new(2, :oz)) + def and_raise(*args) + raise_already_invoked_error_if_necessary(__method__) + self.terminal_implementation_action = Proc.new { raise(*args) } + nil + end + + # @overload and_throw(symbol) + # @overload and_throw(symbol, object) + # + # Tells the object to throw a symbol (with the object if that form is + # used) when the message is received. + # + # @return [nil] No further chaining is supported after this. + # @example + # allow(car).to receive(:go).and_throw(:out_of_gas) + # allow(car).to receive(:go).and_throw(:out_of_gas, :level => 0.1) + def and_throw(*args) + raise_already_invoked_error_if_necessary(__method__) + self.terminal_implementation_action = Proc.new { throw(*args) } + nil + end + + # Tells the object to yield one or more args to a block when the message + # is received. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # stream.stub(:open).and_yield(StringIO.new) + def and_yield(*args, &block) + raise_already_invoked_error_if_necessary(__method__) + yield @eval_context = Object.new if block + + # Initialize args to yield now that it's being used, see also: comment + # in constructor. + @args_to_yield ||= [] + + @args_to_yield << args + self.initial_implementation_action = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator) + self + end + # @!endgroup + + # @!group Constraining Receive Counts + + # Constrain a message expectation to be received a specific number of + # times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).exactly(10).times + def exactly(n, &block) + raise_already_invoked_error_if_necessary(__method__) + self.inner_implementation_action = block + set_expected_received_count :exactly, n + self + end + + # Constrain a message expectation to be received at least a specific + # number of times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).at_least(9).times + def at_least(n, &block) + raise_already_invoked_error_if_necessary(__method__) + set_expected_received_count :at_least, n + + if n == 0 + raise "at_least(0) has been removed, use allow(...).to receive(:message) instead" + end + + self.inner_implementation_action = block + + self + end + + # Constrain a message expectation to be received at most a specific + # number of times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).at_most(10).times + def at_most(n, &block) + raise_already_invoked_error_if_necessary(__method__) + self.inner_implementation_action = block + set_expected_received_count :at_most, n + self + end + + # Syntactic sugar for `exactly`, `at_least` and `at_most` + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).exactly(10).times + # expect(dealer).to receive(:deal_card).at_least(10).times + # expect(dealer).to receive(:deal_card).at_most(10).times + def times(&block) + self.inner_implementation_action = block + self + end + alias time times + + # Expect a message not to be received at all. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:stop).never + def never + error_generator.raise_double_negation_error("expect(obj)") if negative? + @expected_received_count = 0 + self + end + + # Expect a message to be received exactly one time. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:go).once + def once(&block) + self.inner_implementation_action = block + set_expected_received_count :exactly, 1 + self + end + + # Expect a message to be received exactly two times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:go).twice + def twice(&block) + self.inner_implementation_action = block + set_expected_received_count :exactly, 2 + self + end + + # Expect a message to be received exactly three times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:go).thrice + def thrice(&block) + self.inner_implementation_action = block + set_expected_received_count :exactly, 3 + self + end + # @!endgroup + + # @!group Other Constraints + + # Constrains a stub or message expectation to invocations with specific + # arguments. + # + # With a stub, if the message might be received with other args as well, + # you should stub a default value first, and then stub or mock the same + # message using `with` to constrain to specific arguments. + # + # A message expectation will fail if the message is received with different + # arguments. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # allow(cart).to receive(:add) { :failure } + # allow(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success } + # cart.add(Book.new(:isbn => 1234567890)) + # # => :failure + # cart.add(Book.new(:isbn => 1934356379)) + # # => :success + # + # expect(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success } + # cart.add(Book.new(:isbn => 1234567890)) + # # => failed expectation + # cart.add(Book.new(:isbn => 1934356379)) + # # => passes + def with(*args, &block) + raise_already_invoked_error_if_necessary(__method__) + if args.empty? + raise ArgumentError, + "`with` must have at least one argument. Use `no_args` matcher to set the expectation of receiving no arguments." + end + + self.inner_implementation_action = block + @argument_list_matcher = ArgumentListMatcher.new(*args) + self + end + ruby2_keywords(:with) if respond_to?(:ruby2_keywords, true) + + # Expect messages to be received in a specific order. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(api).to receive(:prepare).ordered + # expect(api).to receive(:run).ordered + # expect(api).to receive(:finish).ordered + def ordered(&block) + if type == :stub + RSpec.warning( + "`allow(...).to receive(..).ordered` is not supported and will " \ + "have no effect, use `and_return(*ordered_values)` instead." + ) + end + + self.inner_implementation_action = block + additional_expected_calls.times do + @order_group.register(self) + end + @ordered = true + self + end + + # @return [String] a nice representation of the message expectation + def to_s + args_description = error_generator.method_call_args_description(@argument_list_matcher.expected_args, "", "") { true } + args_description = "(#{args_description})" unless args_description.start_with?("(") + "#<#{self.class} #{error_generator.intro}.#{message}#{args_description}>" + end + alias inspect to_s + + # Implementation details is a long module + # rubocop:disable Metrics/ModuleLength + + # @private + # Contains the parts of `MessageExpectation` that aren't part of + # rspec-mocks' public API. The class is very big and could really use + # some collaborators it delegates to for this stuff but for now this was + # the simplest way to split the public from private stuff to make it + # easier to publish the docs for the APIs we want published. + module ImplementationDetails + attr_accessor :error_generator, :implementation + attr_reader :message + attr_reader :orig_object + attr_writer :expected_received_count, :expected_from, :argument_list_matcher + protected :expected_received_count=, :expected_from=, :error_generator=, :implementation= + + # @private + attr_reader :type + + # rubocop:disable Metrics/ParameterLists + def initialize(error_generator, expectation_ordering, expected_from, method_double, + type=:expectation, opts={}, &implementation_block) + @type = type + @error_generator = error_generator + @error_generator.opts = error_generator.opts.merge(opts) + @expected_from = expected_from + @method_double = method_double + @orig_object = @method_double.object + @message = @method_double.method_name + @actual_received_count = 0 + @actual_received_count_write_mutex = Support::Mutex.new + @expected_received_count = type == :expectation ? 1 : :any + @argument_list_matcher = ArgumentListMatcher::MATCH_ALL + @order_group = expectation_ordering + @order_group.register(self) unless type == :stub + @expectation_type = type + @ordered = false + @at_least = @at_most = @exactly = nil + + self.invoking_internals = false + + # Initialized to nil so that we don't allocate an array for every + # mock or stub. See also comment in `and_yield`. + @args_to_yield = nil + @eval_context = nil + @yield_receiver_to_implementation_block = false + + @implementation = Implementation.new + self.inner_implementation_action = implementation_block + end + # rubocop:enable Metrics/ParameterLists + + def expected_args + @argument_list_matcher.expected_args + end + + def and_yield_receiver_to_implementation + @yield_receiver_to_implementation_block = true + self + end + + def yield_receiver_to_implementation_block? + @yield_receiver_to_implementation_block + end + + def matches?(message, *args) + @message == message && @argument_list_matcher.args_match?(*args) + end + ruby2_keywords :matches? if respond_to?(:ruby2_keywords, true) + + def safe_invoke(parent_stub, *args, &block) + invoke_incrementing_actual_calls_by(1, false, parent_stub, *args, &block) + end + ruby2_keywords :safe_invoke if respond_to?(:ruby2_keywords, true) + + def invoke(parent_stub, *args, &block) + if invoking_internals + safe_invoke_without_incrementing_received_count(parent_stub, *args, &block) + else + invoke_incrementing_actual_calls_by(1, true, parent_stub, *args, &block) + end + end + ruby2_keywords :invoke if respond_to?(:ruby2_keywords, true) + + def safe_invoke_without_incrementing_received_count(parent_stub, *args, &block) + invoke_incrementing_actual_calls_by(0, false, parent_stub, *args, &block) + end + ruby2_keywords :safe_invoke_without_incrementing_received_count if respond_to?(:ruby2_keywords, true) + + def invoke_without_incrementing_received_count(parent_stub, *args, &block) + invoke_incrementing_actual_calls_by(0, true, parent_stub, *args, &block) + end + ruby2_keywords :invoke_without_incrementing_received_count if respond_to?(:ruby2_keywords, true) + + def negative? + @expected_received_count == 0 && !@at_least + end + + def called_max_times? + @expected_received_count != :any && + !@at_least && + @expected_received_count > 0 && + @actual_received_count >= @expected_received_count + end + + def matches_name_but_not_args(message, *args) + @message == message && !@argument_list_matcher.args_match?(*args) + end + + def verify_messages_received + return if expected_messages_received? + generate_error + end + + def expected_messages_received? + ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count? + end + + def ensure_expected_ordering_received! + @order_group.verify_invocation_order(self) if @ordered + true + end + + def ignoring_args? + @expected_received_count == :any + end + + def matches_at_least_count? + @at_least && @actual_received_count >= @expected_received_count + end + + def matches_at_most_count? + @at_most && @actual_received_count <= @expected_received_count + end + + def matches_exact_count? + @expected_received_count == @actual_received_count + end + + def similar_messages + @similar_messages ||= [] + end + + def advise(*args) + similar_messages << args + end + + def unadvise(args) + similar_messages.delete_if { |message| args.include?(message) } + end + + def generate_error + if similar_messages.empty? + @error_generator.raise_expectation_error( + @message, @expected_received_count, @argument_list_matcher, + @actual_received_count, expectation_count_type, expected_args, + @expected_from, exception_source_id + ) + else + @error_generator.raise_similar_message_args_error( + self, @similar_messages, @expected_from + ) + end + end + + def raise_unexpected_message_args_error(args_for_multiple_calls) + @error_generator.raise_unexpected_message_args_error(self, args_for_multiple_calls, exception_source_id) + end + + def expectation_count_type + return :at_least if @at_least + return :at_most if @at_most + nil + end + + def description_for(verb) + @error_generator.describe_expectation( + verb, @message, @expected_received_count, + @actual_received_count, expected_args + ) + end + + def raise_out_of_order_error + @error_generator.raise_out_of_order_error @message + end + + def additional_expected_calls + return 0 if @expectation_type == :stub || !@exactly + @expected_received_count - 1 + end + + def ordered? + @ordered + end + + def negative_expectation_for?(message) + @message == message && negative? + end + + def actual_received_count_matters? + @at_least || @at_most || @exactly + end + + def increase_actual_received_count! + @actual_received_count_write_mutex.synchronize do + @actual_received_count += 1 + end + end + + private + + def exception_source_id + @exception_source_id ||= "#{self.class.name} #{__id__}" + end + + def invoking_internals + RSpec::Support.thread_local_data[:"__rspec_#{object_id}_invoking_internals"] + end + + def invoking_internals=(value) + # We clear the key for this rather than setting to false because otherwise the amount of + # thread local data will keep growing over the lifetime of the thread (which is a long + # time on a single threaded spec run e.g standard MRI) + if value + RSpec::Support.thread_local_data[:"__rspec_#{object_id}_invoking_internals"] = true + else + RSpec::Support.thread_local_data.delete(:"__rspec_#{object_id}_invoking_internals") + end + end + + def invoke_incrementing_actual_calls_by(increment, allowed_to_fail, parent_stub, *args, &block) + self.invoking_internals = true + + args.unshift(orig_object) if yield_receiver_to_implementation_block? + + if negative? || (allowed_to_fail && (@exactly || @at_most) && (@actual_received_count == @expected_received_count)) + # args are the args we actually received, @argument_list_matcher is the + # list of args we were expecting + @error_generator.raise_expectation_error( + @message, @expected_received_count, + @argument_list_matcher, + @actual_received_count + increment, + expectation_count_type, args, nil, exception_source_id + ) + end + + @order_group.handle_order_constraint self + + self.invoking_internals = false + + if implementation.present? + implementation.call(*args, &block) + elsif parent_stub + parent_stub.invoke(nil, *args, &block) + end + ensure + self.invoking_internals = false + @actual_received_count_write_mutex.synchronize do + @actual_received_count += increment + end + end + ruby2_keywords :invoke_incrementing_actual_calls_by if respond_to?(:ruby2_keywords, true) + + def has_been_invoked? + @actual_received_count > 0 + end + + def raise_already_invoked_error_if_necessary(calling_customization) + return unless has_been_invoked? + + error_generator.raise_already_invoked_error(message, calling_customization) + end + + def set_expected_received_count(relativity, n) + raise "`count` is not supported with negative message expectations" if negative? + @at_least = (relativity == :at_least) + @at_most = (relativity == :at_most) + @exactly = (relativity == :exactly) + @expected_received_count = case n + when Numeric then n + when :once then 1 + when :twice then 2 + when :thrice then 3 + end + end + + def initial_implementation_action=(action) + implementation.initial_action = action + end + + def inner_implementation_action=(action) + return unless action + warn_about_stub_override if implementation.inner_action + implementation.inner_action = action + end + + def terminal_implementation_action=(action) + implementation.terminal_action = action + end + + def warn_about_stub_override + RSpec.warning( + "You're overriding a previous stub implementation of `#{@message}`. " \ + "Called from #{CallerFilter.first_non_rspec_line}." + ) + end + + def wrap_original(method_name, &block) + if RSpec::Mocks::TestDouble === @method_double.object + @error_generator.raise_only_valid_on_a_partial_double(method_name) + else + warn_about_stub_override if implementation.inner_action + @implementation = AndWrapOriginalImplementation.new(@method_double.original_implementation_callable, block) + @yield_receiver_to_implementation_block = false + end + + nil + end + end + + include ImplementationDetails + end + # rubocop:enable Metrics/ModuleLength + + # Handles the implementation of an `and_yield` declaration. + # @private + class AndYieldImplementation + def initialize(args_to_yield, eval_context, error_generator) + @args_to_yield = args_to_yield + @eval_context = eval_context + @error_generator = error_generator + end + + def call(*_args_to_ignore, &block) + return if @args_to_yield.empty? && @eval_context.nil? + + @error_generator.raise_missing_block_error @args_to_yield unless block + value = nil + block_signature = Support::BlockSignature.new(block) + + @args_to_yield.each do |args| + unless Support::StrictSignatureVerifier.new(block_signature, args).valid? + @error_generator.raise_wrong_arity_error(args, block_signature) + end + + value = @eval_context ? @eval_context.instance_exec(*args, &block) : yield(*args) + end + value + end + end + + # Handles the implementation of an `and_return` implementation. + # @private + class AndReturnImplementation + def initialize(values_to_return) + @values_to_return = values_to_return + end + + def call(*_args_to_ignore, &_block) + if @values_to_return.size > 1 + @values_to_return.shift + else + @values_to_return.first + end + end + end + + # Handles the implementation of an `and_invoke` implementation. + # @private + class AndInvokeImplementation + def initialize(procs_to_invoke) + @procs_to_invoke = procs_to_invoke + end + + def call(*args, &block) + proc = if @procs_to_invoke.size > 1 + @procs_to_invoke.shift + else + @procs_to_invoke.first + end + + proc.call(*args, &block) + end + ruby2_keywords(:call) if respond_to?(:ruby2_keywords, true) + end + + # Represents a configured implementation. Takes into account + # any number of sub-implementations. + # @private + class Implementation + attr_accessor :initial_action, :inner_action, :terminal_action + + def call(*args, &block) + actions.map do |action| + action.call(*args, &block) + end.last + end + ruby2_keywords :call if respond_to?(:ruby2_keywords, true) + + def present? + actions.any? + end + + private + + def actions + [initial_action, inner_action, terminal_action].compact + end + end + + # Represents an `and_call_original` implementation. + # @private + class AndWrapOriginalImplementation + def initialize(method, block) + @method = method + @block = block + end + + CannotModifyFurtherError = Class.new(StandardError) + + def initial_action=(_value) + raise cannot_modify_further_error + end + + def inner_action=(_value) + raise cannot_modify_further_error + end + + def terminal_action=(_value) + raise cannot_modify_further_error + end + + def present? + true + end + + def inner_action + true + end + + def call(*args, &block) + @block.call(@method, *args, &block) + end + ruby2_keywords :call if respond_to?(:ruby2_keywords, true) + + private + + def cannot_modify_further_error + CannotModifyFurtherError.new "This method has already been configured " \ + "to call the original implementation, and cannot be modified further." + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb new file mode 100644 index 0000000..7417f65 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb @@ -0,0 +1,316 @@ +module RSpec + module Mocks + # @private + class MethodDouble + # @private TODO: drop in favor of FrozenError in ruby 2.5+ + FROZEN_ERROR_MSG = /can't modify frozen/ + + # @private + attr_reader :method_name, :object, :expectations, :stubs, :method_stasher + + # @private + def initialize(object, method_name, proxy) + @method_name = method_name + @object = object + @proxy = proxy + + @original_visibility = nil + @method_stasher = InstanceMethodStasher.new(object, method_name) + @method_is_proxied = false + @expectations = [] + @stubs = [] + end + + def original_implementation_callable + # If original method is not present, uses the `method_missing` + # handler of the object. This accounts for cases where the user has not + # correctly defined `respond_to?`, and also 1.8 which does not provide + # method handles for missing methods even if `respond_to?` is correct. + @original_implementation_callable ||= original_method || method_missing_block + end + + alias_method :save_original_implementation_callable!, :original_implementation_callable + + def original_method + @original_method ||= + @method_stasher.original_method || + @proxy.original_method_handle_for(method_name) + end + + # @private + def method_missing_block + block = Proc.new do |*args, &b| + @object.__send__(:method_missing, @method_name, *args, &b) + end + block.ruby2_keywords if block.respond_to?(:ruby2_keywords) + + block + end + + # @private + def visibility + @proxy.visibility_for(@method_name) + end + + # @private + def object_singleton_class + class << @object; self; end + end + + # @private + def configure_method + @original_visibility = visibility + @method_stasher.stash unless @method_is_proxied + define_proxy_method + end + + # @private + def define_proxy_method + return if @method_is_proxied + + save_original_implementation_callable! + definition_target.class_exec(self, method_name, @original_visibility || visibility) do |method_double, method_name, visibility| + define_method(method_name) do |*args, &block| + method_double.proxy_method_invoked(self, *args, &block) + end + # This can't be `if respond_to?(:ruby2_keywords, true)`, + # see https://github.com/rspec/rspec-mocks/pull/1385#issuecomment-755340298 + ruby2_keywords(method_name) if Module.private_method_defined?(:ruby2_keywords) + __send__(visibility, method_name) + end + + @method_is_proxied = true + rescue RuntimeError, TypeError => e + # TODO: drop in favor of FrozenError in ruby 2.5+ + # RuntimeError (and FrozenError) for ruby 2.x + # TypeError for ruby 1.x + if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message + raise ArgumentError, "Cannot proxy frozen objects, rspec-mocks relies on proxies for method stubbing and expectations." + end + raise + end + + # The implementation of the proxied method. Subclasses may override this + # method to perform additional operations. + # + # @private + def proxy_method_invoked(_obj, *args, &block) + @proxy.message_received method_name, *args, &block + end + ruby2_keywords :proxy_method_invoked if respond_to?(:ruby2_keywords, true) + + # @private + def restore_original_method + return unless @method_is_proxied + + remove_method_from_definition_target + @method_stasher.restore if @method_stasher.method_is_stashed? + restore_original_visibility + + @method_is_proxied = false + rescue RuntimeError, TypeError => e + # TODO: drop in favor of FrozenError in ruby 2.5+ + # RuntimeError (and FrozenError) for ruby 2.x + # TypeError for ruby 1.x + if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message + return show_frozen_warning + end + raise + end + + # @private + def show_frozen_warning + RSpec.warn_with( + "WARNING: rspec-mocks was unable to restore the original `#{@method_name}` " \ + "method on #{@object.inspect} because it has been frozen. If you reuse this " \ + "object, `#{@method_name}` will continue to respond with its stub implementation.", + :call_site => nil, + :use_spec_location_as_call_site => true + ) + end + + # @private + def restore_original_visibility + return unless @original_visibility && + MethodReference.method_defined_at_any_visibility?(object_singleton_class, @method_name) + + object_singleton_class.__send__(@original_visibility, method_name) + end + + # @private + def verify + expectations.each { |e| e.verify_messages_received } + end + + # @private + def reset + restore_original_method + clear + end + + # @private + def clear + expectations.clear + stubs.clear + end + + # The type of message expectation to create has been extracted to its own + # method so that subclasses can override it. + # + # @private + def message_expectation_class + MessageExpectation + end + + # @private + def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation) + configure_method + expectation = message_expectation_class.new(error_generator, expectation_ordering, + expected_from, self, :expectation, opts, &implementation) + expectations << expectation + expectation + end + + # @private + def build_expectation(error_generator, expectation_ordering) + expected_from = IGNORED_BACKTRACE_LINE + message_expectation_class.new(error_generator, expectation_ordering, expected_from, self) + end + + # @private + def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation) + configure_method + stub = message_expectation_class.new(error_generator, expectation_ordering, expected_from, + self, :stub, opts, &implementation) + stubs.unshift stub + stub + end + + # A simple stub can only return a concrete value for a message, and + # cannot match on arguments. It is used as an optimization over + # `add_stub` / `add_expectation` where it is known in advance that this + # is all that will be required of a stub, such as when passing attributes + # to the `double` example method. They do not stash or restore existing method + # definitions. + # + # @private + def add_simple_stub(method_name, response) + setup_simple_method_double method_name, response, stubs + end + + # @private + def add_simple_expectation(method_name, response, error_generator, backtrace_line) + setup_simple_method_double method_name, response, expectations, error_generator, backtrace_line + end + + # @private + def setup_simple_method_double(method_name, response, collection, error_generator=nil, backtrace_line=nil) + define_proxy_method + + me = SimpleMessageExpectation.new(method_name, response, error_generator, backtrace_line) + collection.unshift me + me + end + + # @private + def add_default_stub(*args, &implementation) + return if stubs.any? + add_stub(*args, &implementation) + end + + # @private + def remove_stub + raise_method_not_stubbed_error if stubs.empty? + remove_stub_if_present + end + + # @private + def remove_stub_if_present + expectations.empty? ? reset : stubs.clear + end + + # @private + def raise_method_not_stubbed_error + RSpec::Mocks.error_generator.raise_method_not_stubbed_error(method_name) + end + + # In Ruby 2.0.0 and above prepend will alter the method lookup chain. + # We use an object's singleton class to define method doubles upon, + # however if the object has had its singleton class (as opposed to + # its actual class) prepended too then the the method lookup chain + # will look in the prepended module first, **before** the singleton + # class. + # + # This code works around that by providing a mock definition target + # that is either the singleton class, or if necessary, a prepended module + # of our own. + # + if Support::RubyFeatures.module_prepends_supported? + + private + + # We subclass `Module` in order to be able to easily detect our prepended module. + RSpecPrependedModule = Class.new(Module) + + def definition_target + @definition_target ||= usable_rspec_prepended_module || object_singleton_class + end + + def usable_rspec_prepended_module + @proxy.prepended_modules_of_singleton_class.each do |mod| + # If we have one of our modules prepended before one of the user's + # modules that defines the method, use that, since our module's + # definition will take precedence. + return mod if RSpecPrependedModule === mod + + # If we hit a user module with the method defined first, + # we must create a new prepend module, even if one exists later, + # because ours will only take precedence if it comes first. + return new_rspec_prepended_module if mod.method_defined?(method_name) + end + + nil + end + + def new_rspec_prepended_module + RSpecPrependedModule.new.tap do |mod| + object_singleton_class.__send__ :prepend, mod + end + end + + else + + private + + def definition_target + object_singleton_class + end + + end + + private + + def remove_method_from_definition_target + definition_target.__send__(:remove_method, @method_name) + rescue NameError + # This can happen when the method has been monkeyed with by + # something outside RSpec. This happens, for example, when + # `file.write` has been stubbed, and then `file.reopen(other_io)` + # is later called, as `File#reopen` appears to redefine `write`. + # + # Note: we could avoid rescuing this by checking + # `definition_target.instance_method(@method_name).owner == definition_target`, + # saving us from the cost of the expensive exception, but this error is + # extremely rare (it was discovered on 2014-12-30, only happens on + # RUBY_VERSION < 2.0 and our spec suite only hits this condition once), + # so we'd rather avoid the cost of that check for every method double, + # and risk the rare situation where this exception will get raised. + RSpec.warn_with( + "WARNING: RSpec could not fully restore #{@object.inspect}." \ + "#{@method_name}, possibly because the method has been redefined " \ + "by something outside of RSpec." + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb new file mode 100644 index 0000000..50608b0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb @@ -0,0 +1,214 @@ +RSpec::Support.require_rspec_support 'comparable_version' + +module RSpec + module Mocks + # Represents a method on an object that may or may not be defined. + # The method may be an instance method on a module or a method on + # any object. + # + # @private + class MethodReference + def self.for(object_reference, method_name) + new(object_reference, method_name) + end + + def initialize(object_reference, method_name) + @object_reference = object_reference + @method_name = method_name + end + + # A method is implemented if sending the message does not result in + # a `NoMethodError`. It might be dynamically implemented by + # `method_missing`. + def implemented? + @object_reference.when_loaded do |m| + method_implemented?(m) + end + end + + # Returns true if we definitively know that sending the method + # will result in a `NoMethodError`. + # + # This is not simply the inverse of `implemented?`: there are + # cases when we don't know if a method is implemented and + # both `implemented?` and `unimplemented?` will return false. + def unimplemented? + @object_reference.when_loaded do |_m| + return !implemented? + end + + # If it's not loaded, then it may be implemented but we can't check. + false + end + + # A method is defined if we are able to get a `Method` object for it. + # In that case, we can assert against metadata like the arity. + def defined? + @object_reference.when_loaded do |m| + method_defined?(m) + end + end + + def with_signature + return unless (original = original_method) + yield Support::MethodSignature.new(original) + end + + def visibility + @object_reference.when_loaded do |m| + return visibility_from(m) + end + + # When it's not loaded, assume it's public. We don't want to + # wrongly treat the method as private. + :public + end + + def self.instance_method_visibility_for(klass, method_name) + if klass.public_method_defined?(method_name) + :public + elsif klass.private_method_defined?(method_name) + :private + elsif klass.protected_method_defined?(method_name) + :protected + end + end + + class << self + alias method_defined_at_any_visibility? instance_method_visibility_for + end + + def self.method_visibility_for(object, method_name) + vis = instance_method_visibility_for(class << object; self; end, method_name) + + # If the method is not defined on the class, `instance_method_visibility_for` + # returns `nil`. However, it may be handled dynamically by `method_missing`, + # so here we check `respond_to` (passing false to not check private methods). + # + # This only considers the public case, but I don't think it's possible to + # write `method_missing` in such a way that it handles a dynamic message + # with private or protected visibility. Ruby doesn't provide you with + # the caller info. + return vis unless vis.nil? + + proxy = RSpec::Mocks.space.proxy_for(object) + respond_to = proxy.method_double_if_exists_for_message(:respond_to?) + + visible = respond_to && respond_to.original_method.call(method_name) || + object.respond_to?(method_name) + + return :public if visible + end + + private + + def original_method + @object_reference.when_loaded do |m| + self.defined? && find_method(m) + end + end + end + + # @private + class InstanceMethodReference < MethodReference + private + + def method_implemented?(mod) + MethodReference.method_defined_at_any_visibility?(mod, @method_name) + end + + # Ideally, we'd use `respond_to?` for `method_implemented?` but we need a + # reference to an instance to do that and we don't have one. Note that + # we may get false negatives: if the method is implemented via + # `method_missing`, we'll return `false` even though it meets our + # definition of "implemented". However, it's the best we can do. + alias method_defined? method_implemented? + + # works around the fact that repeated calls for method parameters will + # falsely return empty arrays on JRuby in certain circumstances, this + # is necessary here because we can't dup/clone UnboundMethods. + # + # This is necessary due to a bug in JRuby prior to 1.7.5 fixed in: + # https://github.com/jruby/jruby/commit/99a0613fe29935150d76a9a1ee4cf2b4f63f4a27 + if RUBY_PLATFORM == 'java' && RSpec::Support::ComparableVersion.new(JRUBY_VERSION) < '1.7.5' + def find_method(mod) + mod.dup.instance_method(@method_name) + end + else + def find_method(mod) + mod.instance_method(@method_name) + end + end + + def visibility_from(mod) + MethodReference.instance_method_visibility_for(mod, @method_name) + end + end + + # @private + class ObjectMethodReference < MethodReference + def self.for(object_reference, method_name) + if ClassNewMethodReference.applies_to?(method_name) { object_reference.when_loaded { |o| o } } + ClassNewMethodReference.new(object_reference, method_name) + else + super + end + end + + private + + def method_implemented?(object) + object.respond_to?(@method_name, true) + end + + def method_defined?(object) + (class << object; self; end).method_defined?(@method_name) + end + + def find_method(object) + object.method(@method_name) + end + + def visibility_from(object) + MethodReference.method_visibility_for(object, @method_name) + end + end + + # When a class's `.new` method is stubbed, we want to use the method + # signature from `#initialize` because `.new`'s signature is a generic + # `def new(*args)` and it simply delegates to `#initialize` and forwards + # all args...so the method with the actually used signature is `#initialize`. + # + # This method reference implementation handles that specific case. + # @private + class ClassNewMethodReference < ObjectMethodReference + def self.applies_to?(method_name) + return false unless method_name == :new + klass = yield + return false unless ::Class === klass && klass.respond_to?(:new, true) + + # We only want to apply our special logic to normal `new` methods. + # Methods that the user has monkeyed with should be left as-is. + uses_class_new?(klass) + end + + if RUBY_VERSION.to_i >= 3 + CLASS_NEW = ::Class.instance_method(:new) + + def self.uses_class_new?(klass) + ::RSpec::Support.method_handle_for(klass, :new) == CLASS_NEW.bind(klass) + end + else # Ruby 2's Method#== is too strict + def self.uses_class_new?(klass) + ::RSpec::Support.method_handle_for(klass, :new).owner == ::Class + end + end + + def with_signature + @object_reference.when_loaded do |klass| + yield Support::MethodSignature.new(klass.instance_method(:initialize)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb new file mode 100644 index 0000000..a129890 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb @@ -0,0 +1,68 @@ +require 'rspec/mocks' + +module RSpec + module Mocks + # @private + module MinitestIntegration + include ::RSpec::Mocks::ExampleMethods + + def before_setup + ::RSpec::Mocks.setup + super + end + + def after_teardown + super + + # Only verify if there's not already an error. Otherwise + # we risk getting the same failure twice, since negative + # expectation violations raise both when the message is + # unexpectedly received, and also during `verify` (in case + # the first failure was caught by user code via a + # `rescue Exception`). + ::RSpec::Mocks.verify unless failures.any? + ensure + ::RSpec::Mocks.teardown + end + end + end +end + +Minitest::Test.send(:include, RSpec::Mocks::MinitestIntegration) + +if defined?(::Minitest::Expectation) + if defined?(::RSpec::Expectations) && ::Minitest::Expectation.method_defined?(:to) + # rspec/expectations/minitest_integration has already been loaded and + # has defined `to`/`not_to`/`to_not` on `Minitest::Expectation` so we do + # not want to here (or else we would interfere with rspec-expectations' definition). + else + # ...otherwise, define those methods now. If `rspec/expectations/minitest_integration` + # is loaded after this file, it'll override the definition here. + Minitest::Expectation.class_eval do + include RSpec::Mocks::ExpectationTargetMethods + + def to(*args) + ctx.assertions += 1 + super + end + + def not_to(*args) + ctx.assertions += 1 + super + end + + def to_not(*args) + ctx.assertions += 1 + super + end + end + end +end + +module RSpec + module Mocks + remove_const :MockExpectationError + # Raised when a message expectation is not satisfied. + MockExpectationError = ::Minitest::Assertion + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb new file mode 100644 index 0000000..071d7a2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb @@ -0,0 +1,339 @@ +RSpec::Support.require_rspec_support 'recursive_const_methods' + +module RSpec + module Mocks + # Provides information about constants that may (or may not) + # have been mutated by rspec-mocks. + class Constant + extend Support::RecursiveConstMethods + + # @api private + def initialize(name) + @name = name + @previously_defined = false + @stubbed = false + @hidden = false + @valid_name = true + yield self if block_given? + end + + # @return [String] The fully qualified name of the constant. + attr_reader :name + + # @return [Object, nil] The original value (e.g. before it + # was mutated by rspec-mocks) of the constant, or + # nil if the constant was not previously defined. + attr_accessor :original_value + + # @private + attr_writer :previously_defined, :stubbed, :hidden, :valid_name + + # @return [Boolean] Whether or not the constant was defined + # before the current example. + def previously_defined? + @previously_defined + end + + # @return [Boolean] Whether or not rspec-mocks has mutated + # (stubbed or hidden) this constant. + def mutated? + @stubbed || @hidden + end + + # @return [Boolean] Whether or not rspec-mocks has stubbed + # this constant. + def stubbed? + @stubbed + end + + # @return [Boolean] Whether or not rspec-mocks has hidden + # this constant. + def hidden? + @hidden + end + + # @return [Boolean] Whether or not the provided constant name + # is a valid Ruby constant name. + def valid_name? + @valid_name + end + + # The default `to_s` isn't very useful, so a custom version is provided. + def to_s + "#<#{self.class.name} #{name}>" + end + alias inspect to_s + + # @private + def self.unmutated(name) + previously_defined = !!recursive_const_defined?(name) + rescue NameError + new(name) do |c| + c.valid_name = false + end + else + new(name) do |const| + const.previously_defined = previously_defined + const.original_value = recursive_const_get(name) if previously_defined + end + end + + # Queries rspec-mocks to find out information about the named constant. + # + # @param [String] name the name of the constant + # @return [Constant] an object containing information about the named + # constant. + def self.original(name) + mutator = ::RSpec::Mocks.space.constant_mutator_for(name) + mutator ? mutator.to_constant : unmutated(name) + end + end + + # Provides a means to stub constants. + class ConstantMutator + extend Support::RecursiveConstMethods + + # Stubs a constant. + # + # @param (see ExampleMethods#stub_const) + # @option (see ExampleMethods#stub_const) + # @return (see ExampleMethods#stub_const) + # + # @see ExampleMethods#stub_const + # @note It's recommended that you use `stub_const` in your + # examples. This is an alternate public API that is provided + # so you can stub constants in other contexts (e.g. helper + # classes). + def self.stub(constant_name, value, options={}) + unless String === constant_name + raise ArgumentError, "`stub_const` requires a String, but you provided a #{constant_name.class.name}" + end + + mutator = if recursive_const_defined?(constant_name, &raise_on_invalid_const) + DefinedConstantReplacer + else + UndefinedConstantSetter + end + + mutate(mutator.new(constant_name, value, options[:transfer_nested_constants])) + value + end + + # Hides a constant. + # + # @param (see ExampleMethods#hide_const) + # + # @see ExampleMethods#hide_const + # @note It's recommended that you use `hide_const` in your + # examples. This is an alternate public API that is provided + # so you can hide constants in other contexts (e.g. helper + # classes). + def self.hide(constant_name) + mutate(ConstantHider.new(constant_name, nil, {})) + nil + end + + # Contains common functionality used by all of the constant mutators. + # + # @private + class BaseMutator + include Support::RecursiveConstMethods + + attr_reader :original_value, :full_constant_name + + def initialize(full_constant_name, mutated_value, transfer_nested_constants) + @full_constant_name = normalize_const_name(full_constant_name) + @mutated_value = mutated_value + @transfer_nested_constants = transfer_nested_constants + @context_parts = @full_constant_name.split('::') + @const_name = @context_parts.pop + @reset_performed = false + end + + def to_constant + const = Constant.new(full_constant_name) + const.original_value = original_value + + const + end + + def idempotently_reset + reset unless @reset_performed + @reset_performed = true + end + end + + # Hides a defined constant for the duration of an example. + # + # @private + class ConstantHider < BaseMutator + def mutate + return unless (@defined = recursive_const_defined?(full_constant_name)) + @context = recursive_const_get(@context_parts.join('::')) + @original_value = get_const_defined_on(@context, @const_name) + + @context.__send__(:remove_const, @const_name) + end + + def to_constant + return Constant.unmutated(full_constant_name) unless @defined + + const = super + const.hidden = true + const.previously_defined = true + + const + end + + def reset + return unless @defined + @context.const_set(@const_name, @original_value) + end + end + + # Replaces a defined constant for the duration of an example. + # + # @private + class DefinedConstantReplacer < BaseMutator + def initialize(*args) + super + @constants_to_transfer = [] + end + + def mutate + @context = recursive_const_get(@context_parts.join('::')) + @original_value = get_const_defined_on(@context, @const_name) + + @constants_to_transfer = verify_constants_to_transfer! + + @context.__send__(:remove_const, @const_name) + @context.const_set(@const_name, @mutated_value) + + transfer_nested_constants + end + + def to_constant + const = super + const.stubbed = true + const.previously_defined = true + + const + end + + def reset + @constants_to_transfer.each do |const| + @mutated_value.__send__(:remove_const, const) + end + + @context.__send__(:remove_const, @const_name) + @context.const_set(@const_name, @original_value) + end + + def transfer_nested_constants + @constants_to_transfer.each do |const| + @mutated_value.const_set(const, get_const_defined_on(original_value, const)) + end + end + + def verify_constants_to_transfer! + return [] unless should_transfer_nested_constants? + + { @original_value => "the original value", @mutated_value => "the stubbed value" }.each do |value, description| + next if value.respond_to?(:constants) + + raise ArgumentError, + "Cannot transfer nested constants for #{@full_constant_name} " \ + "since #{description} is not a class or module and only classes " \ + "and modules support nested constants." + end + + if Array === @transfer_nested_constants + @transfer_nested_constants = @transfer_nested_constants.map(&:to_s) if RUBY_VERSION == '1.8.7' + undefined_constants = @transfer_nested_constants - constants_defined_on(@original_value) + + if undefined_constants.any? + available_constants = constants_defined_on(@original_value) - @transfer_nested_constants + raise ArgumentError, + "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " \ + "for #{@full_constant_name} since they are not defined. Did you mean " \ + "#{available_constants.join(' or ')}?" + end + + @transfer_nested_constants + else + constants_defined_on(@original_value) + end + end + + def should_transfer_nested_constants? + return true if @transfer_nested_constants + return false unless RSpec::Mocks.configuration.transfer_nested_constants? + @original_value.respond_to?(:constants) && @mutated_value.respond_to?(:constants) + end + end + + # Sets an undefined constant for the duration of an example. + # + # @private + class UndefinedConstantSetter < BaseMutator + def mutate + @parent = @context_parts.inject(Object) do |klass, name| + if const_defined_on?(klass, name) + get_const_defined_on(klass, name) + else + ConstantMutator.stub(name_for(klass, name), Module.new) + end + end + + @parent.const_set(@const_name, @mutated_value) + end + + def to_constant + const = super + const.stubbed = true + const.previously_defined = false + + const + end + + def reset + @parent.__send__(:remove_const, @const_name) + end + + private + + def name_for(parent, name) + root = if parent == Object + '' + else + parent.name + end + root + '::' + name + end + end + + # Uses the mutator to mutate (stub or hide) a constant. Ensures that + # the mutator is correctly registered so it can be backed out at the end + # of the test. + # + # @private + def self.mutate(mutator) + ::RSpec::Mocks.space.register_constant_mutator(mutator) + mutator.mutate + end + + # Used internally by the constant stubbing to raise a helpful + # error when a constant like "A::B::C" is stubbed and A::B is + # not a module (and thus, it's impossible to define "A::B::C" + # since only modules can have nested constants). + # + # @api private + def self.raise_on_invalid_const + lambda do |const_name, failed_name| + raise "Cannot stub constant #{failed_name} on #{const_name} " \ + "since #{const_name} is not a module." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb new file mode 100644 index 0000000..cce2c33 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb @@ -0,0 +1,149 @@ +module RSpec + module Mocks + # @private + class ObjectReference + # Returns an appropriate Object or Module reference based + # on the given argument. + def self.for(object_module_or_name, allow_direct_object_refs=false) + case object_module_or_name + when Module + if anonymous_module?(object_module_or_name) + DirectObjectReference.new(object_module_or_name) + else + # Use a `NamedObjectReference` if it has a name because this + # will use the original value of the constant in case it has + # been stubbed. + NamedObjectReference.new(name_of(object_module_or_name)) + end + when String + NamedObjectReference.new(object_module_or_name) + else + if allow_direct_object_refs + DirectObjectReference.new(object_module_or_name) + else + raise ArgumentError, + "Module or String expected, got #{object_module_or_name.inspect}" + end + end + end + + if Module.new.name.nil? + def self.anonymous_module?(mod) + !name_of(mod) + end + else # 1.8.7 + def self.anonymous_module?(mod) + name_of(mod) == "" + end + end + private_class_method :anonymous_module? + + def self.name_of(mod) + MODULE_NAME_METHOD.bind(mod).call + end + private_class_method :name_of + + # @private + MODULE_NAME_METHOD = Module.instance_method(:name) + end + + # An implementation of rspec-mocks' reference interface. + # Used when an object is passed to {ExampleMethods#object_double}, or + # an anonymous class or module is passed to {ExampleMethods#instance_double} + # or {ExampleMethods#class_double}. + # Represents a reference to that object. + # @see NamedObjectReference + class DirectObjectReference + # @param object [Object] the object to which this refers + def initialize(object) + @object = object + end + + # @return [String] the object's description (via `#inspect`). + def description + @object.inspect + end + + # Defined for interface parity with the other object reference + # implementations. Raises an `ArgumentError` to indicate that `as_stubbed_const` + # is invalid when passing an object argument to `object_double`. + def const_to_replace + raise ArgumentError, + "Can not perform constant replacement with an anonymous object." + end + + # The target of the verifying double (the object itself). + # + # @return [Object] + def target + @object + end + + # Always returns true for an object as the class is defined. + # + # @return [true] + def defined? + true + end + + # Yields if the reference target is loaded, providing a generic mechanism + # to optionally run a bit of code only when a reference's target is + # loaded. + # + # This specific implementation always yields because direct references + # are always loaded. + # + # @yield [Object] the target of this reference. + def when_loaded + yield @object + end + end + + # An implementation of rspec-mocks' reference interface. + # Used when a string is passed to {ExampleMethods#object_double}, + # and when a string, named class or named module is passed to + # {ExampleMethods#instance_double}, or {ExampleMethods#class_double}. + # Represents a reference to the object named (via a constant lookup) + # by the string. + # @see DirectObjectReference + class NamedObjectReference + # @param const_name [String] constant name + def initialize(const_name) + @const_name = const_name + end + + # @return [Boolean] true if the named constant is defined, false otherwise. + def defined? + !!object + end + + # @return [String] the constant name to replace with a double. + def const_to_replace + @const_name + end + alias description const_to_replace + + # @return [Object, nil] the target of the verifying double (the named object), or + # nil if it is not defined. + def target + object + end + + # Yields if the reference target is loaded, providing a generic mechanism + # to optionally run a bit of code only when a reference's target is + # loaded. + # + # @yield [Object] the target object + def when_loaded + yield object if object + end + + private + + def object + return @object if defined?(@object) + @object = Constant.original(@const_name).original_value + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb new file mode 100644 index 0000000..a994799 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb @@ -0,0 +1,81 @@ +module RSpec + module Mocks + # @private + class OrderGroup + def initialize + @expectations = [] + @invocation_order = [] + @index = 0 + end + + # @private + def register(expectation) + @expectations << expectation + end + + def invoked(message) + @invocation_order << message + end + + # @private + def ready_for?(expectation) + remaining_expectations.find(&:ordered?) == expectation + end + + # @private + def consume + remaining_expectations.each_with_index do |expectation, index| + next unless expectation.ordered? + + @index += index + 1 + return expectation + end + nil + end + + # @private + def handle_order_constraint(expectation) + return unless expectation.ordered? && remaining_expectations.include?(expectation) + return consume if ready_for?(expectation) + expectation.raise_out_of_order_error + end + + def verify_invocation_order(expectation) + expectation.raise_out_of_order_error unless expectations_invoked_in_order? + true + end + + def clear + @index = 0 + @invocation_order.clear + @expectations.clear + end + + def empty? + @expectations.empty? + end + + private + + def remaining_expectations + @expectations[@index..-1] || [] + end + + def expectations_invoked_in_order? + invoked_expectations == expected_invocations + end + + def invoked_expectations + @expectations.select { |e| e.ordered? && @invocation_order.include?(e) } + end + + def expected_invocations + @invocation_order.map { |invocation| expectation_for(invocation) }.compact + end + + def expectation_for(message) + @expectations.find { |e| message == e } + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb new file mode 100644 index 0000000..6bd1393 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb @@ -0,0 +1,517 @@ +RSpec::Support.require_rspec_support 'mutex' + +module RSpec + module Mocks + # @private + class Proxy + # @private + SpecificMessage = Struct.new(:object, :message, :args) do + def ==(expectation) + expectation.orig_object == object && expectation.matches?(message, *args) + end + end + + # @private + def ensure_implemented(*_args) + # noop for basic proxies, see VerifyingProxy for behaviour. + end + + # @private + def initialize(object, order_group, options={}) + ensure_can_be_proxied!(object) + + @object = object + @order_group = order_group + @error_generator = ErrorGenerator.new(object) + @messages_received = [] + @messages_received_mutex = Support::Mutex.new + @options = options + @null_object = false + @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) } + end + + # @private + def ensure_can_be_proxied!(object) + return unless Symbol === object + + msg = "Cannot proxy frozen objects. Symbols such as #{object} cannot be mocked or stubbed." + raise ArgumentError, msg + end + + # @private + attr_reader :object + + # @private + def null_object? + @null_object + end + + # @private + # Tells the object to ignore any messages that aren't explicitly set as + # stubs or message expectations. + def as_null_object + @null_object = true + @object + end + + # @private + def original_method_handle_for(_message) + nil + end + + DEFAULT_MESSAGE_EXPECTATION_OPTS = {}.freeze + + # @private + def add_message_expectation(method_name, opts=DEFAULT_MESSAGE_EXPECTATION_OPTS, &block) + location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line } + meth_double = method_double_for(method_name) + + if null_object? && !block + meth_double.add_default_stub(@error_generator, @order_group, location, opts) do + @object + end + end + + meth_double.add_expectation @error_generator, @order_group, location, opts, &block + end + + # @private + def add_simple_expectation(method_name, response, location) + method_double_for(method_name).add_simple_expectation method_name, response, @error_generator, location + end + + # @private + def build_expectation(method_name) + meth_double = method_double_for(method_name) + + meth_double.build_expectation( + @error_generator, + @order_group + ) + end + + # @private + def replay_received_message_on(expectation, &block) + expected_method_name = expectation.message + meth_double = method_double_for(expected_method_name) + + if meth_double.expectations.any? + @error_generator.raise_expectation_on_mocked_method(expected_method_name) + end + + unless null_object? || meth_double.stubs.any? + @error_generator.raise_expectation_on_unstubbed_method(expected_method_name) + end + + @messages_received_mutex.synchronize do + @messages_received.each do |(actual_method_name, args, received_block)| + next unless expectation.matches?(actual_method_name, *args) + + expectation.safe_invoke(nil) + block.call(*args, &received_block) if block + end + end + end + + # @private + def check_for_unexpected_arguments(expectation) + @messages_received_mutex.synchronize do + return if @messages_received.empty? + + return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) } + + name_but_not_args, others = @messages_received.partition do |(method_name, args, _)| + expectation.matches_name_but_not_args(method_name, *args) + end + + return if name_but_not_args.empty? && !others.empty? + + expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] }) + end + end + + # @private + def add_stub(method_name, opts={}, &implementation) + location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line } + method_double_for(method_name).add_stub @error_generator, @order_group, location, opts, &implementation + end + + # @private + def add_simple_stub(method_name, response) + method_double_for(method_name).add_simple_stub method_name, response + end + + # @private + def remove_stub(method_name) + method_double_for(method_name).remove_stub + end + + # @private + def remove_stub_if_present(method_name) + method_double_for(method_name).remove_stub_if_present + end + + # @private + def verify + @method_doubles.each_value { |d| d.verify } + end + + # @private + def reset + @messages_received_mutex.synchronize do + @messages_received.clear + end + end + + # @private + def received_message?(method_name, *args, &block) + @messages_received_mutex.synchronize do + @messages_received.any? { |array| array == [method_name, args, block] } + end + end + + # @private + def messages_arg_list + @messages_received_mutex.synchronize do + @messages_received.map { |_, args, _| args } + end + end + + # @private + def has_negative_expectation?(message) + method_double_for(message).expectations.find { |expectation| expectation.negative_expectation_for?(message) } + end + + # @private + def record_message_received(message, *args, &block) + @order_group.invoked SpecificMessage.new(object, message, args) + @messages_received_mutex.synchronize do + @messages_received << [message, args, block] + end + end + ruby2_keywords :record_message_received if respond_to?(:ruby2_keywords, true) + + # @private + def message_received(message, *args, &block) + record_message_received message, *args, &block + + expectation = find_matching_expectation(message, *args) + stub = find_matching_method_stub(message, *args) + + if (stub && expectation && expectation.called_max_times?) || (stub && !expectation) + expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters? + if (expectation = find_almost_matching_expectation(message, *args)) + expectation.advise(*args) unless expectation.expected_messages_received? + end + stub.invoke(nil, *args, &block) + elsif expectation + expectation.unadvise(messages_arg_list) + expectation.invoke(stub, *args, &block) + elsif (expectation = find_almost_matching_expectation(message, *args)) + expectation.advise(*args) if null_object? unless expectation.expected_messages_received? + + if null_object? || !has_negative_expectation?(message) + expectation.raise_unexpected_message_args_error([args]) + end + elsif (stub = find_almost_matching_stub(message, *args)) + stub.advise(*args) + raise_missing_default_stub_error(stub, [args]) + elsif Class === @object + @object.superclass.__send__(message, *args, &block) + else + @object.__send__(:method_missing, message, *args, &block) + end + end + ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true) + + # @private + def raise_unexpected_message_error(method_name, args) + @error_generator.raise_unexpected_message_error method_name, args + end + + # @private + def raise_missing_default_stub_error(expectation, args_for_multiple_calls) + @error_generator.raise_missing_default_stub_error(expectation, args_for_multiple_calls) + end + + # @private + def visibility_for(_method_name) + # This is the default (for test doubles). Subclasses override this. + :public + end + + if Support::RubyFeatures.module_prepends_supported? + def self.prepended_modules_of(klass) + ancestors = klass.ancestors + + # `|| 0` is necessary for Ruby 2.0, where the singleton class + # is only in the ancestor list when there are prepended modules. + singleton_index = ancestors.index(klass) || 0 + + ancestors[0, singleton_index] + end + + def prepended_modules_of_singleton_class + @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class) + end + end + + # @private + def method_double_if_exists_for_message(message) + method_double_for(message) if @method_doubles.key?(message.to_sym) + end + + private + + def method_double_for(message) + @method_doubles[message.to_sym] + end + + def find_matching_expectation(method_name, *args) + find_best_matching_expectation_for(method_name) do |expectation| + expectation.matches?(method_name, *args) + end + end + ruby2_keywords :find_matching_expectation if respond_to?(:ruby2_keywords, true) + + def find_almost_matching_expectation(method_name, *args) + find_best_matching_expectation_for(method_name) do |expectation| + expectation.matches_name_but_not_args(method_name, *args) + end + end + ruby2_keywords :find_almost_matching_expectation if respond_to?(:ruby2_keywords, true) + + def find_best_matching_expectation_for(method_name) + first_match = nil + + method_double_for(method_name).expectations.each do |expectation| + next unless yield expectation + return expectation unless expectation.called_max_times? + first_match ||= expectation + end + + first_match + end + + def find_matching_method_stub(method_name, *args) + method_double_for(method_name).stubs.find { |stub| stub.matches?(method_name, *args) } + end + ruby2_keywords :find_matching_method_stub if respond_to?(:ruby2_keywords, true) + + def find_almost_matching_stub(method_name, *args) + method_double_for(method_name).stubs.find { |stub| stub.matches_name_but_not_args(method_name, *args) } + end + ruby2_keywords :find_almost_matching_stub if respond_to?(:ruby2_keywords, true) + end + + # @private + class TestDoubleProxy < Proxy + def reset + @method_doubles.clear + object.__disallow_further_usage! + super + end + end + + # @private + class PartialDoubleProxy < Proxy + def original_method_handle_for(message) + if any_instance_class_recorder_observing_method?(@object.class, message) + message = ::RSpec::Mocks.space. + any_instance_recorder_for(@object.class). + build_alias_method_name(message) + end + + ::RSpec::Support.method_handle_for(@object, message) + rescue NameError + nil + end + + # @private + def add_simple_expectation(method_name, response, location) + method_double_for(method_name).configure_method + super + end + + # @private + def add_simple_stub(method_name, response) + method_double_for(method_name).configure_method + super + end + + # @private + def visibility_for(method_name) + # We fall back to :public because by default we allow undefined methods + # to be stubbed, and when we do so, we make them public. + MethodReference.method_visibility_for(@object, method_name) || :public + end + + def reset + @method_doubles.each_value { |d| d.reset } + super + end + + def message_received(message, *args, &block) + RSpec::Mocks.space.any_instance_recorders_from_ancestry_of(object).each do |subscriber| + subscriber.notify_received_message(object, message, args, block) + end + super + end + ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true) + + private + + def any_instance_class_recorder_observing_method?(klass, method_name) + only_return_existing = true + recorder = ::RSpec::Mocks.space.any_instance_recorder_for(klass, only_return_existing) + return true if recorder && recorder.already_observing?(method_name) + + superklass = klass.superclass + return false if superklass.nil? + any_instance_class_recorder_observing_method?(superklass, method_name) + end + end + + # @private + # When we mock or stub a method on a class, we have to treat it a bit different, + # because normally singleton method definitions only affect the object on which + # they are defined, but on classes they affect subclasses, too. As a result, + # we need some special handling to get the original method. + module PartialClassDoubleProxyMethods + def initialize(source_space, *args) + @source_space = source_space + super(*args) + end + + # Consider this situation: + # + # class A; end + # class B < A; end + # + # allow(A).to receive(:new) + # expect(B).to receive(:new).and_call_original + # + # When getting the original definition for `B.new`, we cannot rely purely on + # using `B.method(:new)` before our redefinition is defined on `B`, because + # `B.method(:new)` will return a method that will execute the stubbed version + # of the method on `A` since singleton methods on classes are in the lookup + # hierarchy. + # + # To do it properly, we need to find the original definition of `new` from `A` + # from _before_ `A` was stubbed, and we need to rebind it to `B` so that it will + # run with the proper `self`. + # + # That's what this method (together with `original_unbound_method_handle_from_ancestor_for`) + # does. + def original_method_handle_for(message) + unbound_method = superclass_proxy && + superclass_proxy.original_unbound_method_handle_from_ancestor_for(message.to_sym) + + return super unless unbound_method + unbound_method.bind(object) + # :nocov: + rescue TypeError + if RUBY_VERSION == '1.8.7' + # In MRI 1.8.7, a singleton method on a class cannot be rebound to its subclass + if unbound_method && unbound_method.owner.ancestors.first != unbound_method.owner + # This is a singleton method; we can't do anything with it + # But we can work around this using a different implementation + double = method_double_from_ancestor_for(message) + return object.method(double.method_stasher.stashed_method_name) + end + end + raise + # :nocov: + end + + protected + + def original_unbound_method_handle_from_ancestor_for(message) + double = method_double_from_ancestor_for(message) + double && double.original_method.unbind + end + + def method_double_from_ancestor_for(message) + @method_doubles.fetch(message) do + # The fact that there is no method double for this message indicates + # that it has not been redefined by rspec-mocks. We need to continue + # looking up the ancestor chain. + return superclass_proxy && + superclass_proxy.method_double_from_ancestor_for(message) + end + end + + def superclass_proxy + return @superclass_proxy if defined?(@superclass_proxy) + + if (superclass = object.superclass) + @superclass_proxy = @source_space.superclass_proxy_for(superclass) + else + @superclass_proxy = nil + end + end + end + + # @private + class PartialClassDoubleProxy < PartialDoubleProxy + include PartialClassDoubleProxyMethods + end + + # @private + class ProxyForNil < PartialDoubleProxy + def initialize(order_group) + set_expectation_behavior + super(nil, order_group) + end + + attr_accessor :disallow_expectations + attr_accessor :warn_about_expectations + + def add_message_expectation(method_name, opts={}, &block) + warn_or_raise!(method_name) + super + end + + def add_stub(method_name, opts={}, &implementation) + warn_or_raise!(method_name) + super + end + + private + + def set_expectation_behavior + case RSpec::Mocks.configuration.allow_message_expectations_on_nil + when false + @warn_about_expectations = false + @disallow_expectations = true + when true + @warn_about_expectations = false + @disallow_expectations = false + else + @warn_about_expectations = true + @disallow_expectations = false + end + end + + def warn_or_raise!(method_name) + # This method intentionally swallows the message when + # neither disallow_expectations nor warn_about_expectations + # are set to true. + if disallow_expectations + raise_error(method_name) + elsif warn_about_expectations + warn(method_name) + end + end + + def warn(method_name) + warning_msg = @error_generator.expectation_on_nil_message(method_name) + RSpec.warning(warning_msg) + end + + def raise_error(method_name) + @error_generator.raise_expectation_on_nil_error(method_name) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb new file mode 100644 index 0000000..f933caa --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb @@ -0,0 +1,238 @@ +RSpec::Support.require_rspec_support 'reentrant_mutex' + +module RSpec + module Mocks + # @private + # Provides a default space implementation for outside + # the scope of an example. Called "root" because it serves + # as the root of the space stack. + class RootSpace + def proxy_for(*_args) + raise_lifecycle_message + end + + def any_instance_recorder_for(*_args) + raise_lifecycle_message + end + + def any_instance_proxy_for(*_args) + raise_lifecycle_message + end + + def register_constant_mutator(_mutator) + raise_lifecycle_message + end + + def any_instance_recorders_from_ancestry_of(_object) + raise_lifecycle_message + end + + def reset_all + end + + def verify_all + end + + def registered?(_object) + false + end + + def superclass_proxy_for(*_args) + raise_lifecycle_message + end + + def new_scope + Space.new + end + + private + + def raise_lifecycle_message + raise OutsideOfExampleError, + "The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported." + end + end + + # @private + class Space + attr_reader :proxies, :any_instance_recorders, :proxy_mutex, :any_instance_mutex + + def initialize + @proxies = {} + @any_instance_recorders = {} + @constant_mutators = [] + @expectation_ordering = OrderGroup.new + @proxy_mutex = new_mutex + @any_instance_mutex = new_mutex + end + + def new_scope + NestedSpace.new(self) + end + + def verify_all + proxies.values.each { |proxy| proxy.verify } + any_instance_recorders.each_value { |recorder| recorder.verify } + end + + def reset_all + proxies.each_value { |proxy| proxy.reset } + any_instance_recorders.each_value { |recorder| recorder.stop_all_observation! } + any_instance_recorders.clear + @constant_mutators.reverse.each { |mut| mut.idempotently_reset } + end + + def register_constant_mutator(mutator) + @constant_mutators << mutator + end + + def constant_mutator_for(name) + @constant_mutators.find { |m| m.full_constant_name == name } + end + + def any_instance_recorder_for(klass, only_return_existing=false) + any_instance_mutex.synchronize do + id = klass.__id__ + any_instance_recorders.fetch(id) do + return nil if only_return_existing + any_instance_recorder_not_found_for(id, klass) + end + end + end + + def any_instance_proxy_for(klass) + AnyInstance::Proxy.new(any_instance_recorder_for(klass), proxies_of(klass)) + end + + def proxies_of(klass) + proxies.values.select { |proxy| klass === proxy.object } + end + + def proxy_for(object) + proxy_mutex.synchronize do + id = id_for(object) + proxies.fetch(id) { proxy_not_found_for(id, object) } + end + end + + def superclass_proxy_for(klass) + proxy_mutex.synchronize do + id = id_for(klass) + proxies.fetch(id) { superclass_proxy_not_found_for(id, klass) } + end + end + + alias ensure_registered proxy_for + + def registered?(object) + proxies.key?(id_for object) + end + + def any_instance_recorders_from_ancestry_of(object) + # Optimization: `any_instance` is a feature we generally + # recommend not using, so we can often early exit here + # without doing an O(N) linear search over the number of + # ancestors in the object's class hierarchy. + return [] if any_instance_recorders.empty? + + # We access the ancestors through the singleton class, to avoid calling + # `class` in case `class` has been stubbed. + (class << object; ancestors; end).map do |klass| + any_instance_recorders[klass.__id__] + end.compact + end + + private + + def new_mutex + Support::ReentrantMutex.new + end + + def proxy_not_found_for(id, object) + proxies[id] = case object + when NilClass then ProxyForNil.new(@expectation_ordering) + when TestDouble then object.__build_mock_proxy_unless_expired(@expectation_ordering) + when Class + class_proxy_with_callback_verification_strategy(object, CallbackInvocationStrategy.new) + else + if RSpec::Mocks.configuration.verify_partial_doubles? + VerifyingPartialDoubleProxy.new(object, @expectation_ordering) + else + PartialDoubleProxy.new(object, @expectation_ordering) + end + end + end + + def superclass_proxy_not_found_for(id, object) + raise "superclass_proxy_not_found_for called with something that is not a class" unless Class === object + proxies[id] = class_proxy_with_callback_verification_strategy(object, NoCallbackInvocationStrategy.new) + end + + def class_proxy_with_callback_verification_strategy(object, strategy) + if RSpec::Mocks.configuration.verify_partial_doubles? + VerifyingPartialClassDoubleProxy.new( + self, + object, + @expectation_ordering, + strategy + ) + else + PartialClassDoubleProxy.new(self, object, @expectation_ordering) + end + end + + def any_instance_recorder_not_found_for(id, klass) + any_instance_recorders[id] = AnyInstance::Recorder.new(klass) + end + + if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2 + require 'securerandom' + + def id_for(object) + id = object.__id__ + + return id if object.equal?(::ObjectSpace._id2ref(id)) + # this suggests that object.__id__ is proxying through to some wrapped object + + object.instance_exec do + @__id_for_rspec_mocks_space ||= ::SecureRandom.uuid + end + end + else + def id_for(object) + object.__id__ + end + end + end + + # @private + class NestedSpace < Space + def initialize(parent) + @parent = parent + super() + end + + def proxies_of(klass) + super + @parent.proxies_of(klass) + end + + def constant_mutator_for(name) + super || @parent.constant_mutator_for(name) + end + + def registered?(object) + super || @parent.registered?(object) + end + + private + + def proxy_not_found_for(id, object) + @parent.proxies[id] || super + end + + def any_instance_recorder_not_found_for(id, klass) + @parent.any_instance_recorders[id] || super + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb new file mode 100644 index 0000000..74317b0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb @@ -0,0 +1,3 @@ +require 'rspec/mocks' +extend RSpec::Mocks::ExampleMethods +RSpec::Mocks.setup diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb new file mode 100644 index 0000000..2caabd1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb @@ -0,0 +1,325 @@ +module RSpec + module Mocks + # @api private + # Provides methods for enabling and disabling the available syntaxes + # provided by rspec-mocks. + module Syntax + # @private + def self.warn_about_should! + @warn_about_should = true + end + + # @private + def self.warn_unless_should_configured(method_name , replacement="the new `:expect` syntax or explicitly enable `:should`") + if @warn_about_should + RSpec.deprecate( + "Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", + :replacement => replacement + ) + + @warn_about_should = false + end + end + + # @api private + # Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). + def self.enable_should(syntax_host=default_should_syntax_host) + @warn_about_should = false if syntax_host == default_should_syntax_host + return if should_enabled?(syntax_host) + + syntax_host.class_exec do + def should_receive(message, opts={}, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.expect_message(self, message, opts, &block) + end + + def should_not_receive(message, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.expect_message(self, message, {}, &block).never + end + + def stub(message_or_hash, opts={}, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + if ::Hash === message_or_hash + message_or_hash.each { |message, value| stub(message).and_return value } + else + ::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block) + end + end + + def unstub(message) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to receive(...).and_call_original` or explicitly enable `:should`") + ::RSpec::Mocks.space.proxy_for(self).remove_stub(message) + end + + def stub_chain(*chain, &blk) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk) + end + + def as_null_object + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + @_null_object = true + ::RSpec::Mocks.space.proxy_for(self).as_null_object + end + + def null_object? + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + defined?(@_null_object) + end + + def received_message?(message, *args, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.space.proxy_for(self).received_message?(message, *args, &block) + end + + unless Class.respond_to? :any_instance + Class.class_exec do + def any_instance + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.space.any_instance_proxy_for(self) + end + end + end + end + end + + # @api private + # Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). + def self.disable_should(syntax_host=default_should_syntax_host) + return unless should_enabled?(syntax_host) + + syntax_host.class_exec do + undef should_receive + undef should_not_receive + undef stub + undef unstub + undef stub_chain + undef as_null_object + undef null_object? + undef received_message? + end + + Class.class_exec do + undef any_instance + end + end + + # @api private + # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). + def self.enable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) + return if expect_enabled?(syntax_host) + + syntax_host.class_exec do + def receive(method_name, &block) + Matchers::Receive.new(method_name, block) + end + + def receive_messages(message_return_value_hash, &_block) + matcher = Matchers::ReceiveMessages.new(message_return_value_hash) + matcher.warn_about_block if block_given? + matcher + end + + def receive_message_chain(*messages, &block) + Matchers::ReceiveMessageChain.new(messages, &block) + end + + def allow(target) + AllowanceTarget.new(target) + end + + def expect_any_instance_of(klass) + AnyInstanceExpectationTarget.new(klass) + end + + def allow_any_instance_of(klass) + AnyInstanceAllowanceTarget.new(klass) + end + end + + RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do + def expect(target) + ExpectationTarget.new(target) + end + end + end + + # @api private + # Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). + def self.disable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) + return unless expect_enabled?(syntax_host) + + syntax_host.class_exec do + undef receive + undef receive_messages + undef receive_message_chain + undef allow + undef expect_any_instance_of + undef allow_any_instance_of + end + + RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do + undef expect + end + end + + # @api private + # Indicates whether or not the should syntax is enabled. + def self.should_enabled?(syntax_host=default_should_syntax_host) + syntax_host.method_defined?(:should_receive) + end + + # @api private + # Indicates whether or not the expect syntax is enabled. + def self.expect_enabled?(syntax_host=::RSpec::Mocks::ExampleMethods) + syntax_host.method_defined?(:allow) + end + + # @api private + # Determines where the methods like `should_receive`, and `stub` are added. + def self.default_should_syntax_host + # JRuby 1.7.4 introduces a regression whereby `defined?(::BasicObject) => nil` + # yet `BasicObject` still exists and patching onto ::Object breaks things + # e.g. SimpleDelegator expectations won't work + # + # See: https://github.com/jruby/jruby/issues/814 + if defined?(JRUBY_VERSION) && JRUBY_VERSION == '1.7.4' && RUBY_VERSION.to_f > 1.8 + return ::BasicObject + end + + # On 1.8.7, Object.ancestors.last == Kernel but + # things blow up if we include `RSpec::Mocks::Methods` + # into Kernel...not sure why. + return Object unless defined?(::BasicObject) + + # MacRuby has BasicObject but it's not the root class. + return Object unless Object.ancestors.last == ::BasicObject + + ::BasicObject + end + end + end +end + +if defined?(BasicObject) + # The legacy `:should` syntax adds the following methods directly to + # `BasicObject` so that they are available off of any object. Note, however, + # that this syntax does not always play nice with delegate/proxy objects. + # We recommend you use the non-monkeypatching `:expect` syntax instead. + # @see Class + class BasicObject + # @method should_receive + # Sets an expectation that this object should receive a message before + # the end of the example. + # + # @example + # logger = double('logger') + # thing_that_logs = ThingThatLogs.new(logger) + # logger.should_receive(:log) + # thing_that_logs.do_something_that_logs_a_message + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#expect + + # @method should_not_receive + # Sets and expectation that this object should _not_ receive a message + # during this example. + # @see RSpec::Mocks::ExampleMethods#expect + + # @method stub + # Tells the object to respond to the message with the specified value. + # + # @example + # counter.stub(:count).and_return(37) + # counter.stub(:count => 37) + # counter.stub(:count) { 37 } + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#allow + + # @method unstub + # Removes a stub. On a double, the object will no longer respond to + # `message`. On a real object, the original method (if it exists) is + # restored. + # + # This is rarely used, but can be useful when a stub is set up during a + # shared `before` hook for the common case, but you want to replace it + # for a special case. + # + # @note This is only available when you have enabled the `should` syntax. + + # @method stub_chain + # @overload stub_chain(method1, method2) + # @overload stub_chain("method1.method2") + # @overload stub_chain(method1, method_to_value_hash) + # + # Stubs a chain of methods. + # + # ## Warning: + # + # Chains can be arbitrarily long, which makes it quite painless to + # violate the Law of Demeter in violent ways, so you should consider any + # use of `stub_chain` a code smell. Even though not all code smells + # indicate real problems (think fluent interfaces), `stub_chain` still + # results in brittle examples. For example, if you write + # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the + # implementation calls `foo.baz.bar`, the stub will not work. + # + # @example + # double.stub_chain("foo.bar") { :baz } + # double.stub_chain(:foo, :bar => :baz) + # double.stub_chain(:foo, :bar) { :baz } + # + # # Given any of ^^ these three forms ^^: + # double.foo.bar # => :baz + # + # # Common use in Rails/ActiveRecord: + # Article.stub_chain("recent.published") { [Article.new] } + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#receive_message_chain + + # @method as_null_object + # Tells the object to respond to all messages. If specific stub values + # are declared, they'll work as expected. If not, the receiver is + # returned. + # + # @note This is only available when you have enabled the `should` syntax. + + # @method null_object? + # Returns true if this object has received `as_null_object` + # + # @note This is only available when you have enabled the `should` syntax. + end +end + +# The legacy `:should` syntax adds the `any_instance` to `Class`. +# We generally recommend you use the newer `:expect` syntax instead, +# which allows you to stub any instance of a class using +# `allow_any_instance_of(klass)` or mock any instance using +# `expect_any_instance_of(klass)`. +# @see BasicObject +class Class + # @method any_instance + # Used to set stubs and message expectations on any instance of a given + # class. Returns a [Recorder](Recorder), which records messages like + # `stub` and `should_receive` for later playback on instances of the + # class. + # + # @example + # Car.any_instance.should_receive(:go) + # race = Race.new + # race.cars << Car.new + # race.go # assuming this delegates to all of its cars + # # this example would pass + # + # Account.any_instance.stub(:balance) { Money.new(:USD, 25) } + # Account.new.balance # => Money.new(:USD, 25)) + # + # @return [Recorder] + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#expect_any_instance_of + # @see RSpec::Mocks::ExampleMethods#allow_any_instance_of +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb new file mode 100644 index 0000000..26f7287 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb @@ -0,0 +1,124 @@ +module RSpec + module Mocks + # @private + module TargetDelegationClassMethods + def delegate_to(matcher_method) + define_method(:to) do |matcher, &block| + unless matcher_allowed?(matcher) + raise_unsupported_matcher(:to, matcher) + end + define_matcher(matcher, matcher_method, &block) + end + end + + def delegate_not_to(matcher_method, options={}) + method_name = options.fetch(:from) + define_method(method_name) do |matcher, &block| + case matcher + when Matchers::Receive, Matchers::HaveReceived + define_matcher(matcher, matcher_method, &block) + when Matchers::ReceiveMessages, Matchers::ReceiveMessageChain + raise_negation_unsupported(method_name, matcher) + else + raise_unsupported_matcher(method_name, matcher) + end + end + end + + def disallow_negation(method_name) + define_method(method_name) do |matcher, *_args| + raise_negation_unsupported(method_name, matcher) + end + end + end + + # @private + module TargetDelegationInstanceMethods + attr_reader :target + + private + + def matcher_allowed?(matcher) + Matchers::Matcher === matcher + end + + def define_matcher(matcher, name, &block) + matcher.__send__(name, target, &block) + end + + def raise_unsupported_matcher(method_name, matcher) + raise UnsupportedMatcherError, + "only the `receive`, `have_received` and `receive_messages` matchers are supported " \ + "with `#{expression}(...).#{method_name}`, but you have provided: #{matcher}" + end + + def raise_negation_unsupported(method_name, matcher) + raise NegationUnsupportedError, + "`#{expression}(...).#{method_name} #{matcher.matcher_name}` is not supported since it " \ + "doesn't really make sense. What would it even mean?" + end + end + + # @private + class TargetBase + def initialize(target) + @target = target + end + + extend TargetDelegationClassMethods + include TargetDelegationInstanceMethods + end + + # @private + module ExpectationTargetMethods + extend TargetDelegationClassMethods + include TargetDelegationInstanceMethods + + delegate_to :setup_expectation + delegate_not_to :setup_negative_expectation, :from => :not_to + delegate_not_to :setup_negative_expectation, :from => :to_not + + def expression + :expect + end + end + + # @private + class ExpectationTarget < TargetBase + include ExpectationTargetMethods + end + + # @private + class AllowanceTarget < TargetBase + def expression + :allow + end + + delegate_to :setup_allowance + disallow_negation :not_to + disallow_negation :to_not + end + + # @private + class AnyInstanceAllowanceTarget < TargetBase + def expression + :allow_any_instance_of + end + + delegate_to :setup_any_instance_allowance + disallow_negation :not_to + disallow_negation :to_not + end + + # @private + class AnyInstanceExpectationTarget < TargetBase + def expression + :expect_any_instance_of + end + + delegate_to :setup_any_instance_expectation + delegate_not_to :setup_any_instance_negative_expectation, :from => :not_to + delegate_not_to :setup_any_instance_negative_expectation, :from => :to_not + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb new file mode 100644 index 0000000..c208311 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb @@ -0,0 +1,174 @@ +module RSpec + module Mocks + # Implements the methods needed for a pure test double. RSpec::Mocks::Double + # includes this module, and it is provided for cases where you want a + # pure test double without subclassing RSpec::Mocks::Double. + module TestDouble + # Creates a new test double with a `name` (that will be used in error + # messages only) + def initialize(name=nil, stubs={}) + @__expired = false + if Hash === name && stubs.empty? + stubs = name + @name = nil + else + @name = name + end + assign_stubs(stubs) + end + + # Tells the object to respond to all messages. If specific stub values + # are declared, they'll work as expected. If not, the receiver is + # returned. + def as_null_object + __mock_proxy.as_null_object + end + + # Returns true if this object has received `as_null_object` + def null_object? + __mock_proxy.null_object? + end + + # This allows for comparing the mock to other objects that proxy such as + # ActiveRecords belongs_to proxy objects. By making the other object run + # the comparison, we're sure the call gets delegated to the proxy + # target. + def ==(other) + other == __mock_proxy + end + + # @private + def inspect + TestDoubleFormatter.format(self) + end + + # @private + def to_s + inspect.tr('<', '[').tr('>', ']') + end + + # @private + def respond_to?(message, incl_private=false) + return true if __mock_proxy.null_object? + + super + end + + # @private + def __build_mock_proxy_unless_expired(order_group) + __raise_expired_error || __build_mock_proxy(order_group) + end + + # @private + def __disallow_further_usage! + @__expired = true + end + + # Override for default freeze implementation to prevent freezing of test + # doubles. + def freeze + RSpec.warn_with("WARNING: you attempted to freeze a test double. This is explicitly a no-op as freezing doubles can lead to undesired behaviour when resetting tests.") + self + end + + private + + def method_missing(message, *args, &block) + proxy = __mock_proxy + proxy.record_message_received(message, *args, &block) + + if proxy.null_object? + case message + when :to_int then return 0 + when :to_a, :to_ary then return nil + when :to_h, :to_hash then return {} + when :to_str then return to_s + else return self + end + end + + # Defined private and protected methods will still trigger `method_missing` + # when called publicly. We want ruby's method visibility error to get raised, + # so we simply delegate to `super` in that case. + # ...well, we would delegate to `super`, but there's a JRuby + # bug, so we raise our own visibility error instead: + # https://github.com/jruby/jruby/issues/1398 + visibility = proxy.visibility_for(message) + if visibility == :private || visibility == :protected + ErrorGenerator.new(self).raise_non_public_error( + message, visibility + ) + end + + # Required wrapping doubles in an Array on Ruby 1.9.2 + raise NoMethodError if [:to_a, :to_ary].include? message + proxy.raise_unexpected_message_error(message, args) + end + + def assign_stubs(stubs) + stubs.each_pair do |message, response| + __mock_proxy.add_simple_stub(message, response) + end + end + + def __mock_proxy + ::RSpec::Mocks.space.proxy_for(self) + end + + def __build_mock_proxy(order_group) + TestDoubleProxy.new(self, order_group) + end + + def __raise_expired_error + return false unless @__expired + ErrorGenerator.new(self).raise_expired_test_double_error + end + + def initialize_copy(other) + as_null_object if other.null_object? + super + end + end + + # A generic test double object. `double`, `instance_double` and friends + # return an instance of this. + class Double + include TestDouble + end + + # @private + module TestDoubleFormatter + def self.format(dbl, unwrap=false) + format = "#{type_desc(dbl)}#{verified_module_desc(dbl)} #{name_desc(dbl)}" + return format if unwrap + "#<#{format}>" + end + + class << self + private + + def type_desc(dbl) + case dbl + when InstanceVerifyingDouble then "InstanceDouble" + when ClassVerifyingDouble then "ClassDouble" + when ObjectVerifyingDouble then "ObjectDouble" + else "Double" + end + end + + # @private + IVAR_GET = Object.instance_method(:instance_variable_get) + + def verified_module_desc(dbl) + return nil unless VerifyingDouble === dbl + "(#{IVAR_GET.bind(dbl).call(:@doubled_module).description})" + end + + def name_desc(dbl) + return "(anonymous)" unless (name = IVAR_GET.bind(dbl).call(:@name)) + name.inspect + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb new file mode 100644 index 0000000..3402967 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb @@ -0,0 +1,125 @@ +RSpec::Support.require_rspec_mocks 'verifying_proxy' + +module RSpec + module Mocks + # @private + module VerifyingDouble + def respond_to?(message, include_private=false) + return super unless null_object? + + method_ref = __mock_proxy.method_reference[message] + + case method_ref.visibility + when :public then true + when :private then include_private + when :protected then include_private || RUBY_VERSION.to_f < 2.0 + else !method_ref.unimplemented? + end + end + + def method_missing(message, *args, &block) + # Null object conditional is an optimization. If not a null object, + # validity of method expectations will have been checked at definition + # time. + if null_object? + if @__sending_message == message + __mock_proxy.ensure_implemented(message) + else + __mock_proxy.ensure_publicly_implemented(message, self) + end + + __mock_proxy.validate_arguments!(message, args) + end + + super + end + + # Redefining `__send__` causes ruby to issue a warning. + old, $VERBOSE = $VERBOSE, nil + # rubocop:disable Naming/MethodName + def __send__(name, *args, &block) + @__sending_message = name + super + ensure + @__sending_message = nil + end + # rubocop:enable Naming/MethodName + ruby2_keywords :__send__ if respond_to?(:ruby2_keywords, true) + $VERBOSE = old + + def send(name, *args, &block) + __send__(name, *args, &block) + end + ruby2_keywords :send if respond_to?(:ruby2_keywords, true) + + def initialize(doubled_module, *args) + @doubled_module = doubled_module + + possible_name = args.first + name = if String === possible_name || Symbol === possible_name + args.shift + end + + super(name, *args) + @__sending_message = nil + end + end + + # A mock providing a custom proxy that can verify the validity of any + # method stubs or expectations against the public instance methods of the + # given class. + # + # @private + class InstanceVerifyingDouble + include TestDouble + include VerifyingDouble + + def __build_mock_proxy(order_group) + VerifyingProxy.new(self, order_group, + @doubled_module, + InstanceMethodReference + ) + end + end + + # An awkward module necessary because we cannot otherwise have + # ClassVerifyingDouble inherit from Module and still share these methods. + # + # @private + module ObjectVerifyingDoubleMethods + include TestDouble + include VerifyingDouble + + def as_stubbed_const(options={}) + ConstantMutator.stub(@doubled_module.const_to_replace, self, options) + self + end + + private + + def __build_mock_proxy(order_group) + VerifyingProxy.new(self, order_group, + @doubled_module, + ObjectMethodReference + ) + end + end + + # Similar to an InstanceVerifyingDouble, except that it verifies against + # public methods of the given object. + # + # @private + class ObjectVerifyingDouble + include ObjectVerifyingDoubleMethods + end + + # Effectively the same as an ObjectVerifyingDouble (since a class is a type + # of object), except with Module in the inheritance chain so that + # transferring nested constants to work. + # + # @private + class ClassVerifyingDouble < Module + include ObjectVerifyingDoubleMethods + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb new file mode 100644 index 0000000..d6dcb57 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb @@ -0,0 +1,55 @@ +RSpec::Support.require_rspec_support 'method_signature_verifier' + +module RSpec + module Mocks + # A message expectation that knows about the real implementation of the + # message being expected, so that it can verify that any expectations + # have the valid arguments. + # @api private + class VerifyingMessageExpectation < MessageExpectation + # A level of indirection is used here rather than just passing in the + # method itself, since method look up is expensive and we only want to + # do it if actually needed. + # + # Conceptually the method reference makes more sense as a constructor + # argument since it should be immutable, but it is significantly more + # straight forward to build the object in pieces so for now it stays as + # an accessor. + attr_accessor :method_reference + + def initialize(*args) + super + end + + # @private + def with(*args, &block) + super(*args, &block).tap do + validate_expected_arguments! do |signature| + example_call_site_args = [:an_arg] * signature.min_non_kw_args + example_call_site_args << :kw_args_hash if signature.required_kw_args.any? + @argument_list_matcher.resolve_expected_args_based_on(example_call_site_args) + end + end + end + ruby2_keywords(:with) if respond_to?(:ruby2_keywords, true) + + private + + def validate_expected_arguments! + return if method_reference.nil? + + method_reference.with_signature do |signature| + args = yield signature + verifier = Support::LooseSignatureVerifier.new(signature, args) + + unless verifier.valid? + # Fail fast is required, otherwise the message expectation will fail + # as well ("expected method not called") and clobber this one. + @failed_fast = true + @error_generator.raise_invalid_arguments_error(verifier) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb new file mode 100644 index 0000000..6147b81 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb @@ -0,0 +1,221 @@ +RSpec::Support.require_rspec_mocks 'verifying_message_expectation' +RSpec::Support.require_rspec_mocks 'method_reference' + +module RSpec + module Mocks + # @private + class CallbackInvocationStrategy + def call(doubled_module) + RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| + block.call doubled_module + end + end + end + + # @private + class NoCallbackInvocationStrategy + def call(_doubled_module) + end + end + + # @private + module VerifyingProxyMethods + def add_stub(method_name, opts={}, &implementation) + ensure_implemented(method_name) + super + end + + def add_simple_stub(method_name, *args) + ensure_implemented(method_name) + super + end + + def add_message_expectation(method_name, opts={}, &block) + ensure_implemented(method_name) + super + end + + def ensure_implemented(method_name) + return unless method_reference[method_name].unimplemented? + + @error_generator.raise_unimplemented_error( + @doubled_module, + method_name, + @object + ) + end + + def ensure_publicly_implemented(method_name, _object) + ensure_implemented(method_name) + visibility = method_reference[method_name].visibility + + return if visibility == :public + @error_generator.raise_non_public_error(method_name, visibility) + end + end + + # A verifying proxy mostly acts like a normal proxy, except that it + # contains extra logic to try and determine the validity of any expectation + # set on it. This includes whether or not methods have been defined and the + # validity of arguments on method calls. + # + # In all other ways this behaves like a normal proxy. It only adds the + # verification behaviour to specific methods then delegates to the parent + # implementation. + # + # These checks are only activated if the doubled class has already been + # loaded, otherwise they are disabled. This allows for testing in + # isolation. + # + # @private + class VerifyingProxy < TestDoubleProxy + include VerifyingProxyMethods + + def initialize(object, order_group, doubled_module, method_reference_class) + super(object, order_group) + @object = object + @doubled_module = doubled_module + @method_reference_class = method_reference_class + + # A custom method double is required to pass through a way to lookup + # methods to determine their parameters. This is only relevant if the doubled + # class is loaded. + @method_doubles = Hash.new do |h, k| + h[k] = VerifyingMethodDouble.new(@object, k, self, method_reference[k]) + end + end + + def method_reference + @method_reference ||= Hash.new do |h, k| + h[k] = @method_reference_class.for(@doubled_module, k) + end + end + + def visibility_for(method_name) + method_reference[method_name].visibility + end + + def validate_arguments!(method_name, args) + @method_doubles[method_name].validate_arguments!(args) + end + end + + # @private + DEFAULT_CALLBACK_INVOCATION_STRATEGY = CallbackInvocationStrategy.new + + # @private + class VerifyingPartialDoubleProxy < PartialDoubleProxy + include VerifyingProxyMethods + + def initialize(object, expectation_ordering, optional_callback_invocation_strategy=DEFAULT_CALLBACK_INVOCATION_STRATEGY) + super(object, expectation_ordering) + @doubled_module = DirectObjectReference.new(object) + + # A custom method double is required to pass through a way to lookup + # methods to determine their parameters. + @method_doubles = Hash.new do |h, k| + h[k] = VerifyingExistingMethodDouble.for(object, k, self) + end + + optional_callback_invocation_strategy.call(@doubled_module) + end + + def ensure_implemented(_method_name) + return if Mocks.configuration.temporarily_suppress_partial_double_verification + super + end + + def method_reference + @method_doubles + end + end + + # @private + class VerifyingPartialClassDoubleProxy < VerifyingPartialDoubleProxy + include PartialClassDoubleProxyMethods + end + + # @private + class VerifyingMethodDouble < MethodDouble + def initialize(object, method_name, proxy, method_reference) + super(object, method_name, proxy) + @method_reference = method_reference + end + + def message_expectation_class + VerifyingMessageExpectation + end + + def add_expectation(*args, &block) + # explicit params necessary for 1.8.7 see #626 + super(*args, &block).tap { |x| x.method_reference = @method_reference } + end + + def add_stub(*args, &block) + # explicit params necessary for 1.8.7 see #626 + super(*args, &block).tap { |x| x.method_reference = @method_reference } + end + + def proxy_method_invoked(obj, *args, &block) + validate_arguments!(args) + super + end + ruby2_keywords :proxy_method_invoked if respond_to?(:ruby2_keywords, true) + + def validate_arguments!(actual_args) + @method_reference.with_signature do |signature| + verifier = Support::StrictSignatureVerifier.new(signature, actual_args) + raise ArgumentError, verifier.error_message unless verifier.valid? + end + end + end + + # A VerifyingMethodDouble fetches the method to verify against from the + # original object, using a MethodReference. This works for pure doubles, + # but when the original object is itself the one being modified we need to + # collapse the reference and the method double into a single object so that + # we can access the original pristine method definition. + # + # @private + class VerifyingExistingMethodDouble < VerifyingMethodDouble + def initialize(object, method_name, proxy) + super(object, method_name, proxy, self) + + @valid_method = object.respond_to?(method_name, true) + + # Trigger an eager find of the original method since if we find it any + # later we end up getting a stubbed method with incorrect arity. + save_original_implementation_callable! + end + + def with_signature + yield Support::MethodSignature.new(original_implementation_callable) + end + + def unimplemented? + !@valid_method + end + + def self.for(object, method_name, proxy) + if ClassNewMethodReference.applies_to?(method_name) { object } + VerifyingExistingClassNewMethodDouble + elsif Mocks.configuration.temporarily_suppress_partial_double_verification + MethodDouble + else + self + end.new(object, method_name, proxy) + end + end + + # Used in place of a `VerifyingExistingMethodDouble` for the specific case + # of mocking or stubbing a `new` method on a class. In this case, we substitute + # the method signature from `#initialize` since new's signature is just `*args`. + # + # @private + class VerifyingExistingClassNewMethodDouble < VerifyingExistingMethodDouble + def with_signature + yield Support::MethodSignature.new(object.instance_method(:initialize)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb new file mode 100644 index 0000000..d8bc5a9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb @@ -0,0 +1,9 @@ +module RSpec + module Mocks + # Version information for RSpec mocks. + module Version + # Version of RSpec mocks currently in use in SemVer format. + STRING = '3.13.7' + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md new file mode 100644 index 0000000..80cc104 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md @@ -0,0 +1,437 @@ +### Development +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-support-v3.13.6...3-13-maintenance) + +### 3.13.6 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.5...rspec-support-v3.13.6) + +Bug Fixes: + +* Change `RSpec::Support::HunkGenerator` to autoload rather than manual require, avoids + a load order issue. (Jon Rowe, rspec/rspec#249) + +### 3.13.5 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.4...rspec-support-v3.13.5) + +Bug Fixes: + +* Fix regression in `RSpec::Support::MethodSignature` where positional argument arity confused + a check for keyword arguments, meaning a hash would be wrongly detected as keyword arguments + when it should have been a positional argument. (Malcolm O'Hare, rspec/rspec#121) + +### 3.13.4 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.3...rspec-support-v3.13.4) + +Bug Fixes: + +* Fix homepage link in gemspec. (Jon Rowe) + +### 3.13.3 / 2025-04-30 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.2...rspec-support-v3.13.3) + +Bug Fixes: + +* Support for changes in diff-lcs and Ruby 3.4 in spec helpers. (Jon Rowe, #164 etc) + +### 3.13.2 / 2024-12-02 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.1...rspec-support-v3.13.2) + +No changes. Released during the monorepo migration to test release processes, but accidentally +contained no changes. + +### 3.13.1 / 2024-02-23 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.13.0...v3.13.1) + +Bug Fixes: + +* Exclude ruby internal require warnings from `RSpec::Support::CallerFilter#first_non_rspec_line`. + (Jon Rowe, rspec/rspec-support#593) + +### 3.13.0 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.2...v3.13.0) + +Enchancements + +* Add `RubyFeatures#supports_syntax_suggest?`. (Jon Rowe, rspec/rspec-support#571) + +Bug Fixes: + +* Allow string keys for keyword arguments during verification of method + signatures, (but only on Ruby 3+). (@malcolmohare, rspec/rspec-support#591) + +### 3.12.2 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.1...v3.12.2) + +Bug Fixes: + +* Properly surface errors from `in_sub_process`. (Jon Rowe, rspec/rspec-support#575) +* Add magic comment for freezing string literals. (Josh Nichols, rspec/rspec-support#586) + +### 3.12.1 / 2023-06-26 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.0...v3.12.1) + +Bug Fixes: + +* Fix `RSpec::Support.thread_local_data` to be Thread local but not Fiber local. + (Jon Rowe, rspec/rspec-support#581) + +### 3.12.0 / 2022-10-26 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.11.1...v3.12.0) +Enhancements: + +* Add `RSpec::Support::RubyFeatures.distincts_kw_args_from_positional_hash?` + (Jean byroot Boussier, rspec/rspec-support#535) + +### 3.11.1 / 2022-09-12 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.11.0...v3.11.1) + +Bug Fixes: + +* Fix ripper detection on TruffleRuby. (Brandon Fish, rspec/rspec-support#541) + +### 3.11.0 / 2022-02-09 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.3...v3.11.0) + +No changes. Released to support other RSpec releases. + +### 3.10.3 / 2021-11-03 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.2...v3.10.3) + +Bug Fixes: + +* Use `Mutex#owned?` to allow `RSpec::Support::ReentrantMutex` to work in + nested Fibers on Ruby 3.0 and later. (Benoit Daloze, rspec/rspec-support#503, rspec/rspec-support#504) +* Support `end`-less methods in `RSpec::Support::Source::Token` + so that RSpec won't hang when an `end`-less method raises an error. (Yuji Nakayama, rspec/rspec-support#505) + +### 3.10.2 / 2021-01-28 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.1...v3.10.2) + +Bug Fixes: + +* Fix issue with `RSpec::Support.define_optimized_require_for_rspec` on JRuby + 9.1.17.0 (Jon Rowe, rspec/rspec-support#492) + +### 3.10.1 / 2020-12-27 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.0...v3.10.1) + +Bug Fixes: + +* Fix deprecation expectations to fail correctly when + asserting on messages. (Phil Pirozhkov, rspec/rspec-support#453) + +### 3.10.0 / 2020-10-30 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.4...v3.10.0) + +No changes. Released to support other RSpec releases. + +### 3.9.4 / 2020-10-23 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.3...v3.9.4) + +Bug Fixes: + +* Flag ripper as supported on Truffle Ruby. (Brandon Fish, rspec/rspec-support#427) +* Prevent stubbing `File.read` from breaking source extraction. + (Jon Rowe, rspec/rspec-support#431) + +### 3.9.3 / 2020-05-02 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.2...v3.9.3) + +Bug Fixes: + +* Mark ripper as unsupported on Truffle Ruby. (Brandon Fish, rspec/rspec-support#395) +* Mark ripper as unsupported on JRuby 9.2.0.0. (Brian Hawley, rspec/rspec-support#400) +* Capture `Mutex.new` for our `RSpec::Support:Mutex` in order to + allow stubbing `Mutex.new`. (Jon Rowe, rspec/rspec-support#411) + +### 3.9.2 / 2019-12-30 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.1...v3.9.2) + +Bug Fixes: + +* Remove unneeded eval. (Matijs van Zuijlen, rspec/rspec-support#394) + +### 3.9.1 / 2019-12-28 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.0...v3.9.1) + +Bug Fixes: + +* Remove warning caused by keyword arguments on Ruby 2.7.0. + (Jon Rowe, rspec/rspec-support#392) + +### 3.9.0 / 2019-10-07 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.3...v3.9.0) + +*NO CHANGES* + +Version 3.9.0 was released to allow other RSpec gems to release 3.9.0. + +### 3.8.3 / 2019-10-02 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.2...v3.8.3) + +Bug Fixes: + +* Escape \r when outputting strings inside arrays. + (Tomita Masahiro, Jon Rowe, rspec/rspec-support#378) +* Ensure that optional hash arguments are recognised correctly vs keyword + arguments. (Evgeni Dzhelyov, rspec/rspec-support#366) + +### 3.8.2 / 2019-06-10 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.1...v3.8.2) + +Bug Fixes: + +* Ensure that an empty hash is recognised as empty keyword arguments when + applicable. (Thomas Walpole, rspec/rspec-support#375) +* Ensure that diffing truthy values produce diffs consistently. + (Lucas Nestor, rspec/rspec-support#377) + +### 3.8.1 / 2019-03-03 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.0...v3.8.1) + +Bug Fixes: + +* Ensure that inspecting a `SimpleDelegator` based object works regardless of + visibility of the `__getobj__` method. (Jon Rowe, rspec/rspec-support#369) + +### 3.8.0 / 2018-08-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.7.1...v3.8.0) + +Bug Fixes: + +* Order hash keys before diffing to improve diff accuracy when using mocked calls. + (James Crisp, rspec/rspec-support#334) + +### 3.7.1 / 2018-01-29 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.7.0...v3.7.1) + +Bug Fixes: + +* Fix source extraction logic so that it does not trigger a `SystemStackError` + when processing deeply nested example groups. (Craig Bass, rspec/rspec-support#343) + +### 3.7.0 / 2017-10-17 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0...v3.7.0) + +Enhancements: + +* Improve compatibility with `--enable-frozen-string-literal` option + on Ruby 2.3+. (Pat Allan, rspec/rspec-support#320) +* Add `Support.class_of` for extracting class of any object. + (Yuji Nakayama, rspec/rspec-support#325) + +Bug Fixes: + +* Fix recursive const support to not blow up when given buggy classes + that raise odd errors from `#to_str`. (Myron Marston, rspec/rspec-support#317) + +### 3.6.0 / 2017-05-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta2...3.6.0) + +Enhancements: + +* Import `Source` classes from rspec-core. (Yuji Nakayama, rspec/rspec-support#315) + +### 3.6.0.beta2 / 2016-12-12 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta1...v3.6.0.beta2) + +No user-facing changes. + +### 3.6.0.beta1 / 2016-10-09 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0...v3.6.0.beta1) + +Bug Fixes: + +* Prevent truncated formatted object output from mangling console codes. (rspec/rspec-support#294, Anson Kelly) + +### 3.5.0 / 2016-07-01 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta4...v3.5.0) + +**No user facing changes since beta4** + +### 3.5.0.beta4 / 2016-06-05 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta3...v3.5.0.beta4) + +Enhancements: +* Improve `MethodSignature` to better support keyword arguments. (rspec/rspec-support#250, Rob Smith). + +### 3.5.0.beta3 / 2016-04-02 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta2...v3.5.0.beta3) + +Bug Fixes: + +* Fix `EncodedString` to properly handle the behavior of `String#split` + on JRuby when the string contains invalid bytes. (Jon Rowe, rspec/rspec-support#268) +* Fix `ObjectFormatter` so that formatting objects that don't respond to + `#inspect` (such as `BasicObject`) does not cause `NoMethodError`. + (Yuji Nakayama, rspec/rspec-support#269) +* Fix `ObjectFormatter` so that formatting recursive array or hash does not + cause `SystemStackError`. (Yuji Nakayama, rspec/rspec-support#270, rspec/rspec-support#272) + +### 3.5.0.beta2 / 2016-03-10 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta1...v3.5.0.beta2) + +No user-facing changes. + +### 3.5.0.beta1 / 2016-02-06 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.4.1...v3.5.0.beta1) + +Enhancements: + +* Improve formatting of objects by allowing truncation to a pre-configured length. + (Liam M, rspec/rspec-support#256) + +### 3.4.1 / 2015-11-20 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.4.0...v3.4.1) + +Bug Fixes: + +* Fix `RSpec::Support::RubyFeature.ripper_supported?` so it returns + `false` on Rubinius since the Rubinius team has no plans to support + it. This prevents rspec-core from trying to load and use ripper to + extract failure snippets. (Aaron Stone, rspec/rspec-support#251) + +Changes: + +* Remove `VersionChecker` in favor of `ComparableVersion`. (Yuji Nakayama, rspec/rspec-support#266) + +### 3.4.0 / 2015-11-11 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.3.0...v3.4.0) + +Enhancements: + +* Improve formatting of `Delegator` based objects (e.g. `SimpleDelegator`) in + failure messages and diffs. (Andrew Horner, rspec/rspec-support#215) +* Add `ComparableVersion`. (Yuji Nakayama, rspec/rspec-support#245) +* Add `Ripper` support detection. (Yuji Nakayama, rspec/rspec-support#245) + +Bug Fixes: + +* Work around bug in JRuby that reports that `attr_writer` methods + have no parameters, causing RSpec's verifying doubles to wrongly + fail when mocking or stubbing a writer method on JRuby. (Myron Marston, rspec/rspec-support#225) + +### 3.3.0 / 2015-06-12 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.2...v3.3.0) + +Enhancements: + +* Improve formatting of arrays and hashes in failure messages so they + use our custom formatting of matchers, time objects, etc. + (Myron Marston, Nicholas Chmielewski, rspec/rspec-support#205) +* Use improved formatting for diffs as well. (Nicholas Chmielewski, rspec/rspec-support#205) + +Bug Fixes: + +* Fix `FuzzyMatcher` so that it checks `expected == actual` rather than + `actual == expected`, which avoids errors in situations where the + `actual` object's `==` is improperly implemented to assume that only + objects of the same type will be given. This allows rspec-mocks' + `anything` to match against objects with buggy `==` definitions. + (Myron Marston, rspec/rspec-support#193) + +### 3.2.2 / 2015-02-23 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.1...v3.2.2) + +Bug Fixes: + +* Fix an encoding issue with `EncodedString#split` when encountering an + invalid byte string. (Benjamin Fleischer, rspec/rspec-support#1760) + +### 3.2.1 / 2015-02-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.0...v3.2.1) + +Bug Fixes: + +* Fix `RSpec::CallerFilter` to work on Rubinius 2.2. + (Myron Marston, rspec/rspec-support#169) + +### 3.2.0 / 2015-02-03 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.2...v3.2.0) + +Enhancements: + +* Add extra Ruby type detection. (Jon Rowe, rspec/rspec-support#133) +* Make differ instance re-usable. (Alexey Fedorov, rspec/rspec-support#160) + +Bug Fixes: + +* Do not consider `[]` and `{}` to match when performing fuzzy matching. + (Myron Marston, rspec/rspec-support#157) + +### 3.1.2 / 2014-10-08 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.1...v3.1.2) + +Bug Fixes: + +* Fix method signature to not blow up with a `NoMethodError` on 1.8.7 when + verifying against an RSpec matcher. (Myron Marston, rspec/rspec-support#116) + +### 3.1.1 / 2014-09-26 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.0...v3.1.1) + +Bug Fixes: + +* Fix `RSpec::Support::DirectoryMaker` (used by `rspec --init` and + `rails generate rspec:install`) so that it detects absolute paths + on Windows properly. (Scott Archer, rspec/rspec-support#107, rspec/rspec-support#108, rspec/rspec-support#109) (Jon Rowe, rspec/rspec-support#110) + +### 3.1.0 / 2014-09-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.4...v3.1.0) + +Bug Fixes: + +* Fix `FuzzyMatcher` so that it does not wrongly match a struct against + an array. (Myron Marston, rspec/rspec-support#97) +* Prevent infinitely recursing `#flatten` methods from causing the differ + to hang. (Jon Rowe, rspec/rspec-support#101) + +### 3.0.4 / 2014-08-14 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.3...v3.0.4) + +Bug Fixes: + +* Fix `FuzzyMatcher` so that it does not silence `ArgumentError` raised + from broken implementations of `==`. (Myron Marston, rspec/rspec-support#94) + +### 3.0.3 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.2...v3.0.3) + +Bug Fixes: + +* Fix regression in `Support#method_handle_for` where proxy objects + with method delegated would wrongly not return a method handle. + (Jon Rowe, rspec/rspec-support#90) +* Properly detect Module#prepend support in Ruby 2.1+ (Ben Langfeld, rspec/rspec-support#91) +* Fix `rspec/support/warnings.rb` so it can be loaded and used in + isolation. (Myron Marston, rspec/rspec-support#93) + +### 3.0.2 / 2014-06-20 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.1...v3.0.2) + +* Revert `BlockSignature` change from 3.0.1 because of a ruby bug that + caused it to change the block's behavior (https://bugs.ruby-lang.org/issues/9967). + (Myron Marston, rspec-mocksrspec/rspec-support#721) + +### 3.0.1 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0...v3.0.1) + +* Fix `BlockSignature` so that it correctly differentiates between + required and optional block args. (Myron Marston, rspec-mocksrspec/rspec-support#714) + +### 3.0.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.rc1...v3.0.0) + +### 3.0.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta2...v3.0.0.rc1) + +### 3.0.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta1...v3.0.0.beta2) + +Bug Fixes: + +* Issue message when :replacement is passed to `RSpec.warn_with`. (Jon Rowe) + +### 3.0.0.beta1 / 2013-11-07 +[Full Changelog](https://github.com/rspec/rspec-support/compare/0dc12d1bdbbacc757a9989f8c09cd08ef3a4837e...v3.0.0.beta1) + +Initial release. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md new file mode 100644 index 0000000..08aa3ab --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md @@ -0,0 +1,23 @@ +The MIT License (MIT) +==================== + +* Copyright © 2013 David Chelimsky, Myron Marston, Jon Rowe, Sam Phippen, Xavier Shay, Bradley Schaefer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md new file mode 100644 index 0000000..bb88209 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md @@ -0,0 +1,40 @@ +# RSpec::Support [![Build Status](https://github.com/rspec/rspec-support/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-support/actions) + +`RSpec::Support` provides common functionality to `RSpec::Core`, +`RSpec::Expectations` and `RSpec::Mocks`. It is considered +suitable for internal use only at this time. + +## Installation / Usage + +Install one or more of the `RSpec` gems. + +Want to run against the `main` branch? You'll need to include the dependent +RSpec repos as well. Add the following to your `Gemfile`: + +```ruby +%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| + gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' +end +``` + +## Contributing + +Once you've set up the environment, you'll need to cd into the working +directory of whichever repo you want to work in. From there you can run the +specs and cucumber features, and make patches. + +NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You +can treat each RSpec repo as an independent project. + +- [Build details](BUILD_DETAIL.md) +- [Code of Conduct](CODE_OF_CONDUCT.md) +- [Detailed contributing guide](CONTRIBUTING.md) +- [Development setup guide](DEVELOPMENT.md) + +## Patches + +Please submit a pull request or a github issue. If you submit an issue, please +include a link to either of: + +* a gist (or equivalent) of the patch +* a branch or commit in your github fork of the repo diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb new file mode 100644 index 0000000..4d36414 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +module RSpec + module Support + # @api private + # + # Defines a helper method that is optimized to require files from the + # named lib. The passed block MUST be `{ |f| require_relative f }` + # because for `require_relative` to work properly from within the named + # lib the line of code must be IN that lib. + # + # `require_relative` is preferred when available because it is always O(1), + # regardless of the number of dirs in $LOAD_PATH. `require`, on the other + # hand, does a linear O(N) search over the dirs in the $LOAD_PATH until + # it can resolve the file relative to one of the dirs. + def self.define_optimized_require_for_rspec(lib, &require_relative) + name = "require_rspec_#{lib}" + + if RUBY_PLATFORM == 'java' && !Kernel.respond_to?(:require) + # JRuby 9.1.17.0 has developed a regression for require + (class << self; self; end).__send__(:define_method, name) do |f| + Kernel.send(:require, "rspec/#{lib}/#{f}") + end + elsif Kernel.respond_to?(:require_relative) + (class << self; self; end).__send__(:define_method, name) do |f| + require_relative.call("#{lib}/#{f}") + end + else + (class << self; self; end).__send__(:define_method, name) do |f| + require "rspec/#{lib}/#{f}" + end + end + end + + define_optimized_require_for_rspec(:support) { |f| require_relative(f) } + require_rspec_support "version" + require_rspec_support "ruby_features" + + # @api private + KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method) + + # @api private + # + # Used internally to get a method handle for a particular object + # and method name. + # + # Includes handling for a few special cases: + # + # - Objects that redefine #method (e.g. an HTTPRequest struct) + # - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator) + # - Objects that undefine method and delegate everything to another + # object (e.g. Mongoid association objects) + if RubyFeatures.supports_rebinding_module_methods? + def self.method_handle_for(object, method_name) + KERNEL_METHOD_METHOD.bind(object).call(method_name) + rescue NameError => original + begin + handle = object.method(method_name) + raise original unless handle.is_a? Method + handle + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + raise original + end + end + else + def self.method_handle_for(object, method_name) + if ::Kernel === object + KERNEL_METHOD_METHOD.bind(object).call(method_name) + else + object.method(method_name) + end + rescue NameError => original + begin + handle = object.method(method_name) + raise original unless handle.is_a? Method + handle + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + raise original + end + end + end + + # @api private + # + # Used internally to get a class of a given object, even if it does not respond to #class. + def self.class_of(object) + object.class + rescue NoMethodError + singleton_class = class << object; self; end + singleton_class.ancestors.find { |ancestor| !ancestor.equal?(singleton_class) } + end + + # A single thread local variable so we don't excessively pollute that namespace. + if RUBY_VERSION.to_f >= 2 + def self.thread_local_data + Thread.current.thread_variable_get(:__rspec) || Thread.current.thread_variable_set(:__rspec, {}) + end + else + def self.thread_local_data + Thread.current[:__rspec] ||= {} + end + end + + # @api private + def self.failure_notifier=(callable) + thread_local_data[:failure_notifier] = callable + end + + # @private + DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure } + + # @api private + def self.failure_notifier + thread_local_data[:failure_notifier] || DEFAULT_FAILURE_NOTIFIER + end + + # @api private + def self.notify_failure(failure, options={}) + failure_notifier.call(failure, options) + end + + # @api private + def self.with_failure_notifier(callable) + orig_notifier = failure_notifier + self.failure_notifier = callable + yield + ensure + self.failure_notifier = orig_notifier + end + + class << self + # @api private + attr_writer :warning_notifier + end + + # @private + DEFAULT_WARNING_NOTIFIER = lambda { |warning| ::Kernel.warn warning } + + # @api private + def self.warning_notifier + @warning_notifier ||= DEFAULT_WARNING_NOTIFIER + end + + # @private + module AllExceptionsExceptOnesWeMustNotRescue + # These exceptions are dangerous to rescue as rescuing them + # would interfere with things we should not interfere with. + AVOID_RESCUING = [NoMemoryError, SignalException, Interrupt, SystemExit] + + def self.===(exception) + AVOID_RESCUING.none? { |ar| ar === exception } + end + end + + # The Differ is only needed when a spec fails with a diffable failure. + # In the more common case of all specs passing or the only failures being + # non-diffable, we can avoid the extra cost of loading the differ, diff-lcs, + # pp, etc by avoiding an unnecessary require. Instead, autoload will take + # care of loading the differ on first use. + autoload :Differ, "rspec/support/differ" + autoload :HunkGenerator, "rspec/support/hunk_generator" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb new file mode 100644 index 0000000..e54b23a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support "ruby_features" + +module RSpec + # Consistent implementation for "cleaning" the caller method to strip out + # non-rspec lines. This enables errors to be reported at the call site in + # the code using the library, which is far more useful than the particular + # internal method that raised an error. + class CallerFilter + RSPEC_LIBS = %w[ + core + mocks + expectations + support + matchers + rails + ] + + ADDITIONAL_TOP_LEVEL_FILES = %w[ autorun ] + + LIB_REGEX = %r{/lib/rspec/(#{(RSPEC_LIBS + ADDITIONAL_TOP_LEVEL_FILES).join('|')})(\.rb|/)} + + # rubygems/core_ext/kernel_require.rb isn't actually part of rspec (obviously) but we want + # it ignored when we are looking for the first meaningful line of the backtrace outside + # of RSpec. It can show up in the backtrace as the immediate first caller + # when `CallerFilter.first_non_rspec_line` is called from the top level of a required + # file, but it depends on if rubygems is loaded or not. We don't want to have to deal + # with this complexity in our `RSpec.deprecate` calls, so we ignore it here. + IGNORE_REGEX = Regexp.union(LIB_REGEX, "rubygems/core_ext/kernel_require.rb", "(other) + other = self.class.new(other) unless other.is_a?(self.class) + + return 0 if string == other.string + + longer_segment_count = [self, other].map { |version| version.segments.count }.max + + longer_segment_count.times do |index| + self_segment = segments[index] || 0 + other_segment = other.segments[index] || 0 + + if self_segment.class == other_segment.class + result = self_segment <=> other_segment + return result unless result == 0 + else + return self_segment.is_a?(String) ? -1 : 1 + end + end + + 0 + end + + def segments + @segments ||= string.scan(/[a-z]+|\d+/i).map do |segment| + if segment =~ /\A\d+\z/ + segment.to_i + else + segment + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb new file mode 100644 index 0000000..9344fb3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'encoded_string' +RSpec::Support.require_rspec_support "object_formatter" + +require 'pp' + +module RSpec + module Support + # rubocop:disable Metrics/ClassLength + class Differ + def diff(actual, expected) + diff = "" + + unless actual.nil? || expected.nil? + if all_strings?(actual, expected) + if any_multiline_strings?(actual, expected) + diff = diff_as_string(coerce_to_string(actual), coerce_to_string(expected)) + end + elsif no_procs?(actual, expected) && no_numbers?(actual, expected) + diff = diff_as_object(actual, expected) + end + end + + diff.to_s + end + + # rubocop:disable Metrics/MethodLength + def diff_as_string(actual, expected) + encoding = EncodedString.pick_encoding(actual, expected) + + actual = EncodedString.new(actual, encoding) + expected = EncodedString.new(expected, encoding) + + output = EncodedString.new("\n", encoding) + hunks = build_hunks(actual, expected) + + hunks.each_cons(2) do |prev_hunk, current_hunk| + begin + if current_hunk.overlaps?(prev_hunk) + add_old_hunk_to_hunk(current_hunk, prev_hunk) + else + add_to_output(output, prev_hunk.diff(format_type).to_s) + end + ensure + add_to_output(output, "\n") + end + end + + finalize_output(output, hunks.last.diff(format_type).to_s) if hunks.last + + color_diff output + rescue Encoding::CompatibilityError + handle_encoding_errors(actual, expected) + end + # rubocop:enable Metrics/MethodLength + + def diff_as_object(actual, expected) + actual_as_string = object_to_string(actual) + expected_as_string = object_to_string(expected) + diff_as_string(actual_as_string, expected_as_string) + end + + def color? + @color + end + + def initialize(opts={}) + @color = opts.fetch(:color, false) + @object_preparer = opts.fetch(:object_preparer, lambda { |string| string }) + end + + private + + def no_procs?(*args) + safely_flatten(args).none? { |a| Proc === a } + end + + def all_strings?(*args) + safely_flatten(args).all? { |a| String === a } + end + + def any_multiline_strings?(*args) + all_strings?(*args) && safely_flatten(args).any? { |a| multiline?(a) } + end + + def no_numbers?(*args) + safely_flatten(args).none? { |a| Numeric === a } + end + + def coerce_to_string(string_or_array) + return string_or_array unless Array === string_or_array + diffably_stringify(string_or_array).join("\n") + end + + def diffably_stringify(array) + array.map do |entry| + if Array === entry + entry.inspect + else + entry.to_s.gsub("\n", "\\n").gsub("\r", "\\r") + end + end + end + + if String.method_defined?(:encoding) + def multiline?(string) + string.include?("\n".encode(string.encoding)) + end + else + def multiline?(string) + string.include?("\n") + end + end + + def build_hunks(actual, expected) + HunkGenerator.new(actual, expected).hunks + end + + def finalize_output(output, final_line) + add_to_output(output, final_line) + add_to_output(output, "\n") + end + + def add_to_output(output, string) + output << string + end + + def add_old_hunk_to_hunk(hunk, oldhunk) + hunk.merge(oldhunk) + end + + def safely_flatten(array) + array = array.flatten(1) until (array == array.flatten(1)) + array + end + + def format_type + :unified + end + + def color(text, color_code) + "\e[#{color_code}m#{text}\e[0m" + end + + def red(text) + color(text, 31) + end + + def green(text) + color(text, 32) + end + + def blue(text) + color(text, 34) + end + + def normal(text) + color(text, 0) + end + + def color_diff(diff) + return diff unless color? + + diff.lines.map do |line| + case line[0].chr + when "+" + green line + when "-" + red line + when "@" + line[1].chr == "@" ? blue(line) : normal(line) + else + normal(line) + end + end.join + end + + def object_to_string(object) + object = @object_preparer.call(object) + case object + when Hash + hash_to_string(object) + when Array + PP.pp(ObjectFormatter.prepare_for_inspection(object), "".dup) + when String + object =~ /\n/ ? object : object.inspect + else + PP.pp(object, "".dup) + end + end + + def hash_to_string(hash) + formatted_hash = ObjectFormatter.prepare_for_inspection(hash) + formatted_hash.keys.sort_by { |k| k.to_s }.map do |key| + pp_key = PP.singleline_pp(key, "".dup) + pp_value = PP.singleline_pp(formatted_hash[key], "".dup) + + "#{pp_key} => #{pp_value}," + end.join("\n") + end + + def handle_encoding_errors(actual, expected) + if actual.source_encoding != expected.source_encoding + "Could not produce a diff because the encoding of the actual string " \ + "(#{actual.source_encoding}) differs from the encoding of the expected " \ + "string (#{expected.source_encoding})" + else + "Could not produce a diff because of the encoding of the string " \ + "(#{expected.source_encoding})" + end + end + end + # rubocop:enable Metrics/ClassLength + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb new file mode 100644 index 0000000..c59d751 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'ruby_features' + +module RSpec + module Support + # @api private + # + # Replacement for fileutils#mkdir_p because we don't want to require parts + # of stdlib in RSpec. + class DirectoryMaker + # @api private + # + # Implements nested directory construction + def self.mkdir_p(path) + stack = generate_stack(path) + path.split(File::SEPARATOR).each do |part| + stack = generate_path(stack, part) + begin + Dir.mkdir(stack) unless directory_exists?(stack) + rescue Errno::EEXIST => e + raise e unless directory_exists?(stack) + rescue Errno::ENOTDIR => e + raise Errno::EEXIST, e.message + end + end + end + + if OS.windows_file_path? + def self.generate_stack(path) + if path.start_with?(File::SEPARATOR) + File::SEPARATOR + elsif path[1] == ':' + '' + else + '.' + end + end + def self.generate_path(stack, part) + if stack == '' + part + elsif stack == File::SEPARATOR + File.join('', part) + else + File.join(stack, part) + end + end + else + def self.generate_stack(path) + path.start_with?(File::SEPARATOR) ? File::SEPARATOR : "." + end + def self.generate_path(stack, part) + File.join(stack, part) + end + end + + def self.directory_exists?(dirname) + File.exist?(dirname) && File.directory?(dirname) + end + private_class_method :directory_exists? + private_class_method :generate_stack + private_class_method :generate_path + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb new file mode 100644 index 0000000..044c151 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +module RSpec + module Support + # @private + class EncodedString + # Reduce allocations by storing constants. + UTF_8 = "UTF-8" + US_ASCII = "US-ASCII" + + # Ruby's default replacement string is: + # U+FFFD ("\xEF\xBF\xBD"), for Unicode encoding forms, else + # ? ("\x3F") + REPLACE = "?" + + def initialize(string, encoding=nil) + @encoding = encoding + @source_encoding = detect_source_encoding(string) + @string = matching_encoding(string) + end + attr_reader :source_encoding + + delegated_methods = String.instance_methods.map(&:to_s) & %w[eql? lines == encoding empty?] + delegated_methods.each do |name| + define_method(name) { |*args, &block| @string.__send__(name, *args, &block) } + end + + def <<(string) + @string << matching_encoding(string) + end + + if Ruby.jruby? + def split(regex_or_string) + @string.split(matching_encoding(regex_or_string)) + rescue ArgumentError + # JRuby raises an ArgumentError when splitting a source string that + # contains invalid bytes. + remove_invalid_bytes(@string).split regex_or_string + end + else + def split(regex_or_string) + @string.split(matching_encoding(regex_or_string)) + end + end + + def to_s + @string + end + alias :to_str :to_s + + if String.method_defined?(:encoding) + + private + + # Encoding Exceptions: + # + # Raised by Encoding and String methods: + # Encoding::UndefinedConversionError: + # when a transcoding operation fails + # if the String contains characters invalid for the target encoding + # e.g. "\x80".encode('UTF-8','ASCII-8BIT') + # vs "\x80".encode('UTF-8','ASCII-8BIT', undef: :replace, replace: '') + # # => '' + # Encoding::CompatibilityError + # when Encoding.compatible?(str1, str2) is nil + # e.g. utf_16le_emoji_string.split("\n") + # e.g. valid_unicode_string.encode(utf8_encoding) << ascii_string + # Encoding::InvalidByteSequenceError: + # when the string being transcoded contains a byte invalid for + # either the source or target encoding + # e.g. "\x80".encode('UTF-8','US-ASCII') + # vs "\x80".encode('UTF-8','US-ASCII', invalid: :replace, replace: '') + # # => '' + # ArgumentError + # when operating on a string with invalid bytes + # e.g."\x80".split("\n") + # TypeError + # when a symbol is passed as an encoding + # Encoding.find(:"UTF-8") + # when calling force_encoding on an object + # that doesn't respond to #to_str + # + # Raised by transcoding methods: + # Encoding::ConverterNotFoundError: + # when a named encoding does not correspond with a known converter + # e.g. 'abc'.force_encoding('UTF-8').encode('foo') + # or a converter path cannot be found + # e.g. "\x80".force_encoding('ASCII-8BIT').encode('Emacs-Mule') + # + # Raised by byte <-> char conversions + # RangeError: out of char range + # e.g. the UTF-16LE emoji: 128169.chr + def matching_encoding(string) + string = remove_invalid_bytes(string) + string.encode(@encoding) + rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError + # Originally defined as a constant to avoid unneeded allocations, this hash must + # be defined inline (without {}) to avoid warnings on Ruby 2.7 + # + # In MRI 2.1 'invalid: :replace' changed to also replace an invalid byte sequence + # see https://github.com/ruby/ruby/blob/v2_1_0/NEWS#L176 + # https://www.ruby-forum.com/topic/6861247 + # https://twitter.com/nalsh/status/553413844685438976 + # + # For example, given: + # "\x80".force_encoding("Emacs-Mule").encode(:invalid => :replace).bytes.to_a + # + # On MRI 2.1 or above: 63 # '?' + # else : 128 # "\x80" + # + string.encode(@encoding, :invalid => :replace, :undef => :replace, :replace => REPLACE) + rescue Encoding::ConverterNotFoundError + # Originally defined as a constant to avoid unneeded allocations, this hash must + # be defined inline (without {}) to avoid warnings on Ruby 2.7 + string.dup.force_encoding(@encoding).encode(:invalid => :replace, :replace => REPLACE) + end + + # Prevents raising ArgumentError + if String.method_defined?(:scrub) + # https://github.com/ruby/ruby/blob/eeb05e8c11/doc/NEWS-2.1.0#L120-L123 + # https://github.com/ruby/ruby/blob/v2_1_0/string.c#L8242 + # https://github.com/hsbt/string-scrub + # https://github.com/rubinius/rubinius/blob/v2.5.2/kernel/common/string.rb#L1913-L1972 + def remove_invalid_bytes(string) + string.scrub(REPLACE) + end + else + # http://stackoverflow.com/a/8711118/879854 + # Loop over chars in a string replacing chars + # with invalid encoding, which is a pretty good proxy + # for the invalid byte sequence that causes an ArgumentError + def remove_invalid_bytes(string) + string.chars.map do |char| + char.valid_encoding? ? char : REPLACE + end.join + end + end + + def detect_source_encoding(string) + string.encoding + end + + def self.pick_encoding(source_a, source_b) + Encoding.compatible?(source_a, source_b) || Encoding.default_external + end + else + + def self.pick_encoding(_source_a, _source_b) + end + + private + + def matching_encoding(string) + string + end + + def detect_source_encoding(_string) + US_ASCII + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb new file mode 100644 index 0000000..46c0cab --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module RSpec + module Support + # Provides a means to fuzzy-match between two arbitrary objects. + # Understands array/hash nesting. Uses `===` or `==` to + # perform the matching. + module FuzzyMatcher + # @api private + def self.values_match?(expected, actual) + if Hash === actual + return hashes_match?(expected, actual) if Hash === expected + elsif Array === expected && Enumerable === actual && !(Struct === actual) + return arrays_match?(expected, actual.to_a) + end + + return true if expected == actual + + begin + expected === actual + rescue ArgumentError + # Some objects, like 0-arg lambdas on 1.9+, raise + # ArgumentError for `expected === actual`. + false + end + end + + # @private + def self.arrays_match?(expected_list, actual_list) + return false if expected_list.size != actual_list.size + + expected_list.zip(actual_list).all? do |expected, actual| + values_match?(expected, actual) + end + end + + # @private + def self.hashes_match?(expected_hash, actual_hash) + return false if expected_hash.size != actual_hash.size + + expected_hash.all? do |expected_key, expected_value| + actual_value = actual_hash.fetch(expected_key) { return false } + values_match?(expected_value, actual_value) + end + end + + private_class_method :arrays_match?, :hashes_match? + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb new file mode 100644 index 0000000..086a88e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'diff/lcs' +require 'diff/lcs/hunk' + +module RSpec + module Support + # @private + class HunkGenerator + def initialize(actual, expected) + @actual = actual + @expected = expected + end + + def hunks + @file_length_difference = 0 + @hunks ||= diffs.map do |piece| + build_hunk(piece) + end + end + + private + + def diffs + Diff::LCS.diff(expected_lines, actual_lines) + end + + def expected_lines + @expected.split("\n").map! { |e| e.chomp } + end + + def actual_lines + @actual.split("\n").map! { |e| e.chomp } + end + + def build_hunk(piece) + Diff::LCS::Hunk.new( + expected_lines, actual_lines, piece, context_lines, @file_length_difference + ).tap do |h| + @file_length_difference = h.file_length_difference + end + end + + def context_lines + 3 + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb new file mode 100644 index 0000000..6b7819c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module RSpec + module Support + # @private + def self.matcher_definitions + @matcher_definitions ||= [] + end + + # Used internally to break cyclic dependency between mocks, expectations, + # and support. We don't currently have a consistent implementation of our + # matchers, though we are considering changing that: + # https://github.com/rspec/rspec-mocks/issues/513 + # + # @private + def self.register_matcher_definition(&block) + matcher_definitions << block + end + + # Remove a previously registered matcher. Useful for cleaning up after + # yourself in specs. + # + # @private + def self.deregister_matcher_definition(&block) + matcher_definitions.delete(block) + end + + # @private + def self.is_a_matcher?(object) + matcher_definitions.any? { |md| md.call(object) } + end + + # @api private + # + # gives a string representation of an object for use in RSpec descriptions + def self.rspec_description_for_object(object) + if RSpec::Support.is_a_matcher?(object) && object.respond_to?(:description) + object.description + else + object + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb new file mode 100644 index 0000000..a462772 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb @@ -0,0 +1,467 @@ +# frozen_string_literal: true + +require 'rspec/support' +RSpec::Support.require_rspec_support "ruby_features" +RSpec::Support.require_rspec_support "matcher_definition" + +module RSpec + module Support + # Extracts info about the number of arguments and allowed/required + # keyword args of a given method. + # + # @private + class MethodSignature # rubocop:disable Metrics/ClassLength + attr_reader :min_non_kw_args, :max_non_kw_args, :optional_kw_args, :required_kw_args + + def initialize(method) + @method = method + @optional_kw_args = [] + @required_kw_args = [] + classify_parameters + end + + def non_kw_args_arity_description + case max_non_kw_args + when min_non_kw_args then min_non_kw_args.to_s + when INFINITY then "#{min_non_kw_args} or more" + else "#{min_non_kw_args} to #{max_non_kw_args}" + end + end + + def valid_non_kw_args?(positional_arg_count, optional_max_arg_count=positional_arg_count) + return true if positional_arg_count.nil? + + min_non_kw_args <= positional_arg_count && + optional_max_arg_count <= max_non_kw_args + end + + def classify_arity(arity=@method.arity) + if arity < 0 + # `~` inverts the one's complement and gives us the + # number of required args + @min_non_kw_args = ~arity + @max_non_kw_args = INFINITY + else + @min_non_kw_args = arity + @max_non_kw_args = arity + end + end + + if RubyFeatures.optional_and_splat_args_supported? + def description + @description ||= begin + parts = [] + + unless non_kw_args_arity_description == "0" + parts << "arity of #{non_kw_args_arity_description}" + end + + if @optional_kw_args.any? + parts << "optional keyword args (#{@optional_kw_args.map(&:inspect).join(", ")})" + end + + if @required_kw_args.any? + parts << "required keyword args (#{@required_kw_args.map(&:inspect).join(", ")})" + end + + parts << "any additional keyword args" if @allows_any_kw_args + + parts.join(" and ") + end + end + + def missing_kw_args_from(given_kw_args) + @required_kw_args - given_kw_args + end + + def invalid_kw_args_from(given_kw_args) + return [] if @allows_any_kw_args + given_kw_args - @allowed_kw_args + end + + # Considering the arg types, are there kw_args? + if RubyFeatures.kw_arg_separation? + def has_kw_args_in?(args) + # If the last arg is a hash, depending on the signature it could be kw_args or a positional parameter. + return false unless Hash === args.last && could_contain_kw_args?(args) + + # If the position of the hash is beyond the count of required and optional positional + # args then it is the kwargs hash + return true if args.count > @max_non_kw_args + + # This is the proper way to disambiguate between positional args and keywords hash + # but relies on beginning of the call chain annotating the method with + # ruby2_keywords, so only use it for positive feedback as without the annotation + # this is always false + return true if Hash.ruby2_keywords_hash?(args[-1]) + + # Otherwise, the hash could be defined kw_args or an optional positional parameter + # inspect the keys against known kwargs to determine what it is + # Note: the problem with this is that if a user passes only invalid keyword args, + # rspec no longer detects is and will assign this to a positional argument + return arbitrary_kw_args? || args.last.keys.all? { |x| @allowed_kw_args.include?(x) } + end + else + def has_kw_args_in?(args) + # Version <= Ruby 2.7 + # If the last argument is Hash, Ruby will treat only symbol keys as keyword arguments + # the rest will be grouped in another Hash and passed as positional argument. + Hash === args.last && + could_contain_kw_args?(args) && + (args.last.empty? || args.last.keys.any? { |x| x.is_a?(Symbol) }) + end + end + + # Without considering what the last arg is, could it + # contain keyword arguments? + def could_contain_kw_args?(args) + return false if args.count <= min_non_kw_args + + @allows_any_kw_args || @allowed_kw_args.any? + end + + def arbitrary_kw_args? + @allows_any_kw_args + end + + def unlimited_args? + @max_non_kw_args == INFINITY + end + + def classify_parameters + optional_non_kw_args = @min_non_kw_args = 0 + @allows_any_kw_args = false + + @method.parameters.each do |(type, name)| + case type + # def foo(a:) + when :keyreq then @required_kw_args << name + # def foo(a: 1) + when :key then @optional_kw_args << name + # def foo(**kw_args) + when :keyrest then @allows_any_kw_args = true + # def foo(a) + when :req then @min_non_kw_args += 1 + # def foo(a = 1) + when :opt then optional_non_kw_args += 1 + # def foo(*a) + when :rest then optional_non_kw_args = INFINITY + end + end + + @max_non_kw_args = @min_non_kw_args + optional_non_kw_args + @allowed_kw_args = @required_kw_args + @optional_kw_args + end + else + def description + "arity of #{non_kw_args_arity_description}" + end + + def missing_kw_args_from(_given_kw_args) + [] + end + + def invalid_kw_args_from(_given_kw_args) + [] + end + + def has_kw_args_in?(_args) + false + end + + def could_contain_kw_args?(*) + false + end + + def arbitrary_kw_args? + false + end + + def unlimited_args? + false + end + + alias_method :classify_parameters, :classify_arity + end + + INFINITY = 1 / 0.0 + end + + if RSpec::Support::Ruby.jruby? + # JRuby has only partial support for UnboundMethod#parameters, so we fall back on using #arity + # https://github.com/jruby/jruby/issues/2816 and https://github.com/jruby/jruby/issues/2817 + if RubyFeatures.optional_and_splat_args_supported? && + Java::JavaLang::String.instance_method(:char_at).parameters == [] + + class MethodSignature < remove_const(:MethodSignature) + private + + def classify_parameters + super + if (arity = @method.arity) != 0 && @method.parameters.empty? + classify_arity(arity) + end + end + end + end + + # JRuby used to always report -1 arity for Java proxy methods. + # The workaround essentially makes use of Java's introspection to figure + # out matching methods (which could be more than one partly because Java + # supports multiple overloads, and partly because JRuby introduces + # aliases to make method names look more Rubyesque). If there is only a + # single match, we can use that methods arity directly instead of the + # default -1 arity. + # + # This workaround only works for Java proxy methods, and in order to + # support regular methods and blocks, we need to be careful about calling + # owner and java_class as they might not be available + if Java::JavaLang::String.instance_method(:char_at).arity == -1 + class MethodSignature < remove_const(:MethodSignature) + private + + def classify_parameters + super + return unless @method.arity == -1 + return unless @method.respond_to?(:owner) + return unless @method.owner.respond_to?(:java_class) + java_instance_methods = @method.owner.java_class.java_instance_methods + compatible_overloads = java_instance_methods.select do |java_method| + @method == @method.owner.instance_method(java_method.name) + end + if compatible_overloads.size == 1 + classify_arity(compatible_overloads.first.arity) + end + end + end + end + end + + # Encapsulates expectations about the number of arguments and + # allowed/required keyword args of a given method. + # + # @api private + class MethodSignatureExpectation + def initialize + @min_count = nil + @max_count = nil + @keywords = [] + + @expect_unlimited_arguments = false + @expect_arbitrary_keywords = false + end + + attr_reader :min_count, :max_count, :keywords + + attr_accessor :expect_unlimited_arguments, :expect_arbitrary_keywords + + def max_count=(number) + raise ArgumentError, 'must be a non-negative integer or nil' \ + unless number.nil? || (number.is_a?(Integer) && number >= 0) + + @max_count = number + end + + def min_count=(number) + raise ArgumentError, 'must be a non-negative integer or nil' \ + unless number.nil? || (number.is_a?(Integer) && number >= 0) + + @min_count = number + end + + def empty? + @min_count.nil? && + @keywords.to_a.empty? && + !@expect_arbitrary_keywords && + !@expect_unlimited_arguments + end + + def keywords=(values) + @keywords = values.to_a || [] + end + end + + # Deals with the slightly different semantics of block arguments. + # For methods, arguments are required unless a default value is provided. + # For blocks, arguments are optional, even if no default value is provided. + # + # However, we want to treat block args as required since you virtually + # always want to pass a value for each received argument and our + # `and_yield` has treated block args as required for many years. + # + # @api private + class BlockSignature < MethodSignature + if RubyFeatures.optional_and_splat_args_supported? + def classify_parameters + super + @min_non_kw_args = @max_non_kw_args unless @max_non_kw_args == INFINITY + end + end + end + + # Abstract base class for signature verifiers. + # + # @api private + class MethodSignatureVerifier + attr_reader :non_kw_args, :kw_args, :min_non_kw_args, :max_non_kw_args + + def initialize(signature, args=[]) + @signature = signature + @non_kw_args, @kw_args = split_args(args.clone) + @min_non_kw_args = @max_non_kw_args = @non_kw_args + @arbitrary_kw_args = @unlimited_args = false + end + + def with_expectation(expectation) # rubocop:disable Metrics/MethodLength + return self unless MethodSignatureExpectation === expectation + + if expectation.empty? + @min_non_kw_args = @max_non_kw_args = @non_kw_args = nil + @kw_args = [] + else + @min_non_kw_args = @non_kw_args = expectation.min_count || 0 + @max_non_kw_args = expectation.max_count || @min_non_kw_args + + if RubyFeatures.optional_and_splat_args_supported? + @unlimited_args = expectation.expect_unlimited_arguments + else + @unlimited_args = false + end + + if RubyFeatures.kw_args_supported? + @kw_args = expectation.keywords + @arbitrary_kw_args = expectation.expect_arbitrary_keywords + else + @kw_args = [] + @arbitrary_kw_args = false + end + end + + self + end + + def valid? + missing_kw_args.empty? && + invalid_kw_args.empty? && + valid_non_kw_args? && + arbitrary_kw_args? && + unlimited_args? + end + + def error_message + if missing_kw_args.any? + "Missing required keyword arguments: %s" % [ + missing_kw_args.join(", ") + ] + elsif invalid_kw_args.any? + "Invalid keyword arguments provided: %s" % [ + invalid_kw_args.join(", ") + ] + elsif !valid_non_kw_args? + "Wrong number of arguments. Expected %s, got %s." % [ + @signature.non_kw_args_arity_description, + non_kw_args + ] + end + end + + private + + def valid_non_kw_args? + @signature.valid_non_kw_args?(min_non_kw_args, max_non_kw_args) + end + + def missing_kw_args + @signature.missing_kw_args_from(kw_args) + end + + def invalid_kw_args + @signature.invalid_kw_args_from(kw_args) + end + + def arbitrary_kw_args? + !@arbitrary_kw_args || @signature.arbitrary_kw_args? + end + + def unlimited_args? + !@unlimited_args || @signature.unlimited_args? + end + + def split_args(args) + kw_args = if @signature.has_kw_args_in?(args) && !RubyFeatures.kw_arg_separation? + last = args.pop + non_kw_args = last.reject { |k, _| k.is_a?(Symbol) } + if non_kw_args.empty? + last.keys + else + args << non_kw_args + last.select { |k, _| k.is_a?(Symbol) }.keys + end + elsif @signature.has_kw_args_in?(args) && RubyFeatures.kw_arg_separation? + args.pop.keys + else + [] + end + + [args.length, kw_args] + end + end + + # Figures out whether a given method can accept various arguments. + # Surprisingly non-trivial. + # + # @private + StrictSignatureVerifier = MethodSignatureVerifier + + # Allows matchers to be used instead of providing keyword arguments. In + # practice, when this happens only the arity of the method is verified. + # + # @private + class LooseSignatureVerifier < MethodSignatureVerifier + private + + def split_args(args) + if RSpec::Support.is_a_matcher?(args.last) && @signature.could_contain_kw_args?(args) + args.pop + @signature = SignatureWithKeywordArgumentsMatcher.new(@signature) + end + + super(args) + end + + # If a matcher is used in a signature in place of keyword arguments, all + # keyword argument validation needs to be skipped since the matcher is + # opaque. + # + # Instead, keyword arguments will be validated when the method is called + # and they are actually known. + # + # @private + class SignatureWithKeywordArgumentsMatcher + def initialize(signature) + @signature = signature + end + + def missing_kw_args_from(_kw_args) + [] + end + + def invalid_kw_args_from(_kw_args) + [] + end + + def non_kw_args_arity_description + @signature.non_kw_args_arity_description + end + + def valid_non_kw_args?(*args) + @signature.valid_non_kw_args?(*args) + end + + def has_kw_args_in?(args) + @signature.has_kw_args_in?(args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb new file mode 100644 index 0000000..63eeca4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module RSpec + module Support + # On 1.8.7, it's in the stdlib. + # We don't want to load the stdlib, b/c this is a test tool, and can affect + # the test environment, causing tests to pass where they should fail. + # + # So we're transcribing/modifying it from + # https://github.com/ruby/ruby/blob/v1_8_7_374/lib/thread.rb#L56 + # Some methods we don't need are deleted. Anything I don't + # understand (there's quite a bit, actually) is left in. + # + # Some formatting changes are made to appease the robot overlord: + # https://travis-ci.org/rspec/rspec-core/jobs/54410874 + # @private + class Mutex + def initialize + @waiting = [] + @locked = false + @waiting.taint + taint + end + + # @private + def lock + while Thread.critical = true && @locked + @waiting.push Thread.current + Thread.stop + end + @locked = true + Thread.critical = false + self + end + + # @private + def unlock + return unless @locked + Thread.critical = true + @locked = false + wakeup_and_run_waiting_thread + self + end + + # @private + def synchronize + lock + begin + yield + ensure + unlock + end + end + + private + + def wakeup_and_run_waiting_thread + begin + t = @waiting.shift + t.wakeup if t + rescue ThreadError + retry + end + Thread.critical = false + begin + t.run if t + rescue ThreadError + :noop + end + end + + # Avoid warnings for library wide checks spec + end unless defined?(::RSpec::Support::Mutex) || defined?(::Mutex) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb new file mode 100644 index 0000000..d464f1b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb @@ -0,0 +1,279 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'matcher_definition' + +module RSpec + module Support + # Provide additional output details beyond what `inspect` provides when + # printing Time, DateTime, or BigDecimal + # @api private + class ObjectFormatter # rubocop:disable Metrics/ClassLength + ELLIPSIS = "..." + + attr_accessor :max_formatted_output_length + + # Methods are deferred to a default instance of the class to maintain the interface + # For example, calling ObjectFormatter.format is still possible + def self.default_instance + @default_instance ||= new + end + + def self.format(object) + default_instance.format(object) + end + + def self.prepare_for_inspection(object) + default_instance.prepare_for_inspection(object) + end + + def initialize(max_formatted_output_length=200) + @max_formatted_output_length = max_formatted_output_length + @current_structure_stack = [] + end + + def format(object) + if max_formatted_output_length.nil? + prepare_for_inspection(object).inspect + else + formatted_object = prepare_for_inspection(object).inspect + if formatted_object.length < max_formatted_output_length + formatted_object + else + beginning = truncate_string formatted_object, 0, max_formatted_output_length / 2 + ending = truncate_string formatted_object, -max_formatted_output_length / 2, -1 + beginning + ELLIPSIS + ending + end + end + end + + # Prepares the provided object to be formatted by wrapping it as needed + # in something that, when `inspect` is called on it, will produce the + # desired output. + # + # This allows us to apply the desired formatting to hash/array data structures + # at any level of nesting, simply by walking that structure and replacing items + # with custom items that have `inspect` defined to return the desired output + # for that item. Then we can just use `Array#inspect` or `Hash#inspect` to + # format the entire thing. + def prepare_for_inspection(object) + case object + when Array + prepare_array(object) + when Hash + prepare_hash(object) + when Symbol + object + else + inspector_class = INSPECTOR_CLASSES.find { |inspector| inspector.can_inspect?(object) } + inspector_class.new(object, self) + end + end + + def prepare_array(array) + with_entering_structure(array) do + array.map { |element| prepare_element(element) } + end + end + + def prepare_hash(input_hash) + with_entering_structure(input_hash) do + sort_hash_keys(input_hash).inject({}) do |output_hash, key_and_value| + key, value = key_and_value.map { |element| prepare_element(element) } + output_hash[key] = value + output_hash + end + end + end + + def sort_hash_keys(input_hash) + if input_hash.keys.all? { |k| k.is_a?(String) || k.is_a?(Symbol) } + Hash[input_hash.sort_by { |k, _v| k.to_s }] + else + input_hash + end + end + + def prepare_element(element) + if recursive_structure?(element) + case element + when Array then InspectableItem.new('[...]') + when Hash then InspectableItem.new('{...}') + else raise # This won't happen + end + else + prepare_for_inspection(element) + end + end + + def with_entering_structure(structure) + @current_structure_stack.push(structure) + return_value = yield + @current_structure_stack.pop + return_value + end + + def recursive_structure?(object) + @current_structure_stack.any? { |seen_structure| seen_structure.equal?(object) } + end + + InspectableItem = Struct.new(:text) do + def inspect + text + end + + def pretty_print(pp) + pp.text(text) + end + end + + BaseInspector = Struct.new(:object, :formatter) do + def self.can_inspect?(_object) + raise NotImplementedError + end + + def inspect + raise NotImplementedError + end + + def pretty_print(pp) + pp.text(inspect) + end + end + + class TimeInspector < BaseInspector + FORMAT = "%Y-%m-%d %H:%M:%S" + + def self.can_inspect?(object) + Time === object + end + + if Time.method_defined?(:nsec) + def inspect + object.strftime("#{FORMAT}.#{"%09d" % object.nsec} %z") + end + else # for 1.8.7 + def inspect + object.strftime("#{FORMAT}.#{"%06d" % object.usec} %z") + end + end + end + + class DateTimeInspector < BaseInspector + FORMAT = "%a, %d %b %Y %H:%M:%S.%N %z" + + def self.can_inspect?(object) + defined?(DateTime) && DateTime === object + end + + # ActiveSupport sometimes overrides inspect. If `ActiveSupport` is + # defined use a custom format string that includes more time precision. + def inspect + if defined?(ActiveSupport) + object.strftime(FORMAT) + else + object.inspect + end + end + end + + class BigDecimalInspector < BaseInspector + def self.can_inspect?(object) + defined?(BigDecimal) && BigDecimal === object + end + + def inspect + "#{object.to_s('F')} (#{object.inspect})" + end + end + + class DescribableMatcherInspector < BaseInspector + def self.can_inspect?(object) + Support.is_a_matcher?(object) && object.respond_to?(:description) + end + + def inspect + object.description + end + end + + class UninspectableObjectInspector < BaseInspector + OBJECT_ID_FORMAT = '%#016x' + + def self.can_inspect?(object) + object.inspect + false + rescue NoMethodError + true + end + + def inspect + "#<#{klass}:#{native_object_id}>" + end + + def klass + Support.class_of(object) + end + + # http://stackoverflow.com/a/2818916 + def native_object_id + OBJECT_ID_FORMAT % (object.__id__ << 1) + rescue NoMethodError + # In Ruby 1.9.2, BasicObject responds to none of #__id__, #object_id, #id... + '-' + end + end + + class DelegatorInspector < BaseInspector + def self.can_inspect?(object) + defined?(Delegator) && Delegator === object + end + + def inspect + "#<#{object.class}(#{formatter.format(object.send(:__getobj__))})>" + end + end + + class InspectableObjectInspector < BaseInspector + def self.can_inspect?(object) + object.inspect + true + rescue NoMethodError + false + end + + def inspect + object.inspect + end + end + + INSPECTOR_CLASSES = [ + TimeInspector, + DateTimeInspector, + BigDecimalInspector, + UninspectableObjectInspector, + DescribableMatcherInspector, + DelegatorInspector, + InspectableObjectInspector + ].tap do |classes| + # 2.4 has improved BigDecimal formatting so we do not need + # to provide our own. + # https://github.com/ruby/bigdecimal/pull/42 + classes.delete(BigDecimalInspector) if RUBY_VERSION >= '2.4' + end + + private + + # Returns the substring defined by the start_index and end_index + # If the string ends with a partial ANSI code code then that + # will be removed as printing partial ANSI + # codes to the terminal can lead to corruption + def truncate_string(str, start_index, end_index) + cut_str = str[start_index..end_index] + + # ANSI color codes are like: \e[33m so anything with \e[ and a + # number without a 'm' is an incomplete color code + cut_str.sub(/\e\[\d+$/, '') + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb new file mode 100644 index 0000000..ac2910d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +module RSpec + module Support + # Provides recursive constant lookup methods useful for + # constant stubbing. + module RecursiveConstMethods + # We only want to consider constants that are defined directly on a + # particular module, and not include top-level/inherited constants. + # Unfortunately, the constant API changed between 1.8 and 1.9, so + # we need to conditionally define methods to ignore the top-level/inherited + # constants. + # + # Given: + # class A; B = 1; end + # class C < A; end + # + # On 1.8: + # - C.const_get("Hash") # => ::Hash + # - C.const_defined?("Hash") # => false + # - C.constants # => ["B"] + # - None of these methods accept the extra `inherit` argument + # On 1.9: + # - C.const_get("Hash") # => ::Hash + # - C.const_defined?("Hash") # => true + # - C.const_get("Hash", false) # => raises NameError + # - C.const_defined?("Hash", false) # => false + # - C.constants # => [:B] + # - C.constants(false) #=> [] + if Module.method(:const_defined?).arity == 1 + def const_defined_on?(mod, const_name) + mod.const_defined?(const_name) + end + + def get_const_defined_on(mod, const_name) + return mod.const_get(const_name) if const_defined_on?(mod, const_name) + + raise NameError, "uninitialized constant #{mod.name}::#{const_name}" + end + + def constants_defined_on(mod) + mod.constants.select { |c| const_defined_on?(mod, c) } + end + else + def const_defined_on?(mod, const_name) + mod.const_defined?(const_name, false) + end + + def get_const_defined_on(mod, const_name) + mod.const_get(const_name, false) + end + + def constants_defined_on(mod) + mod.constants(false) + end + end + + def recursive_const_get(const_name) + normalize_const_name(const_name).split('::').inject(Object) do |mod, name| + get_const_defined_on(mod, name) + end + end + + def recursive_const_defined?(const_name) + parts = normalize_const_name(const_name).split('::') + parts.inject([Object, '']) do |(mod, full_name), name| + yield(full_name, name) if block_given? && !(Module === mod) + return false unless const_defined_on?(mod, name) + [get_const_defined_on(mod, name), [mod.name, name].join('::')] + end + end + + def normalize_const_name(const_name) + const_name.sub(/\A::/, '') + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb new file mode 100644 index 0000000..28957a2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +module RSpec + module Support + # Allows a thread to lock out other threads from a critical section of code, + # while allowing the thread with the lock to reenter that section. + # + # Based on Monitor as of 2.2 - + # https://github.com/ruby/ruby/blob/eb7ddaa3a47bf48045d26c72eb0f263a53524ebc/lib/monitor.rb#L9 + # + # Depends on Mutex, but Mutex is only available as part of core since 1.9.1: + # exists - http://ruby-doc.org/core-1.9.1/Mutex.html + # dne - http://ruby-doc.org/core-1.9.0/Mutex.html + # + # @private + class ReentrantMutex + def initialize + @owner = nil + @count = 0 + @mutex = Mutex.new + end + + def synchronize + enter + yield + ensure + exit + end + + private + + # This is fixing a bug #501 that is specific to Ruby 3.0. The new implementation + # depends on `owned?` that was introduced in Ruby 2.0, so both should work for Ruby 2.x. + if RUBY_VERSION.to_f >= 3.0 + def enter + @mutex.lock unless @mutex.owned? + @count += 1 + end + + def exit + unless @mutex.owned? + raise ThreadError, "Attempt to unlock a mutex which is locked by another thread/fiber" + end + @count -= 1 + @mutex.unlock if @count == 0 + end + else + def enter + @mutex.lock if @owner != Thread.current + @owner = Thread.current + @count += 1 + end + + def exit + @count -= 1 + return unless @count == 0 + @owner = nil + @mutex.unlock + end + end + end + + if defined? ::Mutex + # On 1.9 and up, this is in core, so we just use the real one + class Mutex < ::Mutex + # If you mock Mutex.new you break our usage of Mutex, so + # instead we capture the original method to return Mutexes. + NEW_MUTEX_METHOD = Mutex.method(:new) + + def self.new + NEW_MUTEX_METHOD.call + end + end + else # For 1.8.7 + # :nocov: + RSpec::Support.require_rspec_support "mutex" + # :nocov: + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb new file mode 100644 index 0000000..7ccdb7e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb @@ -0,0 +1,221 @@ +# frozen_string_literal: true + +require 'rbconfig' +RSpec::Support.require_rspec_support "comparable_version" + +module RSpec + module Support + # @api private + # + # Provides query methods for different OS or OS features. + module OS + module_function + + def windows? + !!(RbConfig::CONFIG['host_os'] =~ /cygwin|mswin|mingw|bccwin|wince|emx/) + end + + def windows_file_path? + ::File::ALT_SEPARATOR == '\\' + end + end + + # @api private + # + # Provides query methods for different rubies + module Ruby + module_function + + def jruby? + RUBY_PLATFORM == 'java' + end + + def jruby_version + @jruby_version ||= ComparableVersion.new(JRUBY_VERSION) + end + + def jruby_9000? + jruby? && JRUBY_VERSION >= '9.0.0.0' + end + + def rbx? + defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' + end + + def non_mri? + !mri? + end + + def mri? + !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' + end + + def truffleruby? + defined?(RUBY_ENGINE) && RUBY_ENGINE == 'truffleruby' + end + end + + # @api private + # + # Provides query methods for ruby features that differ among + # implementations. + module RubyFeatures + module_function + + if Ruby.jruby? && RUBY_VERSION.to_f < 1.9 + # On JRuby 1.7 `--1.8` mode, `Process.respond_to?(:fork)` returns true, + # but when you try to fork, it raises an error: + # NotImplementedError: fork is not available on this platform + # + # When we drop support for JRuby 1.7 and/or Ruby 1.8, we can drop + # this special case. + def fork_supported? + false + end + else + def fork_supported? + Process.respond_to?(:fork) + end + end + + def optional_and_splat_args_supported? + Method.method_defined?(:parameters) + end + + def caller_locations_supported? + respond_to?(:caller_locations, true) + end + + if Exception.method_defined?(:cause) + def supports_exception_cause? + true + end + else + def supports_exception_cause? + false + end + end + + if RUBY_VERSION.to_f >= 3.2 + def supports_syntax_suggest? + true + end + else + def supports_syntax_suggest? + false + end + end + + if RUBY_VERSION.to_f >= 3.0 + # https://rubyreferences.github.io/rubychanges/3.0.html#keyword-arguments-are-now-fully-separated-from-positional-arguments + def kw_arg_separation? + true + end + else + def kw_arg_separation? + false + end + end + + if RUBY_VERSION.to_f >= 2.7 + def supports_taint? + false + end + else + def supports_taint? + true + end + end + ripper_requirements = [ComparableVersion.new(RUBY_VERSION) >= '1.9.2'] + + ripper_requirements.push(false) if Ruby.rbx? + + if Ruby.jruby? + ripper_requirements.push(Ruby.jruby_version >= '1.7.5') + # Ripper on JRuby 9.0.0.0.rc1 - 9.1.8.0 reports wrong line number + # or cannot parse source including `:if`. + # Ripper on JRuby 9.x.x.x < 9.1.17.0 can't handle keyword arguments + # Neither can JRuby 9.2, e.g. < 9.2.1.0 + ripper_requirements.push(!Ruby.jruby_version.between?('9.0.0.0.rc1', '9.2.0.0')) + end + + # TruffleRuby disables ripper due to low performance + ripper_requirements.push(false) if Ruby.truffleruby? + + if ripper_requirements.all? + def ripper_supported? + true + end + else + def ripper_supported? + false + end + end + + def distincts_kw_args_from_positional_hash? + RUBY_VERSION >= '3.0.0' + end + + if Ruby.mri? + def kw_args_supported? + RUBY_VERSION >= '2.0.0' + end + + def required_kw_args_supported? + RUBY_VERSION >= '2.1.0' + end + + def supports_rebinding_module_methods? + RUBY_VERSION.to_i >= 2 + end + else + # RBX / JRuby et al support is unknown for keyword arguments + begin + eval("o = Object.new; def o.m(a: 1); end;"\ + " raise SyntaxError unless o.method(:m).parameters.include?([:key, :a])") + + def kw_args_supported? + true + end + rescue SyntaxError + def kw_args_supported? + false + end + end + + begin + eval("o = Object.new; def o.m(a: ); end;"\ + "raise SyntaxError unless o.method(:m).parameters.include?([:keyreq, :a])") + + def required_kw_args_supported? + true + end + rescue SyntaxError + def required_kw_args_supported? + false + end + end + + begin + Module.new { def foo; end }.instance_method(:foo).bind(Object.new) + + def supports_rebinding_module_methods? + true + end + rescue TypeError + def supports_rebinding_module_methods? + false + end + end + end + + def module_refinement_supported? + Module.method_defined?(:refine) || Module.private_method_defined?(:refine) + end + + def module_prepends_supported? + Module.method_defined?(:prepend) || Module.private_method_defined?(:prepend) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb new file mode 100644 index 0000000..8aad27b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'encoded_string' +RSpec::Support.require_rspec_support 'ruby_features' + +module RSpec + module Support + # @private + # Represents a Ruby source file and provides access to AST and tokens. + class Source + attr_reader :source, :path + + # This class protects us against having File read and expand_path + # stubbed out within tests. + class File + class << self + [:read, :expand_path].each do |method_name| + define_method(method_name, &::File.method(method_name)) + end + end + end + + def self.from_file(path) + source = File.read(path) + new(source, path) + end + + if String.method_defined?(:encoding) + def initialize(source_string, path=nil) + @source = RSpec::Support::EncodedString.new(source_string, Encoding.default_external) + @path = path ? File.expand_path(path) : '(string)' + end + else # for 1.8.7 + # :nocov: + def initialize(source_string, path=nil) + @source = RSpec::Support::EncodedString.new(source_string) + @path = path ? File.expand_path(path) : '(string)' + end + # :nocov: + end + + def lines + @lines ||= source.split("\n") + end + + def inspect + "#<#{self.class} #{path}>" + end + + if RSpec::Support::RubyFeatures.ripper_supported? + RSpec::Support.require_rspec_support 'source/node' + RSpec::Support.require_rspec_support 'source/token' + + def ast + @ast ||= begin + require 'ripper' + sexp = Ripper.sexp(source) + raise SyntaxError unless sexp + Node.new(sexp) + end + end + + def tokens + @tokens ||= begin + require 'ripper' + tokens = Ripper.lex(source) + Token.tokens_from_ripper_tokens(tokens) + end + end + + def nodes_by_line_number + @nodes_by_line_number ||= begin + nodes_by_line_number = ast.select(&:location).group_by { |node| node.location.line } + Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number) + end + end + + def tokens_by_line_number + @tokens_by_line_number ||= begin + nodes_by_line_number = tokens.group_by { |token| token.location.line } + Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb new file mode 100644 index 0000000..fb5a377 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module RSpec + module Support + class Source + # @private + # Represents a source location of node or token. + Location = Struct.new(:line, :column) do + include Comparable + + def self.location?(array) + array.is_a?(Array) && array.size == 2 && array.all? { |e| e.is_a?(Integer) } + end + + def <=>(other) + line_comparison = (line <=> other.line) + return line_comparison unless line_comparison == 0 + column <=> other.column + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb new file mode 100644 index 0000000..359bf9f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'source/location' + +module RSpec + module Support + class Source + # @private + # A wrapper for Ripper AST node which is generated with `Ripper.sexp`. + class Node + include Enumerable + + attr_reader :sexp, :parent + + def self.sexp?(array) + array.is_a?(Array) && array.first.is_a?(Symbol) + end + + def initialize(ripper_sexp, parent=nil) + @sexp = ripper_sexp.freeze + @parent = parent + end + + def type + sexp[0] + end + + def args + @args ||= raw_args.map do |raw_arg| + if Node.sexp?(raw_arg) + Node.new(raw_arg, self) + elsif Location.location?(raw_arg) + Location.new(*raw_arg) + elsif raw_arg.is_a?(Array) + ExpressionSequenceNode.new(raw_arg, self) + else + raw_arg + end + end.freeze + end + + def children + @children ||= args.select { |arg| arg.is_a?(Node) }.freeze + end + + def location + @location ||= args.find { |arg| arg.is_a?(Location) } + end + + # We use a loop here (instead of recursion) to prevent SystemStackError + def each + return to_enum(__method__) unless block_given? + + node_queue = [] + node_queue << self + + while (current_node = node_queue.shift) + yield current_node + node_queue.concat(current_node.children) + end + end + + def each_ancestor + return to_enum(__method__) unless block_given? + + current_node = self + + while (current_node = current_node.parent) + yield current_node + end + end + + def inspect + "#<#{self.class} #{type}>" + end + + private + + def raw_args + sexp[1..-1] || [] + end + end + + # @private + # Basically `Ripper.sexp` generates arrays whose first element is a symbol (type of sexp), + # but it exceptionally generates typeless arrays for expression sequence: + # + # Ripper.sexp('foo; bar') + # => [ + # :program, + # [ # Typeless array + # [:vcall, [:@ident, "foo", [1, 0]]], + # [:vcall, [:@ident, "bar", [1, 5]]] + # ] + # ] + # + # We wrap typeless arrays in this pseudo type node + # so that it can be handled in the same way as other type node. + class ExpressionSequenceNode < Node + def type + :_expression_sequence + end + + private + + def raw_args + sexp + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb new file mode 100644 index 0000000..ca887a7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'source/location' + +module RSpec + module Support + class Source + # @private + # A wrapper for Ripper token which is generated with `Ripper.lex`. + class Token + CLOSING_TYPES_BY_OPENING_TYPE = { + :on_lbracket => :on_rbracket, + :on_lparen => :on_rparen, + :on_lbrace => :on_rbrace, + :on_heredoc_beg => :on_heredoc_end + }.freeze + + CLOSING_KEYWORDS_BY_OPENING_KEYWORD = { + 'def' => 'end', + 'do' => 'end', + }.freeze + + attr_reader :token + + def self.tokens_from_ripper_tokens(ripper_tokens) + ripper_tokens.map { |ripper_token| new(ripper_token) }.freeze + end + + def initialize(ripper_token) + @token = ripper_token.freeze + end + + def location + @location ||= Location.new(*token[0]) + end + + def type + token[1] + end + + def string + token[2] + end + + def ==(other) + token == other.token + end + + alias_method :eql?, :== + + def inspect + "#<#{self.class} #{type} #{string.inspect}>" + end + + def keyword? + type == :on_kw + end + + def equals_operator? + type == :on_op && string == '=' + end + + def opening? + opening_delimiter? || opening_keyword? + end + + def closed_by?(other) + delimiter_closed_by?(other) || keyword_closed_by?(other) + end + + private + + def opening_delimiter? + CLOSING_TYPES_BY_OPENING_TYPE.key?(type) + end + + def opening_keyword? + return false unless keyword? + CLOSING_KEYWORDS_BY_OPENING_KEYWORD.key?(string) + end + + def delimiter_closed_by?(other) + other.type == CLOSING_TYPES_BY_OPENING_TYPE[type] + end + + def keyword_closed_by?(other) + return false unless keyword? + return true if other.string == CLOSING_KEYWORDS_BY_OPENING_KEYWORD[string] + + # Ruby 3's `end`-less method definition: `def method_name = body` + string == 'def' && other.equals_operator? && location.line == other.location.line + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb new file mode 100644 index 0000000..5468cf9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'rspec/support' +require 'rspec/support/spec/in_sub_process' + +RSpec::Support.require_rspec_support "spec/deprecation_helpers" +RSpec::Support.require_rspec_support "spec/diff_helpers" +RSpec::Support.require_rspec_support "spec/with_isolated_stderr" +RSpec::Support.require_rspec_support "spec/stderr_splitter" +RSpec::Support.require_rspec_support "spec/formatting_support" +RSpec::Support.require_rspec_support "spec/with_isolated_directory" +RSpec::Support.require_rspec_support "ruby_features" + +warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr) + +RSpec.configure do |c| + c.include RSpecHelpers + c.include RSpec::Support::WithIsolatedStdErr + c.include RSpec::Support::FormattingSupport + c.include RSpec::Support::InSubProcess + + unless defined?(Debugger) # debugger causes warnings when used + c.before do + warning_preventer.reset! + end + + c.after do + warning_preventer.verify_no_warnings! + end + end + + if c.files_to_run.one? + c.full_backtrace = true + c.default_formatter = 'doc' + end + + c.filter_run_when_matching :focus + + c.example_status_persistence_file_path = "./spec/examples.txt" + + c.define_derived_metadata :failing_on_windows_ci do |meta| + meta[:pending] ||= "This spec fails on Windows CI and needs someone to fix it." + end if RSpec::Support::OS.windows? && ENV['CI'] +end + +module RSpec + module Support + module Spec + def self.setup_simplecov(&block) + # Simplecov emits some ruby warnings when loaded, so silence them. + old_verbose, $VERBOSE = $VERBOSE, false + + return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3' + return if RUBY_ENGINE != 'ruby' || RSpec::Support::OS.windows? + + # Don't load it when we're running a single isolated + # test file rather than the whole suite. + return if RSpec.configuration.files_to_run.one? + + require 'simplecov' + start_simplecov(&block) + rescue LoadError + warn "Simplecov could not be loaded" + ensure + $VERBOSE = old_verbose + end + + def self.start_simplecov(&block) + SimpleCov.start do + add_filter "bundle/" + add_filter "tmp/" + add_filter do |source_file| + # Filter out `spec` directory except when it is under `lib` + # (as is the case in rspec-support) + source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/') + end + + instance_eval(&block) if block + end + end + private_class_method :start_simplecov + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb new file mode 100644 index 0000000..f7458c3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module RSpecHelpers + def expect_deprecation_with_call_site(file, line, snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:deprecated => match(snippet), :call_site => include([file, line].join(':')))) + end + + def expect_deprecation_without_call_site(snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:deprecated => match(snippet), :call_site => eq(nil))) + end + + def expect_warn_deprecation_with_call_site(file, line, snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:message => match(snippet), :call_site => include([file, line].join(':')))) + end + + def expect_warn_deprecation(snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:message => match(snippet))) + end + + def allow_deprecation + allow(RSpec.configuration.reporter).to receive(:deprecation) + end + + def expect_no_deprecations + expect(RSpec.configuration.reporter).not_to receive(:deprecation) + end + alias expect_no_deprecation expect_no_deprecations + + def expect_warning_without_call_site(expected=//) + expect(::Kernel).to receive(:warn). + with(match(expected).and(satisfy { |message| !(/Called from/ =~ message) })) + end + + def expect_warning_with_call_site(file, line, expected=//) + expect(::Kernel).to receive(:warn). + with(match(expected).and(match(/Called from #{file}:#{line}/))) + end + + def expect_no_warnings + expect(::Kernel).not_to receive(:warn) + end + + def allow_warning + allow(::Kernel).to receive(:warn) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb new file mode 100644 index 0000000..58e0712 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'diff/lcs' + +module RSpec + module Support + module Spec + module DiffHelpers + # In the updated version of diff-lcs several diff headers change format slightly + # compensate for this and change minimum version in RSpec 4 + if ::Diff::LCS::VERSION.to_f < 1.4 + def one_line_header(line_number=2) + "-1,#{line_number} +1,#{line_number}" + end + elsif ::Diff::LCS::VERSION.to_f < 1.6 + def one_line_header(_=2) + "-1 +1" + end + else + def one_line_header(line_number=2) + if line_number - 1 == 1 + "-1 +1" + else + "-1,#{line_number - 1} +1,#{line_number - 1}" + end + end + end + + if ::Diff::LCS::VERSION.to_f > 1.5 + def removing_two_line_header + "-1,2 +0,0" + end + elsif Diff::LCS::VERSION.to_f < 1.4 || Diff::LCS::VERSION >= "1.4.4" + def removing_two_line_header + "-1,3 +1" + end + else + def removing_two_line_header + "-1,3 +1,5" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb new file mode 100644 index 0000000..a773a20 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module RSpec + module Support + module FormattingSupport + def dedent(string) + string.gsub(/^\s+\|/, '').chomp + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb new file mode 100644 index 0000000..4130225 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +module RSpec + module Support + module InSubProcess + if Process.respond_to?(:fork) && !(Ruby.jruby? && RUBY_VERSION == '1.8.7') + + UnmarshableObject = Struct.new(:error) + + # Useful as a way to isolate a global change to a subprocess. + + def in_sub_process(prevent_warnings=true) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + exception_reader, exception_writer = IO.pipe + result_reader, result_writer = IO.pipe + + # Set binary mode to avoid errors surrounding ascii-8bit to utf-8 conversion + # this happens with warnings on rspec-rails for example + [exception_reader, exception_writer, result_reader, result_writer].each { |io| io.binmode } + + pid = Process.fork do + warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr) + + begin + result = yield + warning_preventer.verify_no_warnings! if prevent_warnings + # rubocop:disable Lint/HandleExceptions + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => exception + # rubocop:enable Lint/HandleExceptions + end + + exception_writer.write marshal_dump_with_unmarshable_object_handling(exception) + exception_reader.close + exception_writer.close + + result_writer.write marshal_dump_with_unmarshable_object_handling(result) + result_reader.close + result_writer.close + + exit! # prevent at_exit hooks from running (e.g. minitest) + end + + exception_writer.close + result_writer.close + Process.waitpid(pid) + + exception = Marshal.load(exception_reader.read) + exception_reader.close + raise exception if exception + + result = Marshal.load(result_reader.read) + result_reader.close + result + end + alias :in_sub_process_if_possible :in_sub_process + + def marshal_dump_with_unmarshable_object_handling(object) + Marshal.dump(object) + rescue TypeError => error + Marshal.dump(UnmarshableObject.new(error)) + end + else + def in_sub_process(*) + skip "This spec requires forking to work properly, " \ + "and your platform does not support forking" + end + + def in_sub_process_if_possible(*) + yield + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb new file mode 100644 index 0000000..d424525 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +require 'rspec/support/spec/shell_out' + +module RSpec + module Support + module WhitespaceChecks + # This malformed whitespace detection logic has been borrowed from bundler: + # https://github.com/bundler/bundler/blob/v1.8.0/spec/quality_spec.rb + def check_for_tab_characters(filename) + failing_lines = [] + File.readlines(filename).each_with_index do |line, number| + failing_lines << number + 1 if line =~ /\t/ + end + + return if failing_lines.empty? + "#{filename} has tab characters on lines #{failing_lines.join(', ')}" + end + + def check_for_extra_spaces(filename) + failing_lines = [] + File.readlines(filename).each_with_index do |line, number| + next if line =~ /^\s+#.*\s+\n$/ + failing_lines << number + 1 if line =~ /\s+\n$/ + end + + return if failing_lines.empty? + "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}" + end + end + end +end + +RSpec.shared_examples_for "library wide checks" do |lib, options| + consider_a_test_env_file = options.fetch(:consider_a_test_env_file, /MATCHES NOTHING/) + allowed_loaded_feature_regexps = options.fetch(:allowed_loaded_feature_regexps, []) + preamble_for_lib = options[:preamble_for_lib] + preamble_for_spec = "require 'rspec/core'; require 'spec_helper'" + skip_spec_files = options.fetch(:skip_spec_files, /MATCHES NOTHING/) + + include RSpec::Support::ShellOut + include RSpec::Support::WhitespaceChecks + + define_method :files_to_require_for do |sub_dir| + slash = File::SEPARATOR + lib_path_re = /#{slash + lib}[^#{slash}]*#{slash}lib/ + load_path = $LOAD_PATH.grep(lib_path_re).first + directory = load_path.sub(/lib$/, sub_dir) + files = Dir["#{directory}/**/*.rb"] + extract_regex = /#{Regexp.escape(directory) + File::SEPARATOR}(.+)\.rb$/ + + # We sort to ensure the files are loaded in a consistent order, regardless + # of OS. Otherwise, it could load in a different order on Travis than + # locally, and potentially trigger a "circular require considered harmful" + # warning or similar. + files.sort.map { |file| file[extract_regex, 1] } + end + + def command_from(code_lines) + code_lines.join("\n") + end + + def load_all_files(files, preamble, postamble=nil) + requires = files.map { |f| "require '#{f}'" } + command = command_from(Array(preamble) + requires + Array(postamble)) + + stdout, stderr, status = with_env 'NO_COVERAGE' => '1' do + options = %w[ -w ] + options << "--disable=gem" if RUBY_VERSION.to_f >= 1.9 && RSpec::Support::Ruby.mri? + run_ruby_with_current_load_path(command, *options) + end + + [stdout, strip_known_warnings(stderr), status.exitstatus] + end + + define_method :load_all_lib_files do + files = all_lib_files - lib_test_env_files + preamble = ['orig_loaded_features = $".dup', preamble_for_lib] + postamble = ['puts(($" - orig_loaded_features).join("\n"))'] + + @loaded_feature_lines, stderr, exitstatus = load_all_files(files, preamble, postamble) + ["", stderr, exitstatus] + end + + define_method :load_all_spec_files do + files = files_to_require_for("spec") + lib_test_env_files + files = files.reject { |f| f =~ skip_spec_files } + load_all_files(files, preamble_for_spec) + end + + attr_reader :all_lib_files, :lib_test_env_files, + :lib_file_results, :spec_file_results + + before(:context) do + @all_lib_files = files_to_require_for("lib") + @lib_test_env_files = all_lib_files.grep(consider_a_test_env_file) + + @lib_file_results, @spec_file_results = [ + # Load them in parallel so it's faster... + Thread.new { load_all_lib_files }, + Thread.new { load_all_spec_files } + ].map(&:join).map(&:value) + end + + def have_successful_no_warnings_output + eq ["", "", 0] + end + + it "issues no warnings when loaded", :slow do + expect(lib_file_results).to have_successful_no_warnings_output + end + + it "issues no warnings when the spec files are loaded", :slow do + expect(spec_file_results).to have_successful_no_warnings_output + end + + it 'only loads a known set of stdlibs so gem authors are forced ' \ + 'to load libs they use to have passing specs', :slow do + loaded_features = @loaded_feature_lines.split("\n") + if RUBY_VERSION == '1.8.7' + # On 1.8.7, $" returns the relative require path if that was used + # to require the file. LIB_REGEX will not match the relative version + # since it has a `/lib` prefix. Here we deal with this by expanding + # relative files relative to the $LOAD_PATH dir (lib). + Dir.chdir("lib") { loaded_features.map! { |f| File.expand_path(f) } } + end + + loaded_features.reject! { |feature| RSpec::CallerFilter::LIB_REGEX =~ feature } + loaded_features.reject! { |feature| allowed_loaded_feature_regexps.any? { |r| r =~ feature } } + + expect(loaded_features).to eq([]) + end + + RSpec::Matchers.define :be_well_formed do + match do |actual| + actual.empty? + end + + failure_message do |actual| + actual.join("\n") + end + end + + it "has no malformed whitespace", :slow do + error_messages = [] + `git ls-files -z`.split("\x0").each do |filename| + error_messages << check_for_tab_characters(filename) + error_messages << check_for_extra_spaces(filename) + end + expect(error_messages.compact).to be_well_formed + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb new file mode 100644 index 0000000..3727c8a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb @@ -0,0 +1,115 @@ +# frozen_string_literal: true + +require 'open3' +require 'rake/file_utils' +require 'shellwords' + +module RSpec + module Support + module ShellOut + def with_env(vars) + original = ENV.to_hash + vars.each { |k, v| ENV[k] = v } + + begin + yield + ensure + ENV.replace(original) + end + end + + if Open3.respond_to?(:capture3) # 1.9+ + def shell_out(*command) + stdout, stderr, status = Open3.capture3(*command) + return stdout, filter(stderr), status + end + else # 1.8.7 + # popen3 doesn't provide the exit status so we fake it out. + FakeProcessStatus = Struct.new(:exitstatus) + + def shell_out(*command) + stdout = stderr = nil + + Open3.popen3(*command) do |_in, out, err| + stdout = out.read + stderr = err.read + end + + status = FakeProcessStatus.new(0) + return stdout, filter(stderr), status + end + end + + def run_ruby_with_current_load_path(ruby_command, *flags) + command = [ + FileUtils::RUBY, + "-I#{$LOAD_PATH.map(&:shellescape).join(File::PATH_SEPARATOR)}", + "-e", ruby_command, *flags + ] + + # Unset these env vars because `ruby -w` will issue warnings whenever + # they are set to non-default values. + with_env 'RUBY_GC_HEAP_FREE_SLOTS' => nil, 'RUBY_GC_MALLOC_LIMIT' => nil, + 'RUBY_FREE_MIN' => nil do + shell_out(*command) + end + end + + LINES_TO_IGNORE = + [ + # Ignore bundler warning. + %r{bundler/source/rubygems}, + # Ignore bundler + rubygems warning. + %r{site_ruby/\d\.\d\.\d/rubygems}, + %r{site_ruby/\d\.\d\.\d/bundler}, + %r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/rubygems}, + %r{lib/rubygems/custom_require}, + # This is required for windows for some reason + %r{lib/bundler/rubygems}, + # This is a JRuby file that generates warnings on 9.0.3.0 + %r{lib/ruby/stdlib/jar}, + # This is a JRuby file that generates warnings on 9.1.7.0 + %r{org/jruby/RubyKernel\.java}, + # This is a JRuby gem that generates warnings on 9.1.7.0 + %r{ffi-1\.13\.\d+-java}, + %r{uninitialized constant FFI}, + # These are related to the above, there is a warning about io from FFI + %r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/io}, + %r{io/console on JRuby shells out to stty for most operations}, + # This is a JRuby 9.1.17.0 error on Github Actions + %r{io/console not supported; tty will not be manipulated}, + # This is a JRuby 9.2.1.x error + %r{jruby/kernel/gem_prelude}, + %r{lib/jruby\.jar!/jruby/preludes}, + # Ignore some JRuby errors for gems + %r{jruby/\d\.\d(\.\d)?/gems/aruba}, + %r{jruby/\d\.\d(\.\d)?/gems/ffi}, + %r{warning: encoding options not supported in 1\.8}, + # Ignore errors from asdf + %r{\.asdf/installs}, + ] + + def strip_known_warnings(input) + input.split("\n").reject do |l| + LINES_TO_IGNORE.any? { |to_ignore| l =~ to_ignore } || + # Remove blank lines + l == "" || l.nil? + end.join("\n") + end + + private + + if Ruby.jruby? + def filter(output) + output.each_line.reject do |line| + line.include?("lib/ruby/shared/rubygems") + end.join($/) + end + else + def filter(output) + output + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb new file mode 100644 index 0000000..9caa34c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'stringio' + +module RSpec + module Support + class StdErrSplitter + def initialize(original) + @orig_stderr = original + @output_tracker = ::StringIO.new + @last_line = nil + end + + respond_to_name = (::RUBY_VERSION.to_f < 1.9) ? :respond_to? : :respond_to_missing? + define_method respond_to_name do |*args| + @orig_stderr.respond_to?(*args) || super(*args) + end + + def method_missing(name, *args, &block) + @output_tracker.__send__(name, *args, &block) if @output_tracker.respond_to?(name) + @orig_stderr.__send__(name, *args, &block) + end + + def ==(other) + @orig_stderr == other + end + + def reopen(*args) + reset! + @orig_stderr.reopen(*args) + end + + # To work around JRuby error: + # can't convert RSpec::Support::StdErrSplitter into String + def to_io + @orig_stderr.to_io + end + + # To work around JRuby error: + # TypeError: $stderr must have write method, RSpec::StdErrSplitter given + def write(line) + return if line =~ %r{^\S+/gems/\S+:\d+: warning:} # http://rubular.com/r/kqeUIZOfPG + + # Ruby 2.7.0 warnings from keyword arguments span multiple lines, extend check above + # to look for the next line. + return if @last_line =~ %r{^\S+/gems/\S+:\d+: warning:} && + line =~ %r{warning: The called method .* is defined here} + + # Ruby 2.7.0 complains about hashes used in place of keyword arguments + # Aruba 0.14.2 uses this internally triggering that here + return if line =~ %r{lib/ruby/2\.7\.0/fileutils\.rb:622: warning:} + + @orig_stderr.write(line) + @output_tracker.write(line) + ensure + @last_line = line + end + + def has_output? + !output.empty? + end + + def reset! + @output_tracker = ::StringIO.new + end + + def verify_no_warnings! + raise "Warnings were generated: #{output}" if has_output? + reset! + end + + def output + @output_tracker.string + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb new file mode 100644 index 0000000..b8c0c71 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'rspec/matchers' +# Special matcher for comparing encoded strings so that +# we don't run any expectation failures through the Differ, +# which also relies on EncodedString. Instead, confirm the +# strings have the same bytes. +RSpec::Matchers.define :be_identical_string do |expected| + if String.method_defined?(:encoding) + match do + expected_encoding? && + actual.bytes.to_a == expected.bytes.to_a + end + + failure_message do + "expected\n#{actual.inspect} (#{actual.encoding.name}) to be identical to\n"\ + "#{expected.inspect} (#{expected.encoding.name})\n"\ + "The exact bytes are printed below for more detail:\n"\ + "#{actual.bytes.to_a}\n"\ + "#{expected.bytes.to_a}\n"\ + end + + # Depends on chaining :with_same_encoding for it to + # check for string encoding. + def expected_encoding? + if defined?(@expect_same_encoding) && @expect_same_encoding + actual.encoding == expected.encoding + else + true + end + end + else + match do + actual.split(//) == expected.split(//) + end + + failure_message do + "expected\n#{actual.inspect} to be identical to\n#{expected.inspect}\n" + end + end + + chain :with_same_encoding do + @expect_same_encoding ||= true + end +end +RSpec::Matchers.alias_matcher :a_string_identical_to, :be_identical_string +RSpec::Matchers.alias_matcher :be_diffed_as, :be_identical_string diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb new file mode 100644 index 0000000..f81a7df --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'tmpdir' + +RSpec.shared_context "isolated directory" do + around do |ex| + Dir.mktmpdir do |tmp_dir| + Dir.chdir(tmp_dir, &ex) + end + end +end + +RSpec.configure do |c| + c.include_context "isolated directory", :isolated_directory => true +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb new file mode 100644 index 0000000..ef62be4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module RSpec + module Support + module WithIsolatedStdErr + def with_isolated_stderr + original = $stderr + $stderr = StringIO.new + yield + ensure + $stderr = original + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb new file mode 100644 index 0000000..20db6c7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module RSpec + module Support + module Version + STRING = '3.13.6' + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb new file mode 100644 index 0000000..31783d9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'rspec/support' +RSpec::Support.require_rspec_support "caller_filter" + +module RSpec + module Support + module Warnings + def deprecate(deprecated, options={}) + warn_with "DEPRECATION: #{deprecated} is deprecated.", options + end + + # @private + # + # Used internally to print deprecation warnings + # when rspec-core isn't loaded + def warn_deprecation(message, options={}) + warn_with "DEPRECATION: \n #{message}", options + end + + # @private + # + # Used internally to print warnings + def warning(text, options={}) + warn_with "WARNING: #{text}.", options + end + + # @private + # + # Used internally to print longer warnings + def warn_with(message, options={}) + call_site = options.fetch(:call_site) { CallerFilter.first_non_rspec_line } + message += " Use #{options[:replacement]} instead." if options[:replacement] + message += " Called from #{call_site}." if call_site + Support.warning_notifier.call message + end + end + end + + extend RSpec::Support::Warnings +end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb new file mode 100644 index 0000000..bec99f4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support("method_signature_verifier") + +module RSpec + module Support + module WithKeywordsWhenNeeded + # This module adds keyword sensitive support for core ruby methods + # where we cannot use `ruby2_keywords` directly. + + module_function + + if RSpec::Support::RubyFeatures.kw_args_supported? + # Remove this in RSpec 4 in favour of explicitly passed in kwargs where + # this is used. Works around a warning in Ruby 2.7 + + def class_exec(klass, *args, &block) + if MethodSignature.new(block).has_kw_args_in?(args) + binding.eval(<<-CODE, __FILE__, __LINE__) + kwargs = args.pop + klass.class_exec(*args, **kwargs, &block) + CODE + else + klass.class_exec(*args, &block) + end + end + ruby2_keywords :class_exec if respond_to?(:ruby2_keywords, true) + else + def class_exec(klass, *args, &block) + klass.class_exec(*args, &block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec b/vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec new file mode 100644 index 0000000..7574737 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec @@ -0,0 +1,35 @@ +# -*- encoding: utf-8 -*- +# stub: diff-lcs 1.6.2 ruby lib + +Gem::Specification.new do |s| + s.name = "diff-lcs".freeze + s.version = "1.6.2" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/halostatue/diff-lcs/issues", "changelog_uri" => "https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md", "homepage_uri" => "https://github.com/halostatue/diff-lcs", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/halostatue/diff-lcs" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Austin Ziegler".freeze] + s.date = "2025-05-12" + s.description = "Diff::LCS computes the difference between two Enumerable sequences using the\nMcIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities\nto create a simple HTML diff output format and a standard diff-like tool.\n\nThis is release 1.6.1, providing a simple extension that allows for\nDiff::LCS::Change objects to be treated implicitly as arrays and fixes a number\nof formatting issues.\n\nRuby versions below 2.5 are soft-deprecated, which means that older versions are\nno longer part of the CI test suite. If any changes have been introduced that\nbreak those versions, bug reports and patches will be accepted, but it will be\nup to the reporter to verify any fixes prior to release. The next major release\nwill completely break compatibility.".freeze + s.email = ["halostatue@gmail.com".freeze] + s.executables = ["htmldiff".freeze, "ldiff".freeze] + s.extra_rdoc_files = ["CHANGELOG.md".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "CONTRIBUTORS.md".freeze, "LICENCE.md".freeze, "Manifest.txt".freeze, "README.md".freeze, "SECURITY.md".freeze, "docs/COPYING.txt".freeze, "docs/artistic.txt".freeze] + s.files = ["CHANGELOG.md".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "CONTRIBUTORS.md".freeze, "LICENCE.md".freeze, "Manifest.txt".freeze, "README.md".freeze, "SECURITY.md".freeze, "bin/htmldiff".freeze, "bin/ldiff".freeze, "docs/COPYING.txt".freeze, "docs/artistic.txt".freeze] + s.homepage = "https://github.com/halostatue/diff-lcs".freeze + s.licenses = ["MIT".freeze, "Artistic-1.0-Perl".freeze, "GPL-2.0-or-later".freeze] + s.rdoc_options = ["--main".freeze, "README.md".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 1.8".freeze) + s.rubygems_version = "3.4.20".freeze + s.summary = "Diff::LCS computes the difference between two Enumerable sequences using the McIlroy-Hunt longest common subsequence (LCS) algorithm".freeze + + s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version + + s.specification_version = 4 + + s.add_development_dependency(%q.freeze, ["~> 4.0"]) + s.add_development_dependency(%q.freeze, ["~> 2.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.0"]) + s.add_development_dependency(%q.freeze, [">= 2.0", "< 4"]) + s.add_development_dependency(%q.freeze, [">= 10.0", "< 14"]) + s.add_development_dependency(%q.freeze, [">= 6.3.1", "< 7"]) +end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec new file mode 100644 index 0000000..2c8c519 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec @@ -0,0 +1,26 @@ +# -*- encoding: utf-8 -*- +# stub: rake 13.3.1 ruby lib + +Gem::Specification.new do |s| + s.name = "rake".freeze + s.version = "13.3.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/ruby/rake/issues", "changelog_uri" => "https://github.com/ruby/rake/releases", "documentation_uri" => "https://ruby.github.io/rake", "source_code_uri" => "https://github.com/ruby/rake" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Hiroshi SHIBATA".freeze, "Eric Hodel".freeze, "Jim Weirich".freeze] + s.bindir = "exe".freeze + s.date = "1980-01-02" + s.description = "Rake is a Make-like program implemented in Ruby. Tasks and dependencies are\nspecified in standard Ruby syntax.\nRake has the following features:\n * Rakefiles (rake's version of Makefiles) are completely defined in standard Ruby syntax.\n No XML files to edit. No quirky Makefile syntax to worry about (is that a tab or a space?)\n * Users can specify tasks with prerequisites.\n * Rake supports rule patterns to synthesize implicit tasks.\n * Flexible FileLists that act like arrays but know about manipulating file names and paths.\n * Supports parallel execution of tasks.\n".freeze + s.email = ["hsbt@ruby-lang.org".freeze, "drbrain@segment7.net".freeze, "".freeze] + s.executables = ["rake".freeze] + s.files = ["exe/rake".freeze] + s.homepage = "https://github.com/ruby/rake".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--main".freeze, "README.rdoc".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 2.3".freeze) + s.rubygems_version = "3.4.20".freeze + s.summary = "Rake is a Make-like program implemented in Ruby".freeze + + s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version +end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec new file mode 100644 index 0000000..0c94086 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec @@ -0,0 +1,31 @@ +# -*- encoding: utf-8 -*- +# stub: rspec 3.13.2 ruby lib + +Gem::Specification.new do |s| + s.name = "rspec".freeze + s.version = "3.13.2" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/tree/rspec-v3.13.2/rspec" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Myron Marston".freeze] + s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] + s.date = "1980-01-02" + s.description = "BDD for Ruby".freeze + s.email = "rspec@googlegroups.com".freeze + s.extra_rdoc_files = ["README.md".freeze] + s.files = ["README.md".freeze] + s.homepage = "https://rspec.info".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--charset=UTF-8".freeze] + s.rubygems_version = "3.4.20".freeze + s.summary = "rspec-3.13.2".freeze + + s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version + + s.specification_version = 4 + + s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) + s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) + s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) +end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec new file mode 100644 index 0000000..8bd860e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec @@ -0,0 +1,31 @@ +# -*- encoding: utf-8 -*- +# stub: rspec-core 3.13.6 ruby lib + +Gem::Specification.new do |s| + s.name = "rspec-core".freeze + s.version = "3.13.6" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-core-v3.13.6/rspec-core/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-core-v3.13.6/rspec-core" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Chad Humphries".freeze, "Myron Marston".freeze] + s.bindir = "exe".freeze + s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] + s.date = "1980-01-02" + s.description = "BDD for Ruby. RSpec runner and example groups.".freeze + s.email = "rspec@googlegroups.com".freeze + s.executables = ["rspec".freeze] + s.files = ["exe/rspec".freeze] + s.homepage = "https://rspec.info".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--charset=UTF-8".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) + s.rubygems_version = "3.4.20".freeze + s.summary = "rspec-core-3.13.6".freeze + + s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version + + s.specification_version = 4 + + s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) +end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec new file mode 100644 index 0000000..780aba2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +# stub: rspec-expectations 3.13.5 ruby lib + +Gem::Specification.new do |s| + s.name = "rspec-expectations".freeze + s.version = "3.13.5" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-expectations-v3.13.5/rspec-expectations/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-expectations-v3.13.5/rspec-expectations" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Myron Marston".freeze] + s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] + s.date = "1980-01-02" + s.description = "rspec-expectations provides a simple, readable API to express expected outcomes of a code example.".freeze + s.email = "rspec@googlegroups.com".freeze + s.homepage = "https://rspec.info".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--charset=UTF-8".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) + s.rubygems_version = "3.4.20".freeze + s.summary = "rspec-expectations-3.13.5".freeze + + s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version + + s.specification_version = 4 + + s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) + s.add_runtime_dependency(%q.freeze, [">= 1.2.0", "< 2.0"]) +end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec new file mode 100644 index 0000000..cc6a2a8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +# stub: rspec-mocks 3.13.7 ruby lib + +Gem::Specification.new do |s| + s.name = "rspec-mocks".freeze + s.version = "3.13.7" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-mocks-v3.13.7/rspec-mocks/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-mocks-v3.13.7/rspec-mocks" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Myron Marston".freeze] + s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] + s.date = "1980-01-02" + s.description = "RSpec's 'test double' framework, with support for stubbing and mocking".freeze + s.email = "rspec@googlegroups.com".freeze + s.homepage = "https://rspec.info".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--charset=UTF-8".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) + s.rubygems_version = "3.4.20".freeze + s.summary = "rspec-mocks-3.13.7".freeze + + s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version + + s.specification_version = 4 + + s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) + s.add_runtime_dependency(%q.freeze, [">= 1.2.0", "< 2.0"]) +end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec new file mode 100644 index 0000000..a7a859f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +# stub: rspec-support 3.13.6 ruby lib + +Gem::Specification.new do |s| + s.name = "rspec-support".freeze + s.version = "3.13.6" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-support-v3.13.6/rspec-support/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-support-v3.13.6/rspec-support" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["David Chelimsky".freeze, "Myron Marson".freeze, "Jon Rowe".freeze, "Sam Phippen".freeze, "Xaviery Shay".freeze, "Bradley Schaefer".freeze] + s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] + s.date = "1980-01-02" + s.description = "Support utilities for RSpec gems".freeze + s.email = "rspec-users@rubyforge.org".freeze + s.homepage = "https://rspec.info".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--charset=UTF-8".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) + s.rubygems_version = "3.4.20".freeze + s.summary = "rspec-support-3.13.6".freeze + + s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version + + s.specification_version = 4 + + s.add_development_dependency(%q.freeze, ["> 10.0.0"]) + s.add_development_dependency(%q.freeze, ["~> 1.1.0"]) +end From d54ebe367603ae49e7508582d3b79ece543a4112 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 31 Dec 2025 15:09:11 +0000 Subject: [PATCH 3/4] Update git_store for Ruby 3.2 compatibility and add CI workflow Co-authored-by: georgi <19498+georgi@users.noreply.github.com> --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++++++++++++ .gitignore | 3 +++ Gemfile.lock | 38 -------------------------------------- git_store.gemspec | 4 +++- lib/git_store.rb | 10 +++++----- lib/git_store/commit.rb | 4 +++- lib/git_store/handlers.rb | 16 ++-------------- lib/git_store/pack.rb | 2 +- lib/git_store/user.rb | 4 ++-- test/bare_store_spec.rb | 3 +++ test/commit_spec.rb | 7 +++++-- test/git_store_spec.rb | 1 + test/spec_helper.rb | 5 +++++ test/tree_spec.rb | 1 + test/user_spec.rb | 1 + 15 files changed, 67 insertions(+), 64 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 Gemfile.lock create mode 100644 test/spec_helper.rb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..84e28cd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: CI + +on: + push: + branches: [ master, main ] + pull_request: + branches: [ master, main ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + ruby-version: ['3.0', '3.1', '3.2', '3.3'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Ruby ${{ matrix.ruby-version }} + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + + - name: Configure git + run: | + git config --global user.name "Test User" + git config --global user.email "test@example.com" + git config --global init.defaultBranch master + + - name: Run tests + run: bundle exec rake spec diff --git a/.gitignore b/.gitignore index 3d120c8..f659bb0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ doc/* pkg/* test/repo html/* +vendor/ +.bundle/ +Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 8d18c4a..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,38 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - diff-lcs (1.6.2) - rake (13.3.1) - rspec (3.13.2) - rspec-core (~> 3.13.0) - rspec-expectations (~> 3.13.0) - rspec-mocks (~> 3.13.0) - rspec-core (3.13.6) - rspec-support (~> 3.13.0) - rspec-expectations (3.13.5) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.13.0) - rspec-mocks (3.13.7) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.13.0) - rspec-support (3.13.6) - -PLATFORMS - ruby - x86_64-linux-gnu - -DEPENDENCIES - rake - rspec - -CHECKSUMS - diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 - rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c - rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587 - rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d - rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 - rspec-mocks (3.13.7) sha256=0979034e64b1d7a838aaaddf12bf065ea4dc40ef3d4c39f01f93ae2c66c62b1c - rspec-support (3.13.6) sha256=2e8de3702427eab064c9352fe74488cc12a1bfae887ad8b91cba480ec9f8afb2 - -BUNDLED WITH - 4.0.3 diff --git a/git_store.gemspec b/git_store.gemspec index 2c10386..921df6d 100644 --- a/git_store.gemspec +++ b/git_store.gemspec @@ -13,7 +13,6 @@ repository. GitStore checks out the repository into a in-memory representation, which can be modified and finally committed. END s.require_path = 'lib' - s.has_rdoc = true s.extra_rdoc_files = ['README.md'] s.files = %w{ .gitignore @@ -34,7 +33,10 @@ test/bare_store_spec.rb test/benchmark.rb test/commit_spec.rb test/git_store_spec.rb +test/helper.rb +test/spec_helper.rb test/tree_spec.rb +test/user_spec.rb } end diff --git a/lib/git_store.rb b/lib/git_store.rb index d5d91eb..671becc 100644 --- a/lib/git_store.rb +++ b/lib/git_store.rb @@ -59,8 +59,8 @@ class GitStore # Initialize a store. def initialize(path, branch = 'master', bare = false) - if bare && !File.exists?("#{path}") or - !bare && !File.exists?("#{path}/.git") + if bare && !File.exist?("#{path}") or + !bare && !File.exist?("#{path}/.git") raise ArgumentError, "first argument must be a valid Git repository: `#{path}'" end @@ -105,7 +105,7 @@ def git_path # # Returns the object id of the last commit. def read_head_id - File.read(head_path).strip if File.exists?(head_path) + File.read(head_path).strip if File.exist?(head_path) end # Return a handler for a given path. @@ -321,7 +321,7 @@ def id_for(type, content) def get_object(id) path = object_path(id) - if File.exists?(path) + if File.exist?(path) buf = open(path, "rb") { |f| f.read } raise "not a loose object: #{id}" if not legacy_loose_object?(buf) @@ -345,7 +345,7 @@ def put_object(type, content) id = sha(data) path = object_path(id) - unless File.exists?(path) + unless File.exist?(path) FileUtils.mkpath(File.dirname(path)) open(path, 'wb') do |f| f.write Zlib::Deflate.deflate(data) diff --git a/lib/git_store/commit.rb b/lib/git_store/commit.rb index 01ebbad..dee367d 100644 --- a/lib/git_store/commit.rb +++ b/lib/git_store/commit.rb @@ -40,7 +40,9 @@ def parse(data) def diff(commit, path = nil) commit = commit.id if Commit === commit - Diff.exec(store, "git diff --full-index #{commit} #{id} -- '#{path}'") + cmd = "git diff --full-index #{commit} #{id}" + cmd += " -- '#{path}'" if path + Diff.exec(store, cmd) end def diffs(path = nil) diff --git a/lib/git_store/handlers.rb b/lib/git_store/handlers.rb index e3167c4..ef7acda 100644 --- a/lib/git_store/handlers.rb +++ b/lib/git_store/handlers.rb @@ -1,16 +1,4 @@ - -# This fix ensures sorted yaml maps. -class Hash - def to_yaml( opts = {} ) - YAML::quick_emit( object_id, opts ) do |out| - out.map( taguri, to_yaml_style ) do |map| - sort_by { |k, v| k.to_s }.each do |k, v| - map.add( k, v ) - end - end - end - end -end +require 'date' class GitStore @@ -26,7 +14,7 @@ def write(data) class YAMLHandler def read(data) - YAML.load(data) + YAML.safe_load(data, permitted_classes: [Symbol, Date, Time]) end def write(data) diff --git a/lib/git_store/pack.rb b/lib/git_store/pack.rb index fb5c43d..451c547 100644 --- a/lib/git_store/pack.rb +++ b/lib/git_store/pack.rb @@ -44,7 +44,7 @@ def [](*idx) when Range offset = idx.first len = idx.last - idx.first + idx.exclude_end? ? 0 : 1 - when Fixnum + when Integer offset = idx len = nil when Array diff --git a/lib/git_store/user.rb b/lib/git_store/user.rb index a17fc67..37b6dbc 100644 --- a/lib/git_store/user.rb +++ b/lib/git_store/user.rb @@ -19,9 +19,9 @@ def self.config_get(key) if $?.exitstatus == 0 return value unless value.empty? - raise RuntimError, "#{key} is empty" + raise RuntimeError, "#{key} is empty" else - raise RuntimError, "No #{key} found in git config" + raise RuntimeError, "No #{key} found in git config" end end diff --git a/test/bare_store_spec.rb b/test/bare_store_spec.rb index c33360e..2be2af3 100644 --- a/test/bare_store_spec.rb +++ b/test/bare_store_spec.rb @@ -1,4 +1,5 @@ require "#{File.dirname(__FILE__)}/../lib/git_store" +require "#{File.dirname(__FILE__)}/spec_helper" require "#{File.dirname(__FILE__)}/helper" require 'pp' @@ -14,6 +15,8 @@ Dir.chdir REPO `git init --bare` + `git config user.name 'User Name'` + `git config user.email 'user.name@email.com'` @store = GitStore.new(REPO, 'master', true) end diff --git a/test/commit_spec.rb b/test/commit_spec.rb index c3a2211..231a2db 100644 --- a/test/commit_spec.rb +++ b/test/commit_spec.rb @@ -1,4 +1,5 @@ require "#{File.dirname(__FILE__)}/../lib/git_store" +require "#{File.dirname(__FILE__)}/spec_helper" require 'pp' describe GitStore::Commit do @@ -12,6 +13,8 @@ Dir.mkdir REPO Dir.chdir REPO `git init` + `git config user.name 'User Name'` + `git config user.email 'user.name@email.com'` @store = GitStore.new(REPO) end @@ -69,13 +72,13 @@ diff = b.diff(a) diff[0].a_path.should == 'x' - diff[0].deleted_file.should be_true + diff[0].deleted_file.should be true diff[1].a_path.should == 'y' diff[1].diff.should == "--- a/y\n+++ b/y\n@@ -1,4 +1,4 @@\n \n First Line.\n-Second Line.\n Last Line.\n+Another Line." diff[2].a_path.should == 'z' - diff[2].new_file.should be_true + diff[2].new_file.should be true end end diff --git a/test/git_store_spec.rb b/test/git_store_spec.rb index 3d09940..5ba2563 100644 --- a/test/git_store_spec.rb +++ b/test/git_store_spec.rb @@ -1,4 +1,5 @@ require "#{File.dirname(__FILE__)}/../lib/git_store" +require "#{File.dirname(__FILE__)}/spec_helper" require "#{File.dirname(__FILE__)}/helper" require 'pp' diff --git a/test/spec_helper.rb b/test/spec_helper.rb new file mode 100644 index 0000000..e057e98 --- /dev/null +++ b/test/spec_helper.rb @@ -0,0 +1,5 @@ +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.syntax = [:should, :expect] + end +end diff --git a/test/tree_spec.rb b/test/tree_spec.rb index 9e8c93d..2732d8d 100644 --- a/test/tree_spec.rb +++ b/test/tree_spec.rb @@ -1,4 +1,5 @@ require "#{File.dirname(__FILE__)}/../lib/git_store" +require "#{File.dirname(__FILE__)}/spec_helper" require "#{File.dirname(__FILE__)}/helper" require 'pp' diff --git a/test/user_spec.rb b/test/user_spec.rb index 6c9a43a..2f04042 100644 --- a/test/user_spec.rb +++ b/test/user_spec.rb @@ -1,4 +1,5 @@ require "#{File.dirname(__FILE__)}/../lib/git_store" +require "#{File.dirname(__FILE__)}/spec_helper" require 'pp' describe GitStore::User do From 629e8f902fca8a69cfdbb75c4271b8a6b5995122 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 31 Dec 2025 17:06:58 +0000 Subject: [PATCH 4/4] Remove vendor and .bundle folders from git tracking Co-authored-by: georgi <19498+georgi@users.noreply.github.com> --- .bundle/config | 2 - vendor/bundle/ruby/3.2.0/bin/htmldiff | 29 - vendor/bundle/ruby/3.2.0/bin/ldiff | 29 - vendor/bundle/ruby/3.2.0/bin/rake | 29 - vendor/bundle/ruby/3.2.0/bin/rspec | 29 - .../ruby/3.2.0/cache/diff-lcs-1.6.2.gem | Bin 59392 -> 0 bytes .../bundle/ruby/3.2.0/cache/rake-13.3.1.gem | Bin 86528 -> 0 bytes .../bundle/ruby/3.2.0/cache/rspec-3.13.2.gem | Bin 10752 -> 0 bytes .../ruby/3.2.0/cache/rspec-core-3.13.6.gem | Bin 167936 -> 0 bytes .../3.2.0/cache/rspec-expectations-3.13.5.gem | Bin 89600 -> 0 bytes .../ruby/3.2.0/cache/rspec-mocks-3.13.7.gem | Bin 82944 -> 0 bytes .../ruby/3.2.0/cache/rspec-support-3.13.6.gem | Bin 40960 -> 0 bytes .../ruby/3.2.0/gems/diff-lcs-1.6.2/.rspec | 1 - .../3.2.0/gems/diff-lcs-1.6.2/CHANGELOG.md | 518 ---- .../gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md | 128 - .../3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md | 71 - .../3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md | 49 - .../ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md | 40 - .../3.2.0/gems/diff-lcs-1.6.2/Manifest.txt | 115 - .../ruby/3.2.0/gems/diff-lcs-1.6.2/README.md | 92 - .../ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile | 115 - .../3.2.0/gems/diff-lcs-1.6.2/SECURITY.md | 41 - .../3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff | 35 - .../ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff | 9 - .../gems/diff-lcs-1.6.2/docs/COPYING.txt | 339 --- .../gems/diff-lcs-1.6.2/docs/artistic.txt | 127 - .../3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb | 3 - .../3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb | 742 ----- .../gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb | 7 - .../diff-lcs-1.6.2/lib/diff/lcs/backports.rb | 13 - .../gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb | 37 - .../diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb | 327 --- .../diff-lcs-1.6.2/lib/diff/lcs/change.rb | 174 -- .../diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb | 160 -- .../gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb | 379 --- .../diff-lcs-1.6.2/lib/diff/lcs/internals.rb | 308 --- .../gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb | 189 -- .../diff-lcs-1.6.2/lib/diff/lcs/string.rb | 5 - .../diff-lcs-1.6.2/lib/diff/lcs/version.rb | 7 - .../ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml | 5 - .../gems/diff-lcs-1.6.2/spec/change_spec.rb | 89 - .../gems/diff-lcs-1.6.2/spec/diff_spec.rb | 51 - .../gems/diff-lcs-1.6.2/spec/fixtures/123_x | 2 - .../gems/diff-lcs-1.6.2/spec/fixtures/456_x | 2 - .../gems/diff-lcs-1.6.2/spec/fixtures/aX | 1 - .../gems/diff-lcs-1.6.2/spec/fixtures/bXaX | 1 - .../gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv | 50 - .../gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv | 51 - .../gems/diff-lcs-1.6.2/spec/fixtures/empty | 0 .../diff-lcs-1.6.2/spec/fixtures/file1.bin | Bin 1 -> 0 bytes .../diff-lcs-1.6.2/spec/fixtures/file2.bin | Bin 6 -> 0 bytes .../diff-lcs-1.6.2/spec/fixtures/four_lines | 4 - .../fixtures/four_lines_with_missing_new_line | 4 - .../fixtures/ldiff/diff.missing_new_line1-e | 1 - .../fixtures/ldiff/diff.missing_new_line1-f | 1 - .../fixtures/ldiff/diff.missing_new_line2-e | 1 - .../fixtures/ldiff/diff.missing_new_line2-f | 1 - .../spec/fixtures/ldiff/error.diff.chef-e | 2 - .../spec/fixtures/ldiff/error.diff.chef-f | 2 - .../ldiff/error.diff.missing_new_line1-e | 1 - .../ldiff/error.diff.missing_new_line1-f | 1 - .../ldiff/error.diff.missing_new_line2-e | 1 - .../ldiff/error.diff.missing_new_line2-f | 1 - .../spec/fixtures/ldiff/output.diff | 4 - .../spec/fixtures/ldiff/output.diff-c | 7 - .../spec/fixtures/ldiff/output.diff-e | 3 - .../spec/fixtures/ldiff/output.diff-f | 3 - .../spec/fixtures/ldiff/output.diff-u | 5 - .../spec/fixtures/ldiff/output.diff.bin1 | 0 .../spec/fixtures/ldiff/output.diff.bin1-c | 0 .../spec/fixtures/ldiff/output.diff.bin1-e | 0 .../spec/fixtures/ldiff/output.diff.bin1-f | 0 .../spec/fixtures/ldiff/output.diff.bin1-u | 0 .../spec/fixtures/ldiff/output.diff.bin2 | 1 - .../spec/fixtures/ldiff/output.diff.bin2-c | 1 - .../spec/fixtures/ldiff/output.diff.bin2-e | 1 - .../spec/fixtures/ldiff/output.diff.bin2-f | 1 - .../spec/fixtures/ldiff/output.diff.bin2-u | 1 - .../spec/fixtures/ldiff/output.diff.chef | 4 - .../spec/fixtures/ldiff/output.diff.chef-c | 15 - .../spec/fixtures/ldiff/output.diff.chef-e | 3 - .../spec/fixtures/ldiff/output.diff.chef-f | 3 - .../spec/fixtures/ldiff/output.diff.chef-u | 9 - .../spec/fixtures/ldiff/output.diff.chef2 | 7 - .../spec/fixtures/ldiff/output.diff.chef2-c | 20 - .../spec/fixtures/ldiff/output.diff.chef2-d | 7 - .../spec/fixtures/ldiff/output.diff.chef2-e | 7 - .../spec/fixtures/ldiff/output.diff.chef2-f | 7 - .../spec/fixtures/ldiff/output.diff.chef2-u | 16 - .../ldiff/output.diff.empty.vs.four_lines | 5 - .../ldiff/output.diff.empty.vs.four_lines-c | 9 - .../ldiff/output.diff.empty.vs.four_lines-e | 6 - .../ldiff/output.diff.empty.vs.four_lines-f | 6 - .../ldiff/output.diff.empty.vs.four_lines-u | 7 - .../ldiff/output.diff.four_lines.vs.empty | 5 - .../ldiff/output.diff.four_lines.vs.empty-c | 9 - .../ldiff/output.diff.four_lines.vs.empty-e | 1 - .../ldiff/output.diff.four_lines.vs.empty-f | 1 - .../ldiff/output.diff.four_lines.vs.empty-u | 7 - .../output.diff.issue95_trailing_context | 4 - .../output.diff.issue95_trailing_context-c | 9 - .../output.diff.issue95_trailing_context-e | 3 - .../output.diff.issue95_trailing_context-f | 3 - .../output.diff.issue95_trailing_context-u | 6 - .../ldiff/output.diff.missing_new_line1 | 5 - .../ldiff/output.diff.missing_new_line1-c | 14 - .../ldiff/output.diff.missing_new_line1-e | 0 .../ldiff/output.diff.missing_new_line1-f | 0 .../ldiff/output.diff.missing_new_line1-u | 9 - .../ldiff/output.diff.missing_new_line2 | 5 - .../ldiff/output.diff.missing_new_line2-c | 14 - .../ldiff/output.diff.missing_new_line2-e | 0 .../ldiff/output.diff.missing_new_line2-f | 0 .../ldiff/output.diff.missing_new_line2-u | 9 - .../diff-lcs-1.6.2/spec/fixtures/new-chef | 4 - .../diff-lcs-1.6.2/spec/fixtures/new-chef2 | 17 - .../diff-lcs-1.6.2/spec/fixtures/old-chef | 4 - .../diff-lcs-1.6.2/spec/fixtures/old-chef2 | 14 - .../gems/diff-lcs-1.6.2/spec/hunk_spec.rb | 83 - .../gems/diff-lcs-1.6.2/spec/issues_spec.rb | 160 -- .../gems/diff-lcs-1.6.2/spec/lcs_spec.rb | 56 - .../gems/diff-lcs-1.6.2/spec/ldiff_spec.rb | 100 - .../gems/diff-lcs-1.6.2/spec/patch_spec.rb | 416 --- .../gems/diff-lcs-1.6.2/spec/sdiff_spec.rb | 216 -- .../gems/diff-lcs-1.6.2/spec/spec_helper.rb | 376 --- .../spec/traverse_balanced_spec.rb | 312 --- .../spec/traverse_sequences_spec.rb | 137 - .../ruby/3.2.0/gems/rake-13.3.1/History.rdoc | 2454 ----------------- .../ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE | 21 - .../ruby/3.2.0/gems/rake-13.3.1/README.rdoc | 155 -- .../rake-13.3.1/doc/command_line_usage.rdoc | 171 -- .../gems/rake-13.3.1/doc/example/Rakefile1 | 38 - .../gems/rake-13.3.1/doc/example/Rakefile2 | 35 - .../3.2.0/gems/rake-13.3.1/doc/example/a.c | 6 - .../3.2.0/gems/rake-13.3.1/doc/example/b.c | 6 - .../3.2.0/gems/rake-13.3.1/doc/example/main.c | 11 - .../3.2.0/gems/rake-13.3.1/doc/glossary.rdoc | 42 - .../ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb | 592 ---- .../gems/rake-13.3.1/doc/proto_rake.rdoc | 127 - .../ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 | 156 -- .../3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc | 622 ----- .../3.2.0/gems/rake-13.3.1/doc/rational.rdoc | 151 - .../ruby/3.2.0/gems/rake-13.3.1/exe/rake | 27 - .../ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb | 68 - .../gems/rake-13.3.1/lib/rake/application.rb | 854 ------ .../gems/rake-13.3.1/lib/rake/backtrace.rb | 25 - .../3.2.0/gems/rake-13.3.1/lib/rake/clean.rb | 78 - .../gems/rake-13.3.1/lib/rake/cloneable.rb | 17 - .../gems/rake-13.3.1/lib/rake/cpu_counter.rb | 122 - .../rake-13.3.1/lib/rake/default_loader.rb | 15 - .../rake-13.3.1/lib/rake/dsl_definition.rb | 196 -- .../gems/rake-13.3.1/lib/rake/early_time.rb | 22 - .../gems/rake-13.3.1/lib/rake/ext/core.rb | 26 - .../gems/rake-13.3.1/lib/rake/ext/string.rb | 176 -- .../lib/rake/file_creation_task.rb | 25 - .../gems/rake-13.3.1/lib/rake/file_list.rb | 435 --- .../gems/rake-13.3.1/lib/rake/file_task.rb | 58 - .../gems/rake-13.3.1/lib/rake/file_utils.rb | 132 - .../rake-13.3.1/lib/rake/file_utils_ext.rb | 134 - .../rake-13.3.1/lib/rake/invocation_chain.rb | 57 - .../lib/rake/invocation_exception_mixin.rb | 17 - .../gems/rake-13.3.1/lib/rake/late_time.rb | 18 - .../gems/rake-13.3.1/lib/rake/linked_list.rb | 112 - .../rake-13.3.1/lib/rake/loaders/makefile.rb | 54 - .../gems/rake-13.3.1/lib/rake/multi_task.rb | 14 - .../gems/rake-13.3.1/lib/rake/name_space.rb | 38 - .../gems/rake-13.3.1/lib/rake/packagetask.rb | 222 -- .../3.2.0/gems/rake-13.3.1/lib/rake/phony.rb | 16 - .../rake-13.3.1/lib/rake/private_reader.rb | 21 - .../gems/rake-13.3.1/lib/rake/promise.rb | 100 - .../rake-13.3.1/lib/rake/pseudo_status.rb | 30 - .../gems/rake-13.3.1/lib/rake/rake_module.rb | 67 - .../rake-13.3.1/lib/rake/rake_test_loader.rb | 27 - .../lib/rake/rule_recursion_overflow_error.rb | 20 - .../3.2.0/gems/rake-13.3.1/lib/rake/scope.rb | 43 - .../3.2.0/gems/rake-13.3.1/lib/rake/task.rb | 434 --- .../lib/rake/task_argument_error.rb | 8 - .../rake-13.3.1/lib/rake/task_arguments.rb | 113 - .../gems/rake-13.3.1/lib/rake/task_manager.rb | 331 --- .../gems/rake-13.3.1/lib/rake/tasklib.rb | 12 - .../gems/rake-13.3.1/lib/rake/testtask.rb | 189 -- .../lib/rake/thread_history_display.rb | 49 - .../gems/rake-13.3.1/lib/rake/thread_pool.rb | 157 -- .../gems/rake-13.3.1/lib/rake/trace_output.rb | 23 - .../gems/rake-13.3.1/lib/rake/version.rb | 10 - .../3.2.0/gems/rake-13.3.1/lib/rake/win32.rb | 51 - .../ruby/3.2.0/gems/rake-13.3.1/rake.gemspec | 101 - .../ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md | 27 - .../ruby/3.2.0/gems/rspec-3.13.2/README.md | 47 - .../ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb | 3 - .../gems/rspec-3.13.2/lib/rspec/version.rb | 5 - .../3.2.0/gems/rspec-core-3.13.6/.document | 5 - .../3.2.0/gems/rspec-core-3.13.6/.yardopts | 8 - .../3.2.0/gems/rspec-core-3.13.6/Changelog.md | 2447 ---------------- .../3.2.0/gems/rspec-core-3.13.6/LICENSE.md | 26 - .../3.2.0/gems/rspec-core-3.13.6/README.md | 389 --- .../3.2.0/gems/rspec-core-3.13.6/exe/rspec | 4 - .../rspec-core-3.13.6/lib/rspec/autorun.rb | 3 - .../gems/rspec-core-3.13.6/lib/rspec/core.rb | 212 -- .../lib/rspec/core/backtrace_formatter.rb | 65 - .../lib/rspec/core/bisect/coordinator.rb | 62 - .../rspec/core/bisect/example_minimizer.rb | 173 -- .../lib/rspec/core/bisect/fork_runner.rb | 140 - .../lib/rspec/core/bisect/server.rb | 61 - .../lib/rspec/core/bisect/shell_command.rb | 126 - .../lib/rspec/core/bisect/shell_runner.rb | 73 - .../lib/rspec/core/bisect/utilities.rb | 69 - .../lib/rspec/core/configuration.rb | 2419 ---------------- .../lib/rspec/core/configuration_options.rb | 240 -- .../lib/rspec/core/did_you_mean.rb | 52 - .../rspec-core-3.13.6/lib/rspec/core/drb.rb | 120 - .../rspec-core-3.13.6/lib/rspec/core/dsl.rb | 98 - .../lib/rspec/core/example.rb | 666 ----- .../lib/rspec/core/example_group.rb | 912 ------ .../rspec/core/example_status_persister.rb | 235 -- .../lib/rspec/core/filter_manager.rb | 231 -- .../lib/rspec/core/flat_map.rb | 20 - .../lib/rspec/core/formatters.rb | 279 -- .../core/formatters/base_bisect_formatter.rb | 45 - .../rspec/core/formatters/base_formatter.rb | 70 - .../core/formatters/base_text_formatter.rb | 75 - .../core/formatters/bisect_drb_formatter.rb | 29 - .../formatters/bisect_progress_formatter.rb | 157 -- .../rspec/core/formatters/console_codes.rb | 76 - .../core/formatters/deprecation_formatter.rb | 223 -- .../formatters/documentation_formatter.rb | 102 - .../core/formatters/exception_presenter.rb | 553 ---- .../core/formatters/failure_list_formatter.rb | 23 - .../formatters/fallback_message_formatter.rb | 28 - .../lib/rspec/core/formatters/helpers.rb | 118 - .../rspec/core/formatters/html_formatter.rb | 153 - .../lib/rspec/core/formatters/html_printer.rb | 412 --- .../core/formatters/html_snippet_extractor.rb | 122 - .../rspec/core/formatters/json_formatter.rb | 103 - .../core/formatters/profile_formatter.rb | 68 - .../core/formatters/progress_formatter.rb | 29 - .../lib/rspec/core/formatters/protocol.rb | 182 -- .../core/formatters/snippet_extractor.rb | 134 - .../core/formatters/syntax_highlighter.rb | 91 - .../rspec-core-3.13.6/lib/rspec/core/hooks.rb | 646 ----- .../lib/rspec/core/invocations.rb | 87 - .../lib/rspec/core/memoized_helpers.rb | 580 ---- .../lib/rspec/core/metadata.rb | 498 ---- .../lib/rspec/core/metadata_filter.rb | 255 -- .../rspec/core/minitest_assertions_adapter.rb | 31 - .../rspec/core/mocking_adapters/flexmock.rb | 31 - .../lib/rspec/core/mocking_adapters/mocha.rb | 57 - .../lib/rspec/core/mocking_adapters/null.rb | 14 - .../lib/rspec/core/mocking_adapters/rr.rb | 31 - .../lib/rspec/core/mocking_adapters/rspec.rb | 32 - .../lib/rspec/core/notifications.rb | 523 ---- .../lib/rspec/core/option_parser.rb | 325 --- .../lib/rspec/core/ordering.rb | 208 -- .../lib/rspec/core/output_wrapper.rb | 29 - .../lib/rspec/core/pending.rb | 157 -- .../lib/rspec/core/profiler.rb | 34 - .../lib/rspec/core/project_initializer.rb | 48 - .../lib/rspec/core/project_initializer/.rspec | 1 - .../project_initializer/spec/spec_helper.rb | 98 - .../lib/rspec/core/rake_task.rb | 190 -- .../lib/rspec/core/reporter.rb | 266 -- .../lib/rspec/core/ruby_project.rb | 53 - .../lib/rspec/core/runner.rb | 216 -- .../lib/rspec/core/sandbox.rb | 37 - .../rspec-core-3.13.6/lib/rspec/core/set.rb | 54 - .../lib/rspec/core/shared_context.rb | 55 - .../lib/rspec/core/shared_example_group.rb | 271 -- .../lib/rspec/core/shell_escape.rb | 49 - .../core/test_unit_assertions_adapter.rb | 30 - .../lib/rspec/core/version.rb | 9 - .../lib/rspec/core/warnings.rb | 40 - .../rspec-core-3.13.6/lib/rspec/core/world.rb | 287 -- .../gems/rspec-expectations-3.13.5/.document | 5 - .../gems/rspec-expectations-3.13.5/.yardopts | 6 - .../rspec-expectations-3.13.5/Changelog.md | 1366 --------- .../gems/rspec-expectations-3.13.5/LICENSE.md | 25 - .../gems/rspec-expectations-3.13.5/README.md | 326 --- .../lib/rspec/expectations.rb | 82 - .../expectations/block_snippet_extractor.rb | 255 -- .../lib/rspec/expectations/configuration.rb | 244 -- .../rspec/expectations/expectation_target.rb | 163 -- .../lib/rspec/expectations/fail_with.rb | 39 - .../rspec/expectations/failure_aggregator.rb | 236 -- .../lib/rspec/expectations/handler.rb | 181 -- .../expectations/minitest_integration.rb | 58 - .../lib/rspec/expectations/syntax.rb | 132 - .../lib/rspec/expectations/version.rb | 8 - .../lib/rspec/matchers.rb | 1046 ------- .../lib/rspec/matchers/aliased_matcher.rb | 116 - .../lib/rspec/matchers/built_in.rb | 53 - .../lib/rspec/matchers/built_in/all.rb | 86 - .../rspec/matchers/built_in/base_matcher.rb | 225 -- .../lib/rspec/matchers/built_in/be.rb | 191 -- .../lib/rspec/matchers/built_in/be_between.rb | 77 - .../rspec/matchers/built_in/be_instance_of.rb | 26 - .../lib/rspec/matchers/built_in/be_kind_of.rb | 20 - .../lib/rspec/matchers/built_in/be_within.rb | 72 - .../lib/rspec/matchers/built_in/change.rb | 452 --- .../lib/rspec/matchers/built_in/compound.rb | 293 -- .../matchers/built_in/contain_exactly.rb | 312 --- .../matchers/built_in/count_expectation.rb | 171 -- .../lib/rspec/matchers/built_in/cover.rb | 24 - .../lib/rspec/matchers/built_in/eq.rb | 44 - .../lib/rspec/matchers/built_in/eql.rb | 38 - .../lib/rspec/matchers/built_in/equal.rb | 81 - .../lib/rspec/matchers/built_in/exist.rb | 90 - .../lib/rspec/matchers/built_in/has.rb | 194 -- .../matchers/built_in/have_attributes.rb | 114 - .../lib/rspec/matchers/built_in/include.rb | 218 -- .../lib/rspec/matchers/built_in/match.rb | 120 - .../lib/rspec/matchers/built_in/operators.rb | 128 - .../lib/rspec/matchers/built_in/output.rb | 207 -- .../rspec/matchers/built_in/raise_error.rb | 275 -- .../lib/rspec/matchers/built_in/respond_to.rb | 200 -- .../lib/rspec/matchers/built_in/satisfy.rb | 62 - .../matchers/built_in/start_or_end_with.rb | 94 - .../rspec/matchers/built_in/throw_symbol.rb | 138 - .../lib/rspec/matchers/built_in/yield.rb | 375 --- .../lib/rspec/matchers/composable.rb | 171 -- .../lib/rspec/matchers/dsl.rb | 546 ---- .../lib/rspec/matchers/english_phrasing.rb | 60 - .../lib/rspec/matchers/fail_matchers.rb | 42 - .../rspec/matchers/generated_descriptions.rb | 41 - .../lib/rspec/matchers/matcher_delegator.rb | 61 - .../lib/rspec/matchers/matcher_protocol.rb | 105 - .../lib/rspec/matchers/multi_matcher_diff.rb | 82 - .../3.2.0/gems/rspec-mocks-3.13.7/.document | 5 - .../3.2.0/gems/rspec-mocks-3.13.7/.yardopts | 6 - .../gems/rspec-mocks-3.13.7/Changelog.md | 1343 --------- .../3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md | 25 - .../3.2.0/gems/rspec-mocks-3.13.7/README.md | 465 ---- .../rspec-mocks-3.13.7/lib/rspec/mocks.rb | 133 - .../lib/rspec/mocks/any_instance.rb | 11 - .../lib/rspec/mocks/any_instance/chain.rb | 111 - .../mocks/any_instance/error_generator.rb | 31 - .../mocks/any_instance/expect_chain_chain.rb | 31 - .../mocks/any_instance/expectation_chain.rb | 50 - .../mocks/any_instance/message_chains.rb | 83 - .../lib/rspec/mocks/any_instance/proxy.rb | 125 - .../lib/rspec/mocks/any_instance/recorder.rb | 299 -- .../rspec/mocks/any_instance/stub_chain.rb | 51 - .../mocks/any_instance/stub_chain_chain.rb | 23 - .../lib/rspec/mocks/argument_list_matcher.rb | 117 - .../lib/rspec/mocks/argument_matchers.rb | 366 --- .../lib/rspec/mocks/configuration.rb | 212 -- .../lib/rspec/mocks/error_generator.rb | 390 --- .../lib/rspec/mocks/example_methods.rb | 434 --- .../rspec/mocks/instance_method_stasher.rb | 146 - .../lib/rspec/mocks/marshal_extension.rb | 41 - .../matchers/expectation_customization.rb | 20 - .../lib/rspec/mocks/matchers/have_received.rb | 134 - .../lib/rspec/mocks/matchers/receive.rb | 134 - .../mocks/matchers/receive_message_chain.rb | 82 - .../rspec/mocks/matchers/receive_messages.rb | 77 - .../lib/rspec/mocks/message_chain.rb | 87 - .../lib/rspec/mocks/message_expectation.rb | 856 ------ .../lib/rspec/mocks/method_double.rb | 316 --- .../lib/rspec/mocks/method_reference.rb | 214 -- .../lib/rspec/mocks/minitest_integration.rb | 68 - .../lib/rspec/mocks/mutate_const.rb | 339 --- .../lib/rspec/mocks/object_reference.rb | 149 - .../lib/rspec/mocks/order_group.rb | 81 - .../lib/rspec/mocks/proxy.rb | 517 ---- .../lib/rspec/mocks/space.rb | 238 -- .../lib/rspec/mocks/standalone.rb | 3 - .../lib/rspec/mocks/syntax.rb | 325 --- .../lib/rspec/mocks/targets.rb | 124 - .../lib/rspec/mocks/test_double.rb | 174 -- .../lib/rspec/mocks/verifying_double.rb | 125 - .../mocks/verifying_message_expectation.rb | 55 - .../lib/rspec/mocks/verifying_proxy.rb | 221 -- .../lib/rspec/mocks/version.rb | 9 - .../gems/rspec-support-3.13.6/Changelog.md | 437 --- .../gems/rspec-support-3.13.6/LICENSE.md | 23 - .../3.2.0/gems/rspec-support-3.13.6/README.md | 40 - .../rspec-support-3.13.6/lib/rspec/support.rb | 163 -- .../lib/rspec/support/caller_filter.rb | 85 - .../lib/rspec/support/comparable_version.rb | 48 - .../lib/rspec/support/differ.rb | 216 -- .../lib/rspec/support/directory_maker.rb | 65 - .../lib/rspec/support/encoded_string.rb | 163 -- .../lib/rspec/support/fuzzy_matcher.rb | 50 - .../lib/rspec/support/hunk_generator.rb | 49 - .../lib/rspec/support/matcher_definition.rb | 44 - .../support/method_signature_verifier.rb | 467 ---- .../lib/rspec/support/mutex.rb | 75 - .../lib/rspec/support/object_formatter.rb | 279 -- .../rspec/support/recursive_const_methods.rb | 78 - .../lib/rspec/support/reentrant_mutex.rb | 80 - .../lib/rspec/support/ruby_features.rb | 221 -- .../lib/rspec/support/source.rb | 87 - .../lib/rspec/support/source/location.rb | 23 - .../lib/rspec/support/source/node.rb | 112 - .../lib/rspec/support/source/token.rb | 96 - .../lib/rspec/support/spec.rb | 84 - .../rspec/support/spec/deprecation_helpers.rb | 50 - .../lib/rspec/support/spec/diff_helpers.rb | 45 - .../rspec/support/spec/formatting_support.rb | 11 - .../lib/rspec/support/spec/in_sub_process.rb | 73 - .../rspec/support/spec/library_wide_checks.rb | 152 - .../lib/rspec/support/spec/shell_out.rb | 115 - .../lib/rspec/support/spec/stderr_splitter.rb | 77 - .../lib/rspec/support/spec/string_matcher.rb | 47 - .../support/spec/with_isolated_directory.rb | 15 - .../support/spec/with_isolated_stderr.rb | 15 - .../lib/rspec/support/version.rb | 9 - .../lib/rspec/support/warnings.rb | 41 - .../support/with_keywords_when_needed.rb | 35 - .../specifications/diff-lcs-1.6.2.gemspec | 35 - .../3.2.0/specifications/rake-13.3.1.gemspec | 26 - .../3.2.0/specifications/rspec-3.13.2.gemspec | 31 - .../specifications/rspec-core-3.13.6.gemspec | 31 - .../rspec-expectations-3.13.5.gemspec | 29 - .../specifications/rspec-mocks-3.13.7.gemspec | 29 - .../rspec-support-3.13.6.gemspec | 29 - 415 files changed, 55663 deletions(-) delete mode 100644 .bundle/config delete mode 100755 vendor/bundle/ruby/3.2.0/bin/htmldiff delete mode 100755 vendor/bundle/ruby/3.2.0/bin/ldiff delete mode 100755 vendor/bundle/ruby/3.2.0/bin/rake delete mode 100755 vendor/bundle/ruby/3.2.0/bin/rspec delete mode 100644 vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem delete mode 100644 vendor/bundle/ruby/3.2.0/cache/rake-13.3.1.gem delete mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-3.13.2.gem delete mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem delete mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-expectations-3.13.5.gem delete mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.7.gem delete mode 100644 vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/.rspec delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CHANGELOG.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md delete mode 100755 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff delete mode 100755 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc delete mode 100755 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md delete mode 100755 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/comparable_version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb delete mode 100644 vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb delete mode 100644 vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec delete mode 100644 vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec delete mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec delete mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec delete mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec delete mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec delete mode 100644 vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec diff --git a/.bundle/config b/.bundle/config deleted file mode 100644 index 2369228..0000000 --- a/.bundle/config +++ /dev/null @@ -1,2 +0,0 @@ ---- -BUNDLE_PATH: "vendor/bundle" diff --git a/vendor/bundle/ruby/3.2.0/bin/htmldiff b/vendor/bundle/ruby/3.2.0/bin/htmldiff deleted file mode 100755 index 58aadf2..0000000 --- a/vendor/bundle/ruby/3.2.0/bin/htmldiff +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby3.2 -# -# This file was generated by RubyGems. -# -# The application 'diff-lcs' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'rubygems' - -Gem.use_gemdeps - -version = ">= 0.a" - -str = ARGV.first -if str - str = str.b[/\A_(.*)_\z/, 1] - if str and Gem::Version.correct?(str) - version = str - ARGV.shift - end -end - -if Gem.respond_to?(:activate_bin_path) -load Gem.activate_bin_path('diff-lcs', 'htmldiff', version) -else -gem "diff-lcs", version -load Gem.bin_path("diff-lcs", "htmldiff", version) -end diff --git a/vendor/bundle/ruby/3.2.0/bin/ldiff b/vendor/bundle/ruby/3.2.0/bin/ldiff deleted file mode 100755 index 7a54829..0000000 --- a/vendor/bundle/ruby/3.2.0/bin/ldiff +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby3.2 -# -# This file was generated by RubyGems. -# -# The application 'diff-lcs' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'rubygems' - -Gem.use_gemdeps - -version = ">= 0.a" - -str = ARGV.first -if str - str = str.b[/\A_(.*)_\z/, 1] - if str and Gem::Version.correct?(str) - version = str - ARGV.shift - end -end - -if Gem.respond_to?(:activate_bin_path) -load Gem.activate_bin_path('diff-lcs', 'ldiff', version) -else -gem "diff-lcs", version -load Gem.bin_path("diff-lcs", "ldiff", version) -end diff --git a/vendor/bundle/ruby/3.2.0/bin/rake b/vendor/bundle/ruby/3.2.0/bin/rake deleted file mode 100755 index 6b572b3..0000000 --- a/vendor/bundle/ruby/3.2.0/bin/rake +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby3.2 -# -# This file was generated by RubyGems. -# -# The application 'rake' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'rubygems' - -Gem.use_gemdeps - -version = ">= 0.a" - -str = ARGV.first -if str - str = str.b[/\A_(.*)_\z/, 1] - if str and Gem::Version.correct?(str) - version = str - ARGV.shift - end -end - -if Gem.respond_to?(:activate_bin_path) -load Gem.activate_bin_path('rake', 'rake', version) -else -gem "rake", version -load Gem.bin_path("rake", "rake", version) -end diff --git a/vendor/bundle/ruby/3.2.0/bin/rspec b/vendor/bundle/ruby/3.2.0/bin/rspec deleted file mode 100755 index b8bf169..0000000 --- a/vendor/bundle/ruby/3.2.0/bin/rspec +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby3.2 -# -# This file was generated by RubyGems. -# -# The application 'rspec-core' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'rubygems' - -Gem.use_gemdeps - -version = ">= 0.a" - -str = ARGV.first -if str - str = str.b[/\A_(.*)_\z/, 1] - if str and Gem::Version.correct?(str) - version = str - ARGV.shift - end -end - -if Gem.respond_to?(:activate_bin_path) -load Gem.activate_bin_path('rspec-core', 'rspec', version) -else -gem "rspec-core", version -load Gem.bin_path("rspec-core", "rspec", version) -end diff --git a/vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem b/vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem deleted file mode 100644 index 21c4c77c3d4368d3a91cd2442074342f08e61a73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59392 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

_+kG)0`f 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

I*-fW7U~MOFJFAV=OmQJuYG7S~r8U3WF9)Bdg< zbW34z7nRqU+fe%QsH*TaE^+tHO+em*PGxaCjECk{_)v;uBijPGl&}zm##c|;s4=D? zAYIwEk$nM9*fx_QceVXsGQ3v8~CR~Xy5pBhw2g8 zkdG`D#96zzAM-x0I1J|)>aSEC9CsC4WYJ>+ihUlEFoby(oRc!!>p5YP$^ZdLRPBU*7? zlJ%4tty=y3xYBS(Wf zCX(Y~vJcYh$wze03Kx#WQ!Vok{^j-=Vw+WORnp=1@bI==;%AD5wm@L0WgAxvp6}AP+5+}(X7OMyNSHX$dGPH{ZP z3_>)yUiyur=^fVO;V=OZ1ggF@p`Zs-J#W+BIQ&(<=w{?W6*)t;fh|LTKS{=b;B6*? zoS*T1kNQc8Rf1t-!KI(x$HO2uts0z~U;a3Xxk(R}V(U*`6ylXwsPFLdA^s3=F1 zWj9Rn$tY4-&E<%^`#Hbo`F5BVRm}pJZH^6Yp!QkCe3C&x&~|+|5m`PYzYDn zS$MEET41O~DP&;NVcWEJqx$r!=#KRXAblo=qZh%M3ro-Xq0+loE;LvU8Z#YNDEMq3 z7u(z4-uv&~_U`w4i_fp&^l~~+mlpFF($dxtU=!zXI$kLop9TKxi|GlKyYN9eorOuX zQN|Ii%N__xDZm@CXZ$?#OnFR#Ar7nPhbTWqoCDP7PG>FR4PdE1fGkB5AV-hST=V-H z=8b%ziL<3Gy0QWUT!3Hi6u&c__QLa2Yy0%FMUj%Xj6MHIF~#yA+}t7yg1?|;0X;z! z?u+<@!4?zSF?MZg(nlm`2)xHo*+c+5b^0-x7v$OG6#dR4&ymWayK!p~)h*4=s~nvo zPdLR6Puy+_;NViBYBRIBC{RS9Dv=L7!CcEc$wnC>)|eG{7SDJg*iz9*p6sE=aH$$w z>hD6JXg*!aGCZakYTbV6rAHQwz4BKf&}ZN1%8oR@G8% z`CDpBk(7&#EzQ!<`Bs2o4q)kmoY#^jkY&%yO)0a5l*3*#U`ocy6@CX1Wn)Xy=3sns2rvL3PhdIH z7Ombb?Gwly)k?Ds8taX)IK2zn6|BP@WsaJ`HHig!(u~%iq|^mFO(x;Rq;##yYmky) z%P`Y5y7#VN&5kxC7Lhf=Y<_M0b<0NG}Eg-_9OEe6tmVlv> zc{rI)(L;Y6P0u<3oARQ#=$I!h71$>L>PyDv0GpVu%>b1ht)s|K7VL_UtX}N?3Zcff zT?BY&I!3i`t+$>(+d4dNw+_SW2knF4aCUTU{{G7RxIRqR+XV%r&lY*L6kU)>>d2j` z(*y*oa80hdFgtR#n=uwkq5N{(&qn4>2FV!|$6ME){uG|Z0Vd9RmX&XLz$aQ1itN9$ zxV{{>YkZAmrulU5i`iKMuFG(z0Axa}o~szB2i#JRGr3!baesaS(HOn=khwCG6YcSB z4U`*e3;&rTii6OqQos$rc0^4pnK3iD%Q?~Z23)R`B~DdFiZ;p22;^tBq%N~C0+7}I zsBVIJ5UshlU^j4?#7b_f-YAB%gn2fdJwOJm6Z8!SrhsOjZG9W`)$f}^QD;(cT{IDg z=B=$YuO=bM-&*je>rUG>)iKHN?8?O&p!Q)3%T4Hjz0O6&AQGiD-webQf-&`KsUFwx zmVfA9=U?>IR_^@X^Q=hVOdZEFLOMmEIdE{^(*{=*KbS!6i`wG0wLhQW>ks~W3$!e2zww`(PN4gFOIF4L>*{n7J_LmoBRG{3M_9^d6904%fw3%Ult8jDj)(Aq zHDhLa3y}LP^|7>A(+bAHXakH^il)}&Bt>0O>m7{JXvDD(IldfPJHryr!?tos(Au}M zBe$oVQxa$2v`S1eX|E~b`rN1>u9H3D_5zsI#Ah?Te68$48Gg}9v@D@B^At)uhFwCl z==?GTs4&os;C&_zGtz!|0p~5-kA!{1cfoU;U zC2RAdK*e%ss?MdEzt@#Ph#Jj8qotiz?@)kBKdB1>K|V!8|oF)B+|j~osLuxECKON+e) zM5g>C=(%gVZY|@r2+Y(km1CR|GVrVn0O$@|$ABxi%Y}r>TVd z&?aU7ub#XvK8M%;-TnVJOZb0JpKRRw|NndV|EGaD5!Qe?}Buy;Vjj(>xSRH_e#oj@5427dOJ(-<`;o8Pgwb8a+i{Pqj*9P&+&X3oVcPVfy)aGDCN;fKI8=k?2 zopZ|05~K7Qr633Ckre?tp(om&dP^}_<<536TZJx&o`bd@6t1Cv$-z94Cx|axW6gsZ zzc?I7e3eqJ8rkz6>SjPogbO=6wjhh#Nb4W#?kS89FVE1X6v#>NrBTAc^@wyo18%(F zh~UGupj-`o=s+Rcl0VvoEhyhZb9$Y`E&SXrd!yjtHe*qRJ1yB?Jed}kJ6Wdq-X=gg zEG6h_U?K-IzY-b3$eed)@nyd1hr7so0GJL5QV;wsi|I@pD_dvn%FS$_}tCydlB17GuJ%q z6Ic{@p@DR+sJ*fsgD4s%gUkCH*mD?R9X3qVELVAIv2uW+l{BN(*2{vh}g4R=Q#IgKwA z@@{i`&4;?ON;NLGv|ue&>0xki)G=qVZnOWu^7((_<))t*2WBzht!F88i_S`#hT=P&XoRff49e4YbbM zBenn5)|Qm_$K%TW}!;F}TETqf^@ z_E+}%ZL70ZLG(5<4+q!i5Ue=!SvGY>UkZJ8Uz^jb=C3&P72A>(C)Z}<6hOWc<75rU zQCfGcl~#%1DrZE<+jfPfz;$m+_eaU*U(^Zb8E}G(K)e~O%o>)gQrOg7RN&6JwrJ_< z1ody_O2RNbqzy3aVl<3q(UNv?5w~(|mk;O`77ZRTIC|OW(b+X%DRKO+R(}`y6++O^ z3zB>3zG#C&1*)OYyzM0W3$_fzkN7~5uNm_+qvFiSic`c!KTjFk(u4QR)C6IyJj?RZVlP55Aj@1- znF^(LkWH13LapVt(zU7rPUYQ0&}?_?m9nDu;|VC*;9g*;*`Dcj&rBX^I*Y~2r|Uma zJ`h-2Fu!`0rOPu^+XtuS|G}Lcf@{+ZENgts<)Cp`^6_i50PaysT%u2=TjaOSy2IIN z@PC_EB}FIM8?CKjw*T916xz1xx&~p~F0;AmVq^|H3d8|QbT}xXNp+>`5>#z#G z+kKS`|C-I;8XDd1-XtE4UY^E-vv_JR8%5cSYkdLS55okXXwmet%eyGV$4O|8J3xJF z`O8*WmTJPjArYNbX4kfxf$nqgX(QYWAAz_AOsd@a^GMm!p;|~S)v31kim4fy?`#{u z8Z&@#K&Ndo#J_o3JzGXAk7=r_fLVAjy0hYM z^N8<8M=Eb|!fqcReHG$N<)_K-`9YXrcH~jDUG}ZR@mtr$zj{&VUEDPbg2hQH2f_(Xcd4Qi#I;T)W+b+J3 zdPkBRI0mJZm)QvvS#KhFMNV!$Uk3;9pQGSL`4G4bR&WB*o6?Z2+#v@?#egd3Q$_aW!6^7X)^v8AZz|hFQWJ;voB|FdvqrNB z(^>#LyvxI-LrC^6j3(|t;$-TBb#xr_wTp5>8wzAU%Ys*NJVF0h!ngm{?9p#LVUlu2 z@Fhx!>5vmFR7tMn)FjEVm2sKdivJ9;hgFucR(`>e#Y;o5pcPm%4^oNZ-5>pmvy}I_ zhrCeb2QLyt#`(ByPCWRJ_#*Uzo)pFeCz&%>;I@|R%Sj>&_g67SUD4v4Uoxzs2Y;2G zx%ZUMZI-RoH4fMeDyHT(2p3(_Ig?{)f9$XX!xB2iT?CM^Ib*^9XvMXxF$; zbrPWt8yK*0E=QW6U#I9w$D?V_zEH;)ByFq!EI*vvZLPy!R@)V|dHo787Rgr|$WXQKR6WrxR3G0`PuaVS z;Dzn(Eeq&swt=^{i-6CToT8-c3?>@7YnFP)L(w9=96JP53oHvwkCyIo=J%&@bY{_@ ziwvU3gLxt%&yT~uAnMSWrN0&7WJOY^_oMaXLFVRDtj`LjAZlWFa8-f8R!XjS;7W)X zI)s5xQ#6wDaq$J-m*l+xTT>}F*)&Tp#{eGYihvmdApwKEPvYV5^lUb7(s230wzV=s z4VUU`T*PQffV?dYSjd3=xd-G)V1-^Jel`sC*>cjeG+!Y8e^HokWt)JL>tjn;-0%hax^={g19S*p@7(rb zJ_<(BrCwcCjd1mE5ec~@6Z7Gb7a_@Jbq0xcN2;`7HP|@fZrJ>IO2S!sxNaKObK16W z+IPpMDO(jrsR9r6dtPRBOW617u3nU}87^3|kGwCc1&tn%?lrG4r5MeMF$@N*e@2$J zBeM4LQ``fz>6u%9GM|MQZnx3AYG8H23Ngkv%_}Bzu%KzSs{G7x>|N;h9eCDR6OsNMH)I{SptS zSL-((`eu>jFNfiJX=#_3-%`KY6=kqj!E;sA{KiHF-Qu3X%E>;Z6YL=>h~G^8py2Eu z%p7#sMc&7Lh5XSJf>mv~8^e)8B(F;0NeL)bvM*J`q!#j%NVlwGHV43PMDi{xS;w%* zK%Pxl)xlQYIvm&VcmzY9*5H|F>jq``(V-_d;iwCv3+vZhWBMANRiN0z7vR)N7HGE{ zgHd6>sXllCOKN>vw<;5u(tUlK&5VcT{>6o(z5n;G^#3zIevc54xBCBnvr&xy`1I+0 z{NFD!{$m*8a;XUR2>6RJA7h}!K<(X|q(3$1EAi#d`Okdz-2PsUvNW~zBR%%Sn8LR2>a|x02ec%hR!YFj%rs=042LmF{^Zz1H6&?6nt{}$fG@LD z+-_~nf`x2y`G}^MNu`2H%yRw_NbdUhKt?Vo;Lo)Wv-k7D^Ysx2s%w zP##mz2~z~*Y>F`*87nII>dpJ@SG^D0`#*?*DKwBht3@z@2a8wpvN;HrD{F=m!a>QB zW2B58c7w#9@On$Y=F20Cuc}J2Ou|w|O1u~=RyHlcAlOcAtR5+;Hd9`;kLhIKVx1oZGi`N}qP1y;g7%KFwU#1KZQqB=YaYr#L{D=QE` zDDhICU5?zs9%TqaVJb2`0Ss|>YWY@tE9U(UyKZfbPz?E~9Xc|ku?J~^ZDKogr6Hd= z9-ur7-lFoV6m1+R^~Pl32_)+PZ{bisv=w7Qn+C5h#S(O0&@^SPqrZIKWo!ng^{&1^dRM5iU9eV}r+2n`|Zenc0`CylN%>yJc}! zl_e`|zRp5UgAq>VsUH0EOxf31!dopU?;L_OQw1sY(OhGN@>d6%vZd||3ADQ9#kNHD zZYwxw01tZPkW<77QpXUTi0V*%^ct+bJ7&*|fhdRGmWxt=VZiV>*rLtu>~?rbd$CS^ z*iWwz(!UDXd~fQFC-hD`dBZ#!m_gt;)T!i>tdw22iX}+JEi&-!+@z9jpE_+w#s2Y zRz`c_#EqAHzi}`+&2Ns1S*jto;TEq-Yf4!vqTso5 z<=lS!JFDK|4%`wsZ;`QU89N$wty*R!eMf8O-H!+Mnb`oJQ(J>hs!8cBDAg+!vp0wO z)@W3?92R$1m01Oz!8W79w#T3I6z%a_jkVW@X7`y>41vFI4o!VF@Ce*_zQtIf>^XV$ z%Wb7I5r#}q)q1I{93B}f#FB9Sb-VER>h0}(*xudVf4^Hns(5OYT|Fd&D0h$3>!1N$ zK2D*t!OfzU+R{~^EOsIrN8YiG;vJQERO5X{>gR)_;}e zSt^K&=?7X%uV^U|&(23qAa*0ZuI~d;-;JHD!LKmr0!xy2g05-j82(G^Hm}0{LEg_n z_2I7oxH|mH2D1l3`1va6&$%fYN5W>g(67VP5MJ@V`ly_9m^ zFrNuznuFYBmI766M$Rv{~M2<6!E{m{^rT!`}_Z2 zfB#o90NFUnodH15$m7{!KH!5{Q-!PFli-0JfXd16*%TOcmDeQ({aaO$xL7g`E@=+0 z8_hRi1y^wcnv!J-#?eKO{G593ra#bGJHewP6|+n+1bgvJ;{tL*Z;bNXx0$Iqo9YaI zpT~G6|G)5God9DqjLni%HGTu&6di@ZyQ}oCDbnOX*1;?=r5FTwr{V7U7*=a|c zW;BzrKD#&!d#u8#K%yR>4jhxuhXFoO@?%3AE-k57`cz=8%{AmRjZ z{_YPUXuXx~aTP^}P)#TvYLOA316bKN!T{V>C?XpH1NoRsMND4 zNpsLZ(QLx;dqeMvu&gwo4U5~xD=S^Y^YunX-34f@XuwO}LQJxGMSq06wQfYjy;Y^U z@biW&s;{XJMf}ptaqLK*dgqU5*;WU0#0cov5 z+;5siOqsdG=3hPh1XukVgJD%4z*L~~R_Trdkp(%!7!rLkMS-tPzxVAh_zM~$WaxrQ zI!A$wGRH;V958YNNQ{eC62>7Lt+~sxiBYF9ASHOiD*TGlKwImsngK7KNLMxqGz`H_ z=%ft}l_R+h5_x&69Jsg($!lAclY3J;ZxYKP8l6X%xx_d(qYg_Sz)A-T<`Cs7E?;2? z3S)5PoG7a}nr;oJX9v^nsvLs~}?wG=ZP;gLed01kGct{M@ma{&S zt8^IOnPZXf=h^hkAANdcsr#Fb1OoEmaEt(!nQM-e+iNj=Mn%qtH;v_z%7?`r*cS{1 zROCe{^!l@^P2m*6pfuwfm+Y|B-Be_X%7_~p6oacTujqvuW`(D4_wE+1b&_cYKI2ef zB@lGMVbKab>BZPB3|O%e$ME&1Su`8~@IC4e>o~sKwCGF4_Jf)G%o8iORPk;;iOvll zs0E}>>}#I>ZUyTsi@K<+i|SsJg+-+B0fJ)Mw>4B20=z;e@yhN5Am>Gto;q09+xQRA zOB`n)^LOL?3H?&31_zL5YU<+ux^EPs zrzr%pW4koUXIM1;%hVG`<6zbNtPl~NW6=cc1|hmOdWe~3nOa}Jr$<%`*eF0lom2B}c0Q!NEZc!`Rg`462V));5{=llI1 zc6K2)6&n69X$pW8G{OemCGS4I{fkKfb=CqZNB0NPZ{PptN&0y6_t^cn?*GS+O8fuG z=F@NP_x~4T{}(i-{Xv!4q&53@$dw-vcMnalWeA<3;qO4xSAy;iJEB!dQTX> zE&?8}KZ?gdix3|yGH>m-#FnhYGX_zyDy0Q7zAcUC=r5&)ZR+ zoUgICNJ5=vM0n6teG-xwQyiza+kc6()9t=||L(ij-ybwiGw>?U8wg*3!{CX?&2sprT8X29+UB-MDw_8DO7O$`w>yQO zuXbPmxMP@H_!~SFRPy$R53jcOx7C-Adpo-ycHe*Z`pr&>`fCn^+s{5pWSE(FnRN)K z-=g~!X6W%|k2(y7>_y>wAURGUb_n@eY>~eLv|0HpB**2f)?3aNzz&vTg{*Kx1&i#eIv^t5#Fk z@Fk8x-LRSsTuv#x+6d7BY>E(M6LqqsLY<%ir(dHg24gdLCnRX6o9%&3&olRQ&COW> zK`LO~!OPd2r{}N>`MX|ku0cRWS>8h9PY{y(@DSj**BhnQ+&}34lmEeq9iEtD*<8)P zR~@(Tf8RWQvRUB&9)Dw4!h8PjOSJzi3JeTK_z!wz?pXU7;dRVTFqVy!prYBHhIPIGYCVi2|CvZhPHI1FYcT*h8=kxJ6LK{jv zz$v&jpyaNN5(4fxnMPy8GC_?sK|25_2X)Q&>wos_e_rkEz1)5MVPD+wekIiqK`JQT zkQaMQfE*mOlPO`DHAD%4h#b*H=&A*~N1yjPjw7^&6W(OS2HZ9r7);o59>{EE$Jk^{ zY~#fwhAkEh-I9z>e~`H(SAX)UqJg_`-{&f;*}k9N{rc4@*db10X z10SV@CW(Xzy$P>3YfpW(d`{0M;H`GGEiL<9AFHtckN$dgPW0wA?J+Kf)^&F@>J(>e z4hoyZR>7H;T5YUm-k;UDx5vc5$#v7_`D;8_I9_bAY7F$$7FI7dYE_v2B*|#8kmmBI zL48R!ok4vPXYQXgTB!9kDecb%yQpde#3<4SL9r7+0U-YpXfhkP1^HUp)HH*5`P)aM&l#Hq z&%M&e?)LPk^eU~ZHTK5rjQ>*CPc-8Vo#C|2s{^y6+sPE8z%JZVkzi8{N zCr#mXn*EyDQO6x$RY|(9e0}u8ob_4`hWT1Tua2=bo>f(fu#MG^j+^bgNb2emVT&@$ zlMkOwyZox=)$5{7-(xLrnxE5HYW*};)APx%Nekp_3T_LZzr%h}qoVl0N^c(qLot=k z+mpHtY-S#teC_bdtNI02_qPaccswhq_siL%J$)OF=WcOlvXQT{RS;ghVQ0ys4bKxJ zb69`Oy0P?#;j!l(=c9Y`w>O>rVCbb^v`4jy@5t)~8@I7tmoWJF>yhoQ=^1za@BUx@ z|NX!CxBLIgGcf%B&&;6naIZSUEf$7B4U#ible3FUbBpyV6LWL)(yM6TS_2?3F)?8P z(LjJs81CMqIHps1Bc6J+oN#_u{?*<1D2iH>3`t*MB(X5^Y1CQ zmN_t8d7W3WH?Cj){{4wh-+rw5_ljTt|A&10|9fnoA80!@CpkU%O3)o;@24{YU&-z| z@ulLIl@{|0?nsz3=||aR2^_5=q_ii@Lm)inL~@{uw6ZFov~@p>K; z9kB;3lZ5BnRX(h@tLEICb?rmhDP}2z z^y_aV7D*oWj#^?hCG5zKQ~|Ttr&beJRJ-l+R5Rm4}5iZ_cS3;R5aeJ1f&_O7E&+1h zoq0cI-hHp$Ox4t#cVAW3pWa=od+pV$`>XwZy&b_GW|n3iWMT^0onk9sb_&yXSx8 z|IfAkZE?Sw{%7q{LC_IGZeaLG$j5qL;|^Zo2kx@&3E|uzs*_|j7cFI8#$efUnudvx zrF^6}K8^G)oC>%v%0JOqsn&rBD|I(jqF7pPMfbT{3M8$&EWnvrtG$x-5E~%6h%&Xc zQG{QA4z!Nmv4rWbB6;6un_pF!ja;Rt%s_ z=!b>iruQieynQynLOwpr5>kMWmo)#bppisUlkiO?gL0?4+*{-~^`E)&jP2=z`6KE; zWr1MSY^0toF1h(D1qNQ2{;~V!u%pnkyda>vy)oAIqCih%N0`X*XEH2mOY?mv41>C8 zPQxafB06-N8^4R1uDYrxWKx_@y*E}@2z$!erblAm&ln`@EFFXDUKJSowqPPRM<+GpOQZ8GEw@fdH7t4a;buhwqyJq{{b+DHs`(XAaYf)x$JwZqugdai~kXO<4Q& z4(;&=5qApA_-#FVu(o>$&SmR#Az4e$1*GkI3j_6cpIUf(fGDt?Xa^|{@bDm1OmkH&r5S~xi|EB3o1Zg#QE zVeRw&(jnJgj4!TY(+Qbrlwxg%kYeq)W4Ev9pA5aV@M_k;_MnkrUTnyx;m#_5&FXWH z%XetPCTPs7Su7$RoTf8AW{!@j&NNg+Go4JNy!Z8+O87$+Ay#>I0iYV-v8pzQ?;qz>l*?4_f~4UH>4+@roD zydqrenF=@-iv& zjQ%V6(Lyi$Lmi^6i&w>_t#WP^A!`C_pjJ{DwB>YSdfH)9zpl1`0Z*ktv% z(nfm4mM0lzM`EMiHhrk&3Ma}XjkYSJmD17P*>cP7No;IjKWU((0$Ka9K-7gx27@$= ztyI`}0)n<*r!^ZbvU~(`EGLJxj)tPQ4-2WLWoF9t*JL`jTbdr}czAxh!%wdVsGg;w z78Bd9gvylHPYT8b#ISLpj8xu@*RhRQ6|m+!u}#{H=|eQ_Wwtz)15aP~C!(2S>DBGG zd{fYOX-nn2MDxfByz=-u-86C5VN|RHlas7bfI*D_#$MAbb}U$Nd#z8Y(}i0|)ok8O zyyc`{QubPzkZ#Ilxyb4n66e#l3Ouu38rA3^j`Z-F7tg7AGu`xh6|Y7Hsf0Tcedf(T zt)g|X2zw~m=O%Z~)F$Pzmx#GCs@n`LUT4z2@O2uD>@e?8-v*7^|O42)^3X{S{bXO zN#8YoY_wqDFD($XxLg_1nWcK}ye_r!Oc-B$%cxYKp7x1e*R4^@K%i9F&vb{RfZh31 zDLZGaO-D2F85#Lwatv9e$l-1{c-OVb=+&4L|7x5{J1gcao^oct=dP9@6ht1WhR$3X z9%`+i=ZGe~W8$PD<;*W5e{`_z*iaicqK+@6u?(A>0#~8R$BPIzc8z&UwD;h8^ltm% z*5#_fd4Bv^>TS#EMoTH#d^C0k zl<8WBNf=<|v!1-V7FLf1tx@F4?1w3VPhcRyi4L7sst)QGU*S0{f9}ef#BaqqozIuw zt(-JuU+gy0tPQoE_*R0j(XtBk2QgW$g;vuoQ&g6$(_Y$s?#ZEnDgsHXHq`<3k(hZR z7FF-j$uBTGa_s5J=G*B{FyU*kgvFx(w3AeqK z&?AEW!%cX^t>0B_ZkWCQQQpG!RAKy`Cx3s?)t<+X{4lab`N%qEsn%(jTKL9BYi9Z5 zjqTAx4+Y?eP3qxhe^o5l5A(zNcTY>$p@qq{&ruUI<8@|=>$)68HAsr|X<~-O#Xvvr zg}>0v^_xEEz+Lw=8Sibgk4OETNhUlP6pw%ZBW(dLWDVH%+9@6AlWlaMf@c4?KUof^ zoxxcJ|Ln-3cY3?b#ys;dpi)3-mtgd)glHpX7Ct0))+X*6_28JE;hgb)!I@YrK&M&+ zpf}tpt@1s~mX13+z-J*So9bF>l}v=T+j1_xZ%PP0am0Y9piInqNFWy7qIE`mlg07y{gx z|LAIb4~0}oLpvz>n0cOeevJHO*olxd5hDj9~Z-M zkVpj-z4}(zU2L^3VtCqlXXo)vu)w+7-432U(>=B)CklVq*8Cn1zGxMIM#HF>g`0lx z*nV`j`$!O^9OakMIp%*CFXk5j&AvS6jv1?ZG+6r?!}s{2tGr@=+UOfb*vkH%xh&LJ8Nb zn*&r@=8z>3wYg+i8^Yne;Iw`1^r7m&4%vlZMY>*&Epj~)IVgrEjzM`{h&GvN4Z6Nd z`xKY#8Ct_~N|4!U@MCl@&N5f|RO1}g%}JeJW!DfEl66!Zk@BWD4+#N>u%l! zyc1{^YN$dPZWm?TzA-O5f>lmb?RZwRh1ODcm49VLsj3|bzxqfF!!Pyyknkm0ar3LZ zfLJ4sZ>h;9)8U*9*}R_OF5+|~q4^0L-(pRU9!y9#S(z8&Tt>=} zc^BzR2kA~N+bj#QG~sY42Lp;@iG#nr=qK76ctkp6$tC`;+W$8N{C}wbdAK>bf3N>} zc=>+e|94RRL%M&{|3`Y?ot9+rZ*~J?5YKzm#T8SN1q6^E#T7l2ve}-}=NOujuMxF# zw=%XL0d3`0&#C7Dd-j*=Kj?GxHKMD395l(e?MWc(Kl9#&A00guWr&^aB+he8ch<^A z_4V}?rg7Y0zh3+)Muu~CVdDV`dh`pBKJ1%1oEjAoSiVP_P0zIV*ai~N!YR5+uUo_J zv(&Pm2;5ktk4PuWesT}ktN%_(H^^9FVDFpr<@7?8Q&9K;pv0ZqtFNh*k=iT3x!uY= zpq)6{yIh4BMCaZ#zKL*$E1UAll*LJ=rb05Aw?C9Pez-fdOtuDJWE7ZB7 zm`BRcTpKKtcAEv1E0DRx&D+FRTLLkKYo{JfM1Q_GunfApwSbW+pu!|l#qYC}+unPY zWM0oCFYO-NHRAWOf?s+Tx0!y!!?;Gr!K4pW3y2c?;dG5rh#p&+*uLHBt?l%O< zS%3vSQ7=N4IArR=9F|oG35(E8?+B^rhZjG`;#Y-S4u;&PePa}i^xDjhRDo7b=n#kt zo-}19w85A2X1A2a;B2DPcUi8|=IO`QTZE|$p)7sP6I4Gc12|*PM&MreOUPG!&Mdz+ zpN)L$laVodWiz$+8HZ2{K*#RMbC?2Z8AFppwfE6VhIQIxE~Hle2;lyCgg$+UM%0`Y zVD=z?nM37^-Ih<4UwH(=R1+yCU_h!w+1@d(jL^WssR(7e48WU`oBP3iwM=>t^XgXA z9eRAcr>ef!K66nk^b?v1-#l|^6M@HLM|Ir6+4uB?d`X4yNGHHwY|`!IFRp&F8Ly9% z@s09Ya2QX1sm4-1l$?DqAk32~epi)ZEH#Mr4aQV0GXnAA)Y}P*Bi+>k3LwRnD7Y4J zXAY*CO&$b%;bm`I024>Z*Hn~e6 za=o+@?r2#J^=R&aatmwz4u?mTFb1O0Rfwdr){#kcE+70BcR;EwF z%zn`JA*M(b#r&kK(gAi|98Sy`K)l-*Y-KvVUd1Zr9a13%Sba&!c+2oSpKklc3R9}= zHoJ{2Ciq+dLPb_SpiO01HOQ-3re4^fQDy1)fy_-39c`{+9|8M;k9LSs;_MBvPXIb+ zJqhCM*_jOUS&pdcp4v!?_ItCQGfe!1dcc$8Q!=H_3EOK`Enmndv=whYr1p>d)O%gN zE(RKjTZWo!Iga6}73G+y6CW7DLv+hUo-4Y7dE6KdD=DdwmKNYgZ29t2J^0hE(b2Hm z!fl$P7=dd8Og5a*&x+Ml97Th=@n(@g-S%7Y=78ky{`$*LqU(5`JKXy5)n7gd^I#&q zXYb!o#B7Q1?*o{SMX0u{KeFZUCJOZ@AgIaJ6L? zS$Lcl<#3D7&oN%yB$bud2jK%?Zq+cAzvSxVTkZ;N{1I~t+QXdOAVTy>MeK}DH#k~) zMT=c(X%+yu&B<%=_t6q$ish#=^y+#{d)6ydJpSW*!)28@KRt2&XW0V46|w{x%#PzV7{_ko|!_i1*v$&kNTc=uy>`MGWzAol>iZqxJyUMt&oRs-)wC1P)Gv|hmULWc6VLS`@Whm z1e1W*hw3HgpyMiR6y?>+=bxG>tQ2lk?RB>k79jYPa4dY%l7~!@Kw%O&c1<;Ob3h_^ z2kw=`VQST$b9#%sGCivEC@jau`Ubs+x+fdP)FYit)b$LLHZoDK*VU@ehZiwd*@hHR z9eQujUFC7B47rjcoQXc4S59YwMqoo~x64qddL2?DnHz<}6OxCiVD>;9d zEc4w0xI%T$v(Fw$b>m?$nPqWgUUzum?U0pNW2t}WG}wL z3VJ$gRoDx(ED3a=BEjCdzw+>pW|p8`;x=v-ZZ>_lw#m-_{UASWk7Yt*gWlrBeP6|1 zjX7MYn~JC+OIy3V;k=j#N3by?y|DAY)CzFLnXC96{xgtW@YK4~OMZ>l`Et=|cOBCtgM>n2r zzE1`ZqEZFtJcv>4^6K0RBY7@t>n!|Gp|6A==2@vhgK{tG=oy}e4U^Nn=H&+W=g)2? z*gD9+)#te#FJvx4Wxa|(332TQ^&nU*7zi#P(Hw4{CJKfU`=dlq3k{gr`|=kK`8IeW zW>DF#Cb>Y2bFCZSVSqe|cSMOI;-ZE=TG)Us?A<*b-GRPljt+l}3j7E6Kb#=m-~ayw z@p1ja|G$9he}3xU^dC4uB#BTQJ>o)Sz|fQ}bH}@Jd`tv!($vyid29dpixM&t)3+N+ zVJNKC*+eX1`|xKj*`@P;MaM(SqZ1>0-v)?9%t>OjRKmHd>Ck!dhf z`h9~hX*W?4coZOP%!T%!@*KU$XWP~o)|whzaumwPYqh3x}BR5N)0K$ zk50Q^Osu~5S%$4~tX6n<28KEynTJ8!cWWXbI`o8j)NvK8wk7y(I^~ zr~IV4FZhEznM`)*fOUECvanQN>}wRy5|Y1K?F)x&| zg+gk`IamwN&5f(_q8`$lwn##9XeM}kZN#tRm3LYpAz8OmFMPvUMj2qeP$v&|M@5-5 zpBG=XdO3Wc67igQ#DXii|B*dZDqEQv#g5`Dn264oXkOEbxHA>N2-U{j=msf>atrFy zH)ngH0tXiQ9Q!0}6n;7nF)GT+ULIk0J!3Gz(qu1?dey)CWQ9nhZT6&}Hsi7%mvj1H zJ?Vjk=>@cf--j6MR_f@Dem?YgS?6W2NWsv#gSS~M^d#ZDYVly*UOl*@#K<0nw~HSQ zg+6a9zeSW8U2-A&43F>Q%Xv&she4XoSItm|P`@T&rU$_o4kMziOC diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem deleted file mode 100644 index 98f9a48ce6d1b1fd431f8bedcfa2523ea334a9d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167936 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

&;l`z>!7E|X9z1!;PcuK-hsOJ+Sf(SV*zoZ$ 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¥p_>;3bGvV3bou|^wDuS8fw>; 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 E1={BUjsO4v diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.7.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.7.gem deleted file mode 100644 index ce97509006fd3d0129e90188bbd809b299cb62e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82944 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%0A+kzZ`jm9WrmLHQ1f=7M%fxS-o>;Rw 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 nIeQ1}r7wP diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem deleted file mode 100644 index a60935045757b8694c9a7e9298f67513c2b112bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40960 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

-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 1.9`. - - Resolves [#63][issue-63]. - -## 1.4.2 / 2020-06-23 - -- Camille Drapier fixed a small issue with RuboCop configuration. [#59][pull-59] - -- Applied another fix (and unit test) to fix an issue for the Chef team. - [#60][issue-60], [#61][pull-61] - -## 1.4.1 / 2020-06-23 - -- Fix an issue where diff sizes could be negative, and they should be. - [#57][issue-57], [#58][pull-58] - -## 1.4 / 2020-06-23 - -- Ruby versions lower than 2.4 are soft-deprecated and will not be run as part - of the CI process any longer. - -- Akinora MUSHA (knu) added the ability for `Diff::LCS::Change` objects to be - implicitly treated arrays. Originally provided as pull request [#47][pull-47], - but it introduced a number of test failures as documented in [#48][issue-48], - and remediation of `Diff::LCS` itself was introduced in [#49][pull-49]. - -- Resolved [#5][issue-05] with some tests comparing output from `system` calls - to `bin/ldiff` with some pre-generated output. Resolved [#6][issue-06] with - these tests. - -- Resolved a previously undetected `bin/ldiff` issue with `--context` output not - matching `diff --context` output. - -- Resolved an issue with later versions of Ruby not working with an `OptParse` - specification of `Numeric`; this has been changed to `Integer`. - -- Brandon Fish added TruffleRuby in [#52][pull-52]. - -- Fixed two missing classes as reported in [#53][issue-53]. - -## 1.3 / 2017-01-18 - -- Bugs fixed: - - - Fixed an error for `bin/ldiff --version`. Fixes issue [#21][issue-21]. - - - Force `Diff::LCS::Change` and `Diff::LCS::ContextChange` to only perform - equality comparisons against themselves. Provided by Kevin Mook in pull - request [#29][pull-29]. - - - Fix tab expansion in `htmldiff`, provided by Mark Friedgan in pull request - [#25][pull-25]. - - - Silence Ruby 2.4 `Fixnum` deprecation warnings. Fixes issue [#38][issue-38] - and pull request [#36][pull-36]. - - - Ensure that test dependencies are loaded properly. Fixes issue - [#33][issue-33] and pull request [#34][pull-34]. - - - Fix issue [#1][issue-01] with incorrect intuition of patch direction. - Tentative fix, but the previous failure cases pass now. - -- Tooling changes: - - - Added SimpleCov and Coveralls support. - - - Change the homepage (temporarily) to the GitHub repo. - - - Updated testing and gem infrastructure. - - - Modernized the specs. - -- Cleaned up documentation. - -- Added a Code of Conduct. - -## 1.2.5 / 2013-11-08 - -- Bugs fixed: - - - Comparing arrays flattened them too far, especially with `Diff::LCS.sdiff`. - Fixed by Josh Bronson in pull request [#23][pull-23]. - -## 1.2.4 / 2013-04-20 - -- Bugs fixed: - - - A bug was introduced after 1.1.3 when pruning common sequences at the start - of comparison. Paul Kunysch (@pck) fixed this in pull request - [#18][pull-18]. Thanks! - - - The Rubinius (1.9 mode) bug in [rubinius/rubinius#2268][rubinius#2268] has - been fixed by the Rubinius team two days after it was filed. Thanks for - fixing this so quickly! - -- Switching to Raggi's hoe-gemspec2 for gemspec generation. - -## 1.2.3 / 2013-04-11 - -- Bugs Fixed: - - - The new encoding detection for diff output generation (added in 1.2.2) - introduced a bug if the left side of the comparison was the empty set. - Originally found in [rspec/rspec-expectations#238][rspec-expectations#238] - and [rspec/rspec-expectations#239][rspec-expectations#239]. Jon Rowe - developed a reasonable heuristic (left side, right side, empty string - literal) to avoid this bug. - - - There is a known issue with Rubinius in 1.9 mode reported in - [rubinius/rubinius#2268][rubinius#2268] and demonstrated in the Travis CI - builds. For all other tested platforms, diff-lcs is considered stable. As - soon as a suitably small test-case can be created for the Rubinius team to - examine, this will be added to the Rubinius issue around this. - -## 1.2.2 / 2013-03-30 - -- Bugs Fixed: - - - `Diff::LCS::Hunk` could not properly generate a difference for comparison - sets that are not US-ASCII-compatible because of the use of literal regular - expressions and strings. Jon Rowe found this in - [rspec/rspec-expectations#219][rspec-expectations#219] and provided a first - pass implementation in pull request [#15][pull-15]. I've reworked it because - of test failures in Rubinius when running in Ruby 1.9 mode. This coerces the - added values to the encoding of the old dataset (as determined by the first - piece of the old dataset). - - - Adding Travis CI testing for Ruby 2.0. - -## 1.2.1 / 2013-02-09 - -- Bugs Fixed: - - - As seen in [rspec/rspec-expectations#200][rspec-expectations#200], the - release of `Diff::LCS` 1.2 introduced an unnecessary public API change to - `Diff::LCS::Hunk` (see the change at - [rspec/rspec-expectations@3d6fc82c][rspec-expectations@3d6fc82c] for - details). The new method name (and behaviour) is more correct, but I should - not have renamed the function or should have at least provided an alias. - This release restores `Diff::LCS::Hunk#unshift` as an alias to #merge. Note - that the old `#unshift` behaviour was incorrect and will not be restored. - -## 1.2.0 / 2013-01-21 - -- Minor Enhancements: - - - Added special case handling for `Diff::LCS.patch` so that it handles patches - that are empty or contain no changes. - - - Added two new methods (`#patch_me` and `#unpatch_me`) to the include-able - module. - -- Bugs Fixed: - - - Fixed issue [#1][issue-01] patch direction detection. - - - Resolved issue [#2][issue-02] by handling `string[string.size, 1]` properly - (it returns `""` not `nil`). - - - Michael Granger (ged) fixed an implementation error in `Diff::LCS::Change` - and added specs in pull request [#8][pull-08]. Thanks! - - - Made the code auto-testable. - - - Vít Ondruch (voxik) provided the latest version of the GPL2 license file in - pull request [#10][pull-10]. Thanks! - - - Fixed a documentation issue with the include-able versions of `#patch!` and - `#unpatch!` where they implied that they would replace the original value. - Given that `Diff::LCS.patch` always returns a copy, the documentation was - incorrect and has been corrected. To provide the behaviour that was - originally documented, two new methods were added to provide this behaviour. - Found by scooter-dangle in issue [#12][issue-12]. Thanks! - -- Code Style Changes: - - - Removed trailing spaces. - - - Calling class methods using `.` instead of `::`. - - - Vít Ondruch (voxik) removed unnecessary shebangs in pull request - [#9][pull-09]. Thanks! - - - Kenichi Kamiya (kachick) removed some warnings of an unused variable in - lucky pull request [#13][pull-13]. Thanks! - - - Embarked on a major refactoring to make the files a little more manageable - and understand the code on a deeper level. - - - Adding CI via Travis CI. - -## 1.1.3 / 2011-08-27 - -- Converted to 'hoe' for release. - -- Converted tests to RSpec 2. - -- Extracted the body of `htmldiff` into a class available from - `diff/lcs/htmldiff`. - -- Migrated development and issue tracking to GitHub. - -- Bugs fixed: - - - Eliminated the explicit use of RubyGems in both `bin/htmldiff` and - `bin/ldiff`. Resolves issue [#4][issue-04]. - - - Eliminated Ruby warnings. Resolves issue [#3][issue-03]. - -## 1.1.2 / 2004-10-20 - -- Fixed a problem reported by Mauricio Fernandez in `htmldiff`. - -## 1.1.1 / 2004-09-25 - -- Fixed bug #891 (Set returned from patch command does not contain last equal - part). - -- Fixed a problem with callback initialisation code (it assumed that all - callbacks passed as classes can be initialised; now, it rescues NoMethodError - in the event of private :new being called). - -- Modified the non-initialisable callbacks to have a private `#new` method. - -- Moved `ldiff` core code to `Diff::LCS::Ldiff` (`diff/lcs/ldiff.rb`). - -## 1.1.0 - -- Eliminated the need for `Diff::LCS::Event` and removed it. - -- Added a contextual diff callback, `Diff::LCS::ContextDiffCallback`. - -- Implemented (un-)patching for standard diff callback output formats with both - `#diff` and `#sdiff`. - -- Extensive documentation changes. - -## 1.0.4 - -- Fixed a problem with `bin/ldiff` output, especially for unified format. - Newlines that should have been present weren't. - -- Changed the `.tar.gz` installer to generate Windows batch files if ones do not - exist already. Removed the existing batch files as they didn't work. - -## 1.0.3 - -- Fixed a problem with `#traverse_sequences` where the first difference from the - left sequence might not be appropriately captured. - -## 1.0.2 - -- Fixed an issue with `ldiff` not working because actions were changed from - symbols to strings. - -## 1.0.1 - -- Minor modifications to the `gemspec`, the `README`. - -- Renamed the diff program to `ldiff` (as well as the companion batch file) so - as to not collide with the standard diff program. - -- Fixed issues with RubyGems. Requires RubyGems > 0.6.1 or >= 0.6.1 with the - latest CVS version. - -## 1.0 - -- Initial release based mostly on Perl's Algorithm::Diff. - -[age]: https://github.com/FiloSottile/age -[hoe-halostatue]: https://github.com/halostatue/hoe-halostatue -[hoe-markdown]: https://github.com/flavorjones/hoe-markdown -[issue-01]: https://github.com/halostatue/diff-lcs/issues/1 -[issue-02]: https://github.com/halostatue/diff-lcs/issues/2 -[issue-03]: https://github.com/halostatue/diff-lcs/issues/3 -[issue-04]: https://github.com/halostatue/diff-lcs/issues/4 -[issue-05]: https://github.com/halostatue/diff-lcs/issues/5 -[issue-06]: https://github.com/halostatue/diff-lcs/issues/6 -[issue-12]: https://github.com/halostatue/diff-lcs/issues/12 -[issue-21]: https://github.com/halostatue/diff-lcs/issues/21 -[issue-33]: https://github.com/halostatue/diff-lcs/issues/33 -[issue-35]: https://github.com/halostatue/diff-lcs/issues/35 -[issue-38]: https://github.com/halostatue/diff-lcs/issues/38 -[issue-43]: https://github.com/halostatue/diff-lcs/issues/43 -[issue-44]: https://github.com/halostatue/diff-lcs/issues/44 -[issue-46]: https://github.com/halostatue/diff-lcs/issues/46 -[issue-48]: https://github.com/halostatue/diff-lcs/issues/48 -[issue-53]: https://github.com/halostatue/diff-lcs/issues/53 -[issue-57]: https://github.com/halostatue/diff-lcs/issues/57 -[issue-60]: https://github.com/halostatue/diff-lcs/issues/60 -[issue-63]: https://github.com/halostatue/diff-lcs/issues/63 -[issue-65]: https://github.com/halostatue/diff-lcs/issues/65 -[issue-70]: https://github.com/halostatue/diff-lcs/issues/70 -[issue-91]: https://github.com/halostatue/diff-lcs/issues/91 -[issue-95]: https://github.com/halostatue/diff-lcs/issues/95 -[issue-100]: https://github.com/halostatue/diff-lcs/issues/100 -[issue-102]: https://github.com/halostatue/diff-lcs/issues/102 -[issue-106]: https://github.com/halostatue/diff-lcs/issues/106 -[issue-107]: https://github.com/halostatue/diff-lcs/issues/107 -[pull-08]: https://github.com/halostatue/diff-lcs/pull/8 -[pull-09]: https://github.com/halostatue/diff-lcs/pull/9 -[pull-10]: https://github.com/halostatue/diff-lcs/pull/10 -[pull-13]: https://github.com/halostatue/diff-lcs/pull/13 -[pull-15]: https://github.com/halostatue/diff-lcs/pull/15 -[pull-18]: https://github.com/halostatue/diff-lcs/pull/18 -[pull-23]: https://github.com/halostatue/diff-lcs/pull/23 -[pull-25]: https://github.com/halostatue/diff-lcs/pull/25 -[pull-29]: https://github.com/halostatue/diff-lcs/pull/29 -[pull-34]: https://github.com/halostatue/diff-lcs/pull/34 -[pull-36]: https://github.com/halostatue/diff-lcs/pull/36 -[pull-47]: https://github.com/halostatue/diff-lcs/pull/47 -[pull-49]: https://github.com/halostatue/diff-lcs/pull/49 -[pull-52]: https://github.com/halostatue/diff-lcs/pull/52 -[pull-58]: https://github.com/halostatue/diff-lcs/pull/58 -[pull-59]: https://github.com/halostatue/diff-lcs/pull/59 -[pull-61]: https://github.com/halostatue/diff-lcs/pull/61 -[pull-69]: https://github.com/halostatue/diff-lcs/pull/69 -[pull-71]: https://github.com/halostatue/diff-lcs/pull/71 -[pull-72]: https://github.com/halostatue/diff-lcs/pull/72 -[pull-73]: https://github.com/halostatue/diff-lcs/pull/73 -[pull-75]: https://github.com/halostatue/diff-lcs/pull/75 -[pull-79]: https://github.com/halostatue/diff-lcs/pull/79 -[pull-80]: https://github.com/halostatue/diff-lcs/pull/80 -[pull-82]: https://github.com/halostatue/diff-lcs/pull/82 -[pull-84]: https://github.com/halostatue/diff-lcs/pull/84 -[pull-86]: https://github.com/halostatue/diff-lcs/pull/86 -[pull-89]: https://github.com/halostatue/diff-lcs/pull/89 -[pull-90]: https://github.com/halostatue/diff-lcs/pull/90 -[pull-92]: https://github.com/halostatue/diff-lcs/pull/92 -[pull-93]: https://github.com/halostatue/diff-lcs/pull/93 -[pull-101]: https://github.com/halostatue/diff-lcs/pull/101 -[pull-103]: https://github.com/halostatue/diff-lcs/pull/103 -[pull-104]: https://github.com/halostatue/diff-lcs/pull/104 -[pull-105]: https://github.com/halostatue/diff-lcs/pull/105 -[pull-129]: https://github.com/halostatue/diff-lcs/pull/129 -[pull-147]: https://github.com/halostatue/diff-lcs/pull/147 -[pull-148]: https://github.com/halostatue/diff-lcs/pull/148 -[rspec-expectations#200]: https://github.com/rspec/rspec-expectations/pull/200 -[rspec-expectations#219]: https://github.com/rspec/rspec-expectations/issues/219 -[rspec-expectations#238]: https://github.com/rspec/rspec-expectations/issues/238 -[rspec-expectations#239]: https://github.com/rspec/rspec-expectations/issues/239 -[rspec-expectations@3d6fc82c]: https://github.com/rspec/rspec-expectations/commit/3d6fc82c -[rubinius#2268]: https://github.com/rubinius/rubinius/issues/2268 -[standard ruby]: https://github.com/standardrb/standard -[tidelift]: https://tidelift.com/security -[tp]: https://guides.rubygems.org/trusted-publishing/ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md deleted file mode 100644 index 184b5fb..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, caste, color, religion, or sexual -identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall - community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or advances of - any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email address, - without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official email address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at [INSERT CONTACT -METHOD]. All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of -actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or permanent -ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the -community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.1, available at -. - -Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. - -For answers to common questions about this code of conduct, see the FAQ at -. Translations are available at -. - -[homepage]: https://www.contributor-covenant.org -[Mozilla CoC]: https://github.com/mozilla/diversity diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md deleted file mode 100644 index 4bcde4b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md +++ /dev/null @@ -1,71 +0,0 @@ -# Contributing - -Contribution to diff-lcs is encouraged in any form: a bug report, a feature -request, or code contributions. There are a few DOs and DON'Ts for -contributions. - -- DO: - - - Keep the coding style that already exists for any updated Ruby code (support - or otherwise). I use [Standard Ruby][standardrb] for linting and formatting. - - - Use thoughtfully-named topic branches for contributions. Rebase your commits - into logical chunks as necessary. - - - Use [quality commit messages][qcm]. - - - Add your name or GitHub handle to `CONTRIBUTORS.md` and a record in the - `CHANGELOG.md` as a separate commit from your main change. (Follow the style - in the `CHANGELOG.md` and provide a link to your PR.) - - - Add or update tests as appropriate for your change. The test suite is - written in [RSpec][rspec]. - - - Add or update documentation as appropriate for your change. The - documentation is RDoc; diff-lcs does not use extensions that may be present - in alternative documentation generators. - -- DO NOT: - - - Modify `VERSION` in `lib/diff/lcs/version.rb`. When your patch is accepted - and a release is made, the version will be updated at that point. - - - Modify `diff-lcs.gemspec`; it is a generated file. (You _may_ use - `rake gemspec` to regenerate it if your change involves metadata related to - gem itself). - - - Modify the `Gemfile`. - -## Test Dependencies - -diff-lcs uses Ryan Davis's [Hoe][Hoe] to manage the release process, and it adds -a number of rake tasks. You will mostly be interested in `rake`, which runs -tests in the same way that `rake spec` does. - -To assist with the installation of the development dependencies for diff-lcs, I -have provided a Gemfile pointing to the (generated) `diff-lcs.gemspec` file. -`minitar.gemspec` file. This will permit you to use `bundle install` to install -the dependencies. - -You can run tests with code coverage analysis by running `rake spec:coverage`. - -## Workflow - -Here's the most direct way to get your work merged into the project: - -- Fork the project. -- Clone your fork (`git clone git://github.com//diff-lcs.git`). -- Create a topic branch to contain your change - (`git checkout -b my_awesome_feature`). -- Hack away, add tests. Not necessarily in that order. -- Make sure everything still passes by running `rake`. -- If necessary, rebase your commits into logical chunks, without errors. -- Push the branch up (`git push origin my_awesome_feature`). -- Create a pull request against halostatue/diff-lcs and describe what your - change does and the why you think it should be merged. - -[hoe]: https://github.com/seattlerb/hoe -[qcm]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html -[release-gem]: https://github.com/rubygems/release-gem -[rspec]: http://rspec.info/documentation/ -[standardrb]: https://github.com/standardrb/standard diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md deleted file mode 100644 index 9053019..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md +++ /dev/null @@ -1,49 +0,0 @@ -# Contributors - -- Austin Ziegler (@halostatue) created diff-lcs. - -Thanks to everyone else who has contributed to diff-lcs over the years: - -- @ginriki -- @joshbronson -- @kevinmook -- @mckaz -- Akinori Musha -- Artem Ignatyev -- Brandon Fish -- Baptiste Courtois (@annih) -- Camille Drapier -- Cédric Boutillier -- @earlopain -- Gregg Kellogg -- Jagdeep Singh -- Jason Gladish -- Jon Rowe -- Josef Strzibny -- Josep (@apuratepp) -- Josh Bronson -- Jun Aruga -- Justin Steele -- Kenichi Kamiya -- Kensuke Nagae -- Kevin Ansfield -- Koichi Ito -- Mark Friedgan -- Masato Nakamura -- Mark Young -- Michael Granger -- Myron Marston -- Nicolas Leger -- Oleg Orlov -- Patrick Linnane -- Paul Kunysch -- Pete Higgins -- Peter Goldstein -- Peter Wagenet -- Philippe Lafoucrière -- Ryan Lovelett -- Scott Steele -- Simon Courtois -- Tien (@tiendo1011) -- Tomas Jura -- Vít Ondruch diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md deleted file mode 100644 index c57c3f1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md +++ /dev/null @@ -1,40 +0,0 @@ -# Licence - -This software is available under three licenses: the GNU GPL version 2 (or at -your option, a later version), the Perl Artistic license, or the MIT license. -Note that my preference for licensing is the MIT license, but Algorithm::Diff -was dually originally licensed with the Perl Artistic and the GNU GPL ("the same -terms as Perl itself") and given that the Ruby implementation originally hewed -pretty closely to the Perl version, I must maintain the additional licensing -terms. - -- Copyright 2004–2025 Austin Ziegler and contributors. -- Adapted from Algorithm::Diff (Perl) by Ned Konz and a Smalltalk version by - Mario I. Wolczko. - -## MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -## Perl Artistic License - -See the file docs/artistic.txt in the main distribution. - -## GNU GPL version 2 - -See the file docs/COPYING.txt in the main distribution. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt deleted file mode 100644 index fe58c86..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt +++ /dev/null @@ -1,115 +0,0 @@ -.rspec -CHANGELOG.md -CODE_OF_CONDUCT.md -CONTRIBUTING.md -CONTRIBUTORS.md -LICENCE.md -Manifest.txt -README.md -Rakefile -SECURITY.md -bin/htmldiff -bin/ldiff -docs/COPYING.txt -docs/artistic.txt -lib/diff-lcs.rb -lib/diff/lcs.rb -lib/diff/lcs/array.rb -lib/diff/lcs/backports.rb -lib/diff/lcs/block.rb -lib/diff/lcs/callbacks.rb -lib/diff/lcs/change.rb -lib/diff/lcs/htmldiff.rb -lib/diff/lcs/hunk.rb -lib/diff/lcs/internals.rb -lib/diff/lcs/ldiff.rb -lib/diff/lcs/string.rb -lib/diff/lcs/version.rb -mise.toml -spec/change_spec.rb -spec/diff_spec.rb -spec/fixtures/123_x -spec/fixtures/456_x -spec/fixtures/aX -spec/fixtures/bXaX -spec/fixtures/ds1.csv -spec/fixtures/ds2.csv -spec/fixtures/empty -spec/fixtures/file1.bin -spec/fixtures/file2.bin -spec/fixtures/four_lines -spec/fixtures/four_lines_with_missing_new_line -spec/fixtures/ldiff/diff.missing_new_line1-e -spec/fixtures/ldiff/diff.missing_new_line1-f -spec/fixtures/ldiff/diff.missing_new_line2-e -spec/fixtures/ldiff/diff.missing_new_line2-f -spec/fixtures/ldiff/error.diff.chef-e -spec/fixtures/ldiff/error.diff.chef-f -spec/fixtures/ldiff/error.diff.missing_new_line1-e -spec/fixtures/ldiff/error.diff.missing_new_line1-f -spec/fixtures/ldiff/error.diff.missing_new_line2-e -spec/fixtures/ldiff/error.diff.missing_new_line2-f -spec/fixtures/ldiff/output.diff -spec/fixtures/ldiff/output.diff-c -spec/fixtures/ldiff/output.diff-e -spec/fixtures/ldiff/output.diff-f -spec/fixtures/ldiff/output.diff-u -spec/fixtures/ldiff/output.diff.bin1 -spec/fixtures/ldiff/output.diff.bin1-c -spec/fixtures/ldiff/output.diff.bin1-e -spec/fixtures/ldiff/output.diff.bin1-f -spec/fixtures/ldiff/output.diff.bin1-u -spec/fixtures/ldiff/output.diff.bin2 -spec/fixtures/ldiff/output.diff.bin2-c -spec/fixtures/ldiff/output.diff.bin2-e -spec/fixtures/ldiff/output.diff.bin2-f -spec/fixtures/ldiff/output.diff.bin2-u -spec/fixtures/ldiff/output.diff.chef -spec/fixtures/ldiff/output.diff.chef-c -spec/fixtures/ldiff/output.diff.chef-e -spec/fixtures/ldiff/output.diff.chef-f -spec/fixtures/ldiff/output.diff.chef-u -spec/fixtures/ldiff/output.diff.chef2 -spec/fixtures/ldiff/output.diff.chef2-c -spec/fixtures/ldiff/output.diff.chef2-d -spec/fixtures/ldiff/output.diff.chef2-e -spec/fixtures/ldiff/output.diff.chef2-f -spec/fixtures/ldiff/output.diff.chef2-u -spec/fixtures/ldiff/output.diff.empty.vs.four_lines -spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c -spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e -spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f -spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u -spec/fixtures/ldiff/output.diff.four_lines.vs.empty -spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c -spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e -spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f -spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u -spec/fixtures/ldiff/output.diff.issue95_trailing_context -spec/fixtures/ldiff/output.diff.issue95_trailing_context-c -spec/fixtures/ldiff/output.diff.issue95_trailing_context-e -spec/fixtures/ldiff/output.diff.issue95_trailing_context-f -spec/fixtures/ldiff/output.diff.issue95_trailing_context-u -spec/fixtures/ldiff/output.diff.missing_new_line1 -spec/fixtures/ldiff/output.diff.missing_new_line1-c -spec/fixtures/ldiff/output.diff.missing_new_line1-e -spec/fixtures/ldiff/output.diff.missing_new_line1-f -spec/fixtures/ldiff/output.diff.missing_new_line1-u -spec/fixtures/ldiff/output.diff.missing_new_line2 -spec/fixtures/ldiff/output.diff.missing_new_line2-c -spec/fixtures/ldiff/output.diff.missing_new_line2-e -spec/fixtures/ldiff/output.diff.missing_new_line2-f -spec/fixtures/ldiff/output.diff.missing_new_line2-u -spec/fixtures/new-chef -spec/fixtures/new-chef2 -spec/fixtures/old-chef -spec/fixtures/old-chef2 -spec/hunk_spec.rb -spec/issues_spec.rb -spec/lcs_spec.rb -spec/ldiff_spec.rb -spec/patch_spec.rb -spec/sdiff_spec.rb -spec/spec_helper.rb -spec/traverse_balanced_spec.rb -spec/traverse_sequences_spec.rb diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md deleted file mode 100644 index 6583803..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# Diff::LCS - -- home :: https://github.com/halostatue/diff-lcs -- changelog :: https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md -- code :: https://github.com/halostatue/diff-lcs -- bugs :: https://github.com/halostatue/diff-lcs/issues -- rdoc :: http://rubydoc.info/github/halostatue/diff-lcs - - - - - -## Description - -Diff::LCS computes the difference between two Enumerable sequences using the -McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities -to create a simple HTML diff output format and a standard diff-like tool. - -This is release 1.6.1, providing a simple extension that allows for -Diff::LCS::Change objects to be treated implicitly as arrays and fixes a number -of formatting issues. - -Ruby versions below 2.5 are soft-deprecated, which means that older versions are -no longer part of the CI test suite. If any changes have been introduced that -break those versions, bug reports and patches will be accepted, but it will be -up to the reporter to verify any fixes prior to release. The next major release -will completely break compatibility. - -## Synopsis - -Using this module is quite simple. By default, Diff::LCS does not extend objects -with the Diff::LCS interface, but will be called as if it were a function: - -```ruby -require 'diff/lcs' - -seq1 = %w(a b c e h j l m n p) -seq2 = %w(b c d e f j k l m r s t) - -lcs = Diff::LCS.LCS(seq1, seq2) -diffs = Diff::LCS.diff(seq1, seq2) -sdiff = Diff::LCS.sdiff(seq1, seq2) -seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj) -bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj) -seq2 == Diff::LCS.patch!(seq1, diffs) -seq1 == Diff::LCS.unpatch!(seq2, diffs) -seq2 == Diff::LCS.patch!(seq1, sdiff) -seq1 == Diff::LCS.unpatch!(seq2, sdiff) -``` - -Objects can be extended with Diff::LCS: - -```ruby -seq1.extend(Diff::LCS) -lcs = seq1.lcs(seq2) -diffs = seq1.diff(seq2) -sdiff = seq1.sdiff(seq2) -seq = seq1.traverse_sequences(seq2, callback_obj) -bal = seq1.traverse_balanced(seq2, callback_obj) -seq2 == seq1.patch!(diffs) -seq1 == seq2.unpatch!(diffs) -seq2 == seq1.patch!(sdiff) -seq1 == seq2.unpatch!(sdiff) -``` - -By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will be -extended for use this way. - -Note that Diff::LCS requires a sequenced enumerable container, which means that -the order of enumeration is both predictable and consistent for the same set of -data. While it is theoretically possible to generate a diff for an unordered -hash, it will only be meaningful if the enumeration of the hashes is consistent. -In general, this will mean that containers that behave like String or Array will -perform best. - -## History - -Diff::LCS is a port of Perl's Algorithm::Diff that uses the McIlroy-Hunt longest -common subsequence (LCS) algorithm to compute intelligent differences between -two sequenced enumerable containers. The implementation is based on Mario I. -Wolczko's [Smalltalk version 1.2][smalltalk] (1993) and Ned Konz's Perl version -[Algorithm::Diff 1.15][perl]. `Diff::LCS#sdiff` and -`Diff::LCS#traverse_balanced` were originally written for the Perl version by -Mike Schilli. - -The algorithm is described in A Fast Algorithm for Computing Longest Common -Subsequences, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor -improvements to improve the speed. A simplified description of the algorithm, -originally written for the Perl version, was written by Mark-Jason Dominus. - -[smalltalk]: ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st -[perl]: http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile deleted file mode 100644 index 0bfe927..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile +++ /dev/null @@ -1,115 +0,0 @@ -require "rubygems" -require "rspec" -require "rspec/core/rake_task" -require "hoe" -require "rake/clean" - -MAINTENANCE = ENV["MAINTENANCE"] == "true" -BUILD_DOCS = MAINTENANCE || ENV["DOCS"] == "true" -TRUSTED_RELEASE = ENV["rubygems_release_gem"] == "true" - -Hoe.plugin :halostatue -Hoe.plugin :rubygems - -Hoe.plugins.delete :debug -Hoe.plugins.delete :newb -Hoe.plugins.delete :signing -Hoe.plugins.delete :publish unless BUILD_DOCS - -if RUBY_VERSION < "1.9" - class Array # :nodoc: - def to_h - Hash[*flatten(1)] - end - end - - class Gem::Specification # :nodoc: - def metadata=(*) - end - - def default_value(*) - end - end - - class Object # :nodoc: - def caller_locations(*) - [] - end - end -end - -_spec = Hoe.spec "diff-lcs" do - developer("Austin Ziegler", "halostatue@gmail.com") - - self.trusted_release = TRUSTED_RELEASE - - require_ruby_version ">= 1.8" - - self.history_file = "CHANGELOG.md" - self.readme_file = "README.md" - self.licenses = ["MIT", "Artistic-1.0-Perl", "GPL-2.0-or-later"] - - spec_extras[:metadata] = ->(val) { - val["rubygems_mfa_required"] = "true" - } - - extra_dev_deps << ["hoe", "~> 4.0"] - extra_dev_deps << ["hoe-halostatue", "~> 2.0"] - extra_dev_deps << ["hoe-rubygems", "~> 1.0"] - extra_dev_deps << ["rspec", ">= 2.0", "< 4"] - extra_dev_deps << ["rake", ">= 10.0", "< 14"] - extra_dev_deps << ["rdoc", ">= 6.3.1", "< 7"] -end - -if BUILD_DOCS - rake_tasks = Rake.application.instance_variable_get(:@tasks) - tasks = ["publish_docs", "publish_on_announce", "debug_email", "post_blog", "announce"] - tasks.each do |task| - rake_tasks.delete(task) - end -end - -desc "Run all specifications" -RSpec::Core::RakeTask.new(:spec) do |t| - rspec_dirs = %w[spec lib].join(":") - t.rspec_opts = ["-I#{rspec_dirs}"] -end - -task :version do - require "diff/lcs/version" - puts Diff::LCS::VERSION -end - -Rake::Task["spec"].actions.uniq! { |a| a.source_location } - -# standard:disable Style/HashSyntax -task :default => :spec unless Rake::Task["default"].prereqs.include?("spec") -task :test => :spec unless Rake::Task["test"].prereqs.include?("spec") -# standard:enable Style/HashSyntax - -if RUBY_VERSION >= "3.0" && RUBY_ENGINE == "ruby" - namespace :spec do - desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed." - task :coverage do - ENV["COVERAGE"] = "true" - Rake::Task["spec"].execute - end - end -end - -if MAINTENANCE - task ruby18: :package do - require "diff/lcs/version" - # standard:disable Layout/HeredocIndentation - puts <<-MESSAGE -You are starting a barebones Ruby 1.8 docker environment for testing. -A snapshot package has been built, so install it with: - - cd diff-lcs - gem install pkg/diff-lcs-#{Diff::LCS::VERSION} - - MESSAGE - # standard:enable Layout/HeredocIndentation - sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l" - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md deleted file mode 100644 index 16854f6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md +++ /dev/null @@ -1,41 +0,0 @@ -# diff-lcs Security - -## Supported Versions - -Security reports are accepted for the most recent major release and the previous -version for a limited time after the initial major release version. After a -major release, the previous version will receive full support for six months and -security support for an additional six months (for a total of twelve months). - -Because diff-lcs 1.x supports a wide range of Ruby versions, security reports -will only be accepted when they can be demonstrated on Ruby 3.1 or higher. - -> [!information] -> -> There will be a diff-lcs 2.0 released in 2025 which narrows support to modern -> versions of Ruby only. -> -> | Release Date | Support Ends | Security Support Ends | -> | ------------ | ------------ | --------------------- | -> | 2025 | +6 months | +12 months | -> -> If the 2.0.0 release happens on 2025-07-01, regular support for diff-lcs 1.x -> will end on 2026-12-31 and security support for diff-lcs 1.x will end on -> 2026-06-30. - -## Reporting a Vulnerability - -By preference, use the [Tidelift security contact][tidelift]. Tidelift will -coordinate the fix and disclosure. - -Alternatively, Send an email to [diff-lcs@halostatue.ca][email] with the text -`Diff::LCS` in the subject. Emails sent to this address should be encrypted -using [age][age] with the following public key: - -``` -age1fc6ngxmn02m62fej5cl30lrvwmxn4k3q2atqu53aatekmnqfwumqj4g93w -``` - -[tidelift]: https://tidelift.com/security -[email]: mailto:diff-lcs@halostatue.ca -[age]: https://github.com/FiloSottile/age diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff deleted file mode 100755 index bcd89d2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env ruby -w -# frozen_string_literal: true - -require "diff/lcs" -require "diff/lcs/htmldiff" - -begin - require "text/format" -rescue LoadError - Diff::LCS::HTMLDiff.can_expand_tabs = false -end - -if ARGV.size < 2 or ARGV.size > 3 - warn "usage: #{File.basename($0)} old new [output.html]" - warn " #{File.basename($0)} old new > output.html" - exit 127 -end - -left = IO.read(ARGV[0]).split($/) -right = IO.read(ARGV[1]).split($/) - -options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" } - -htmldiff = Diff::LCS::HTMLDiff.new(left, right, options) - -if ARGV[2] - File.open(ARGV[2], "w") do |f| - htmldiff.options[:output] = f - htmldiff.run - end -else - htmldiff.run -end - -# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff deleted file mode 100755 index f4734f5..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff +++ /dev/null @@ -1,9 +0,0 @@ -#! /usr/bin/env ruby -w -# frozen_string_literal: true - -require 'diff/lcs' -require 'diff/lcs/ldiff' - -exit Diff::LCS::Ldiff.run(ARGV) - -# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt deleted file mode 100644 index d159169..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt deleted file mode 100644 index 763e17a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt +++ /dev/null @@ -1,127 +0,0 @@ -The "Artistic License" - - Preamble - -The intent of this document is to state the conditions under which a -Package may be copied, such that the Copyright Holder maintains some -semblance of artistic control over the development of the package, -while giving the users of the package the right to use and distribute -the Package in a more-or-less customary fashion, plus the right to make -reasonable modifications. - -Definitions: - - "Package" refers to the collection of files distributed by the - Copyright Holder, and derivatives of that collection of files - created through textual modification. - - "Standard Version" refers to such a Package if it has not been - modified, or has been modified in accordance with the wishes - of the Copyright Holder as specified below. - - "Copyright Holder" is whoever is named in the copyright or - copyrights for the package. - - "You" is you, if you're thinking about copying or distributing - this Package. - - "Reasonable copying fee" is whatever you can justify on the - basis of media cost, duplication charges, time of people involved, - and so on. (You will not be required to justify it to the - Copyright Holder, but only to the computing community at large - as a market that must bear the fee.) - - "Freely Available" means that no fee is charged for the item - itself, though there may be fees involved in handling the item. - It also means that recipients of the item may redistribute it - under the same conditions they received it. - -1. You may make and give away verbatim copies of the source form of the -Standard Version of this Package without restriction, provided that you -duplicate all of the original copyright notices and associated disclaimers. - -2. You may apply bug fixes, portability fixes and other modifications -derived from the Public Domain or from the Copyright Holder. A Package -modified in such a way shall still be considered the Standard Version. - -3. You may otherwise modify your copy of this Package in any way, provided -that you insert a prominent notice in each changed file stating how and -when you changed that file, and provided that you do at least ONE of the -following: - - a) place your modifications in the Public Domain or otherwise make them - Freely Available, such as by posting said modifications to Usenet or - an equivalent medium, or placing the modifications on a major archive - site such as uunet.uu.net, or by allowing the Copyright Holder to include - your modifications in the Standard Version of the Package. - - b) use the modified Package only within your corporation or organization. - - c) rename any non-standard executables so the names do not conflict - with standard executables, which must also be provided, and provide - a separate manual page for each non-standard executable that clearly - documents how it differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -4. You may distribute the programs of this Package in object code or -executable form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library files, - together with instructions (in the manual page or equivalent) on where - to get the Standard Version. - - b) accompany the distribution with the machine-readable source of - the Package with your modifications. - - c) give non-standard executables non-standard names, and clearly - document the differences in manual pages (or equivalent), together - with instructions on where to get the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -5. You may charge a reasonable copying fee for any distribution of this -Package. You may charge any fee you choose for support of this -Package. You may not charge a fee for this Package itself. However, -you may distribute this Package in aggregate with other (possibly -commercial) programs as part of a larger (possibly commercial) software -distribution provided that you do not advertise this Package as a -product of your own. You may embed this Package's interpreter within -an executable of yours (by linking); this shall be construed as a mere -form of aggregation, provided that the complete Standard Version of the -interpreter is so embedded. - -6. The scripts and library files supplied as input to or produced as -output from the programs of this Package do not automatically fall -under the copyright of this Package, but belong to whoever generated -them, and may be sold commercially, and may be aggregated with this -Package. If such scripts or library files are aggregated with this -Package via the so-called "undump" or "unexec" methods of producing a -binary executable image, then distribution of such an image shall -neither be construed as a distribution of this Package nor shall it -fall under the restrictions of Paragraphs 3 and 4, provided that you do -not represent such an executable image as a Standard Version of this -Package. - -7. C subroutines (or comparably compiled subroutines in other -languages) supplied by you and linked into this Package in order to -emulate subroutines and variables of the language defined by this -Package shall not be considered part of this Package, but are the -equivalent of input as in Paragraph 6, provided these subroutines do -not change the language in any way that would cause it to fail the -regression tests for the language. - -8. Aggregation of this Package with a commercial distribution is always -permitted provided that the use of this Package is embedded; that is, -when no overt attempt is made to make this Package's interfaces visible -to the end user of the commercial distribution. Such use shall not be -construed as a distribution of this Package. - -9. The name of the Copyright Holder may not be used to endorse or promote -products derived from this software without specific prior written permission. - -10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - The End diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb deleted file mode 100644 index bc07bf9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb +++ /dev/null @@ -1,3 +0,0 @@ -# frozen_string_literal: true - -require "diff/lcs" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb deleted file mode 100644 index 5ee8937..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb +++ /dev/null @@ -1,742 +0,0 @@ -# frozen_string_literal: true - -module Diff; end unless defined? Diff - -# == How Diff Works (by Mark-Jason Dominus) -# -# I once read an article written by the authors of +diff+; they said that they -# hard worked very hard on the algorithm until they found the right one. -# -# I think what they ended up using (and I hope someone will correct me, because -# I am not very confident about this) was the `longest common subsequence' -# method. In the LCS problem, you have two sequences of items: -# -# a b c d f g h j q z -# a b c d e f g i j k r x y z -# -# and you want to find the longest sequence of items that is present in both -# original sequences in the same order. That is, you want to find a new -# sequence *S* which can be obtained from the first sequence by deleting some -# items, and from the second sequence by deleting other items. You also want -# *S* to be as long as possible. In this case *S* is: -# -# a b c d f g j z -# -# From there it's only a small step to get diff-like output: -# -# e h i k q r x y -# + - + + - + + + -# -# This module solves the LCS problem. It also includes a canned function to -# generate +diff+-like output. -# -# It might seem from the example above that the LCS of two sequences is always -# pretty obvious, but that's not always the case, especially when the two -# sequences have many repeated elements. For example, consider -# -# a x b y c z p d q -# a b c a x b y c z -# -# A naive approach might start by matching up the +a+ and +b+ that appear at -# the beginning of each sequence, like this: -# -# a x b y c z p d q -# a b c a b y c z -# -# This finds the common subsequence +a b c z+. But actually, the LCS is +a x b -# y c z+: -# -# a x b y c z p d q -# a b c a x b y c z -module Diff::LCS -end - -require "diff/lcs/version" -require "diff/lcs/callbacks" -require "diff/lcs/internals" - -module Diff::LCS - # Returns an Array containing the longest common subsequence(s) between - # +self+ and +other+. See Diff::LCS#lcs. - # - # lcs = seq1.lcs(seq2) - # - # A note when using objects: Diff::LCS only works properly when each object - # can be used as a key in a Hash. This means that those objects must implement - # the methods +#hash+ and +#eql?+ such that two objects containing identical values - # compare identically for key purposes. That is: - # - # O.new('a').eql?(O.new('a')) == true && - # O.new('a').hash == O.new('a').hash - def lcs(other, &block) # :yields: self[i] if there are matched subsequences - Diff::LCS.lcs(self, other, &block) - end - - # Returns the difference set between +self+ and +other+. See Diff::LCS#diff. - def diff(other, callbacks = nil, &block) - Diff::LCS.diff(self, other, callbacks, &block) - end - - # Returns the balanced ("side-by-side") difference set between +self+ and - # +other+. See Diff::LCS#sdiff. - def sdiff(other, callbacks = nil, &block) - Diff::LCS.sdiff(self, other, callbacks, &block) - end - - # Traverses the discovered longest common subsequences between +self+ and - # +other+. See Diff::LCS#traverse_sequences. - def traverse_sequences(other, callbacks = nil, &block) - Diff::LCS.traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block) - end - - # Traverses the discovered longest common subsequences between +self+ and - # +other+ using the alternate, balanced algorithm. See - # Diff::LCS#traverse_balanced. - def traverse_balanced(other, callbacks = nil, &block) - Diff::LCS.traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block) - end - - # Attempts to patch +self+ with the provided +patchset+. A new sequence based - # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Attempts - # to autodiscover the direction of the patch. - def patch(patchset) - Diff::LCS.patch(self, patchset) - end - alias_method :unpatch, :patch - - # Attempts to patch +self+ with the provided +patchset+. A new sequence based - # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Does no - # patch direction autodiscovery. - def patch!(patchset) - Diff::LCS.patch!(self, patchset) - end - - # Attempts to unpatch +self+ with the provided +patchset+. A new sequence - # based on +self+ and the +patchset+ will be created. See Diff::LCS#unpatch. - # Does no patch direction autodiscovery. - def unpatch!(patchset) - Diff::LCS.unpatch!(self, patchset) - end - - # Attempts to patch +self+ with the provided +patchset+, using #patch!. If - # the sequence this is used on supports #replace, the value of +self+ will be - # replaced. See Diff::LCS#patch. Does no patch direction autodiscovery. - def patch_me(patchset) - if respond_to? :replace - replace(patch!(patchset)) - else - patch!(patchset) - end - end - - # Attempts to unpatch +self+ with the provided +patchset+, using #unpatch!. - # If the sequence this is used on supports #replace, the value of +self+ will - # be replaced. See Diff::LCS#unpatch. Does no patch direction autodiscovery. - def unpatch_me(patchset) - if respond_to? :replace - replace(unpatch!(patchset)) - else - unpatch!(patchset) - end - end -end - -class << Diff::LCS - def lcs(seq1, seq2, &block) # :yields: seq1[i] for each matched - matches = Diff::LCS::Internals.lcs(seq1, seq2) - ret = [] - string = seq1.is_a? String - matches.each_index do |i| - next if matches[i].nil? - - v = string ? seq1[i, 1] : seq1[i] - v = block[v] if block - ret << v - end - ret - end - alias_method :LCS, :lcs - - # #diff computes the smallest set of additions and deletions necessary to - # turn the first sequence into the second, and returns a description of these - # changes. - # - # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate - # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a - # Class argument is provided for +callbacks+, #diff will attempt to - # initialise it. If the +callbacks+ object (possibly initialised) responds to - # #finish, it will be called. - def diff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes - diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks, &block) - end - - # #sdiff computes all necessary components to show two sequences and their - # minimized differences side by side, just like the Unix utility - # sdiff does: - # - # old < - - # same same - # before | after - # - > new - # - # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate - # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a - # Class argument is provided for +callbacks+, #diff will attempt to - # initialise it. If the +callbacks+ object (possibly initialised) responds to - # #finish, it will be called. - # - # Each element of a returned array is a Diff::LCS::ContextChange object, - # which can be implicitly converted to an array. - # - # Diff::LCS.sdiff(a, b).each do |action, (old_pos, old_element), (new_pos, new_element)| - # case action - # when '!' - # # replace - # when '-' - # # delete - # when '+' - # # insert - # end - # end - def sdiff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes - diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block) - end - - # #traverse_sequences is the most general facility provided by this module; - # #diff and #lcs are implemented as calls to it. - # - # The arguments to #traverse_sequences are the two sequences to traverse, and - # a callback object, like this: - # - # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) - # - # == Callback Methods - # - # Optional callback methods are emphasized. - # - # callbacks#match:: Called when +a+ and +b+ are pointing to - # common elements in +A+ and +B+. - # callbacks#discard_a:: Called when +a+ is pointing to an - # element not in +B+. - # callbacks#discard_b:: Called when +b+ is pointing to an - # element not in +A+. - # callbacks#finished_a:: Called when +a+ has reached the end of - # sequence +A+. - # callbacks#finished_b:: Called when +b+ has reached the end of - # sequence +B+. - # - # == Algorithm - # - # a---+ - # v - # A = a b c e h j l m n p - # B = b c d e f j k l m r s t - # ^ - # b---+ - # - # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ - # and +B+, the arrows will initially point to the first elements of their - # respective sequences. #traverse_sequences will advance the arrows through - # the sequences one element at a time, calling a method on the user-specified - # callback object before each advance. It will advance the arrows in such a - # way that if there are elements A[i] and B[j] which are - # both equal and part of the longest common subsequence, there will be some - # moment during the execution of #traverse_sequences when arrow +a+ is - # pointing to A[i] and arrow +b+ is pointing to B[j]. When - # this happens, #traverse_sequences will call callbacks#match and - # then it will advance both arrows. - # - # Otherwise, one of the arrows is pointing to an element of its sequence that - # is not part of the longest common subsequence. #traverse_sequences will - # advance that arrow and will call callbacks#discard_a or - # callbacks#discard_b, depending on which arrow it advanced. If both - # arrows point to elements that are not part of the longest common - # subsequence, then #traverse_sequences will advance arrow +a+ and call the - # appropriate callback, then it will advance arrow +b+ and call the appropriate - # callback. - # - # The methods for callbacks#match, callbacks#discard_a, and - # callbacks#discard_b are invoked with an event comprising the - # action ("=", "+", or "-", respectively), the indexes +i+ and +j+, and the - # elements A[i] and B[j]. Return values are discarded by - # #traverse_sequences. - # - # === End of Sequences - # - # If arrow +a+ reaches the end of its sequence before arrow +b+ does, - # #traverse_sequence will try to call callbacks#finished_a with the - # last index and element of +A+ (A[-1]) and the current index and - # element of +B+ (B[j]). If callbacks#finished_a does not - # exist, then callbacks#discard_b will be called on each element of - # +B+ until the end of the sequence is reached (the call will be done with - # A[-1] and B[j] for each element). - # - # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+, - # callbacks#finished_b will be called with the current index and - # element of +A+ (A[i]) and the last index and element of +B+ - # (A[-1]). Again, if callbacks#finished_b does not exist on - # the callback object, then callbacks#discard_a will be called on - # each element of +A+ until the end of the sequence is reached (A[i] - # and B[-1]). - # - # There is a chance that one additional callbacks#discard_a or - # callbacks#discard_b will be called after the end of the sequence - # is reached, if +a+ has not yet reached the end of +A+ or +b+ has not yet - # reached the end of +B+. - def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks) # :yields: change events - callbacks ||= Diff::LCS::SequenceCallbacks - matches = Diff::LCS::Internals.lcs(seq1, seq2) - - run_finished_a = run_finished_b = false - string = seq1.is_a?(String) - - a_size = seq1.size - b_size = seq2.size - ai = bj = 0 - - matches.each do |b_line| - if b_line.nil? - unless seq1[ai].nil? - ax = string ? seq1[ai, 1] : seq1[ai] - bx = string ? seq2[bj, 1] : seq2[bj] - - event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_a(event) - end - else - ax = string ? seq1[ai, 1] : seq1[ai] - - loop do - break unless bj < b_line - - bx = string ? seq2[bj, 1] : seq2[bj] - event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_b(event) - bj += 1 - end - bx = string ? seq2[bj, 1] : seq2[bj] - event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.match(event) - bj += 1 - end - ai += 1 - end - - # The last entry (if any) processed was a match. +ai+ and +bj+ point just - # past the last matching lines in their sequences. - while (ai < a_size) || (bj < b_size) - # last A? - if ai == a_size && bj < b_size - if callbacks.respond_to?(:finished_a) && !run_finished_a - ax = string ? seq1[-1, 1] : seq1[-1] - bx = string ? seq2[bj, 1] : seq2[bj] - event = Diff::LCS::ContextChange.new(">", a_size - 1, ax, bj, bx) - event = yield event if block_given? - callbacks.finished_a(event) - run_finished_a = true - else - ax = string ? seq1[ai, 1] : seq1[ai] - loop do - bx = string ? seq2[bj, 1] : seq2[bj] - event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_b(event) - bj += 1 - break unless bj < b_size - end - end - end - - # last B? - if bj == b_size && ai < a_size - if callbacks.respond_to?(:finished_b) && !run_finished_b - ax = string ? seq1[ai, 1] : seq1[ai] - bx = string ? seq2[-1, 1] : seq2[-1] - event = Diff::LCS::ContextChange.new("<", ai, ax, b_size - 1, bx) - event = yield event if block_given? - callbacks.finished_b(event) - run_finished_b = true - else - bx = string ? seq2[bj, 1] : seq2[bj] - loop do - ax = string ? seq1[ai, 1] : seq1[ai] - event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_a(event) - ai += 1 - break unless bj < b_size - end - end - end - - if ai < a_size - ax = string ? seq1[ai, 1] : seq1[ai] - bx = string ? seq2[bj, 1] : seq2[bj] - event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_a(event) - ai += 1 - end - - if bj < b_size - ax = string ? seq1[ai, 1] : seq1[ai] - bx = string ? seq2[bj, 1] : seq2[bj] - event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_b(event) - bj += 1 - end - end - end - - # #traverse_balanced is an alternative to #traverse_sequences. It uses a - # different algorithm to iterate through the entries in the computed longest - # common subsequence. Instead of viewing the changes as insertions or - # deletions from one of the sequences, #traverse_balanced will report - # changes between the sequences. - # - # The arguments to #traverse_balanced are the two sequences to traverse and a - # callback object, like this: - # - # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) - # - # #sdiff is implemented with #traverse_balanced. - # - # == Callback Methods - # - # Optional callback methods are emphasized. - # - # callbacks#match:: Called when +a+ and +b+ are pointing to - # common elements in +A+ and +B+. - # callbacks#discard_a:: Called when +a+ is pointing to an - # element not in +B+. - # callbacks#discard_b:: Called when +b+ is pointing to an - # element not in +A+. - # callbacks#change:: Called when +a+ and +b+ are pointing to - # the same relative position, but - # A[a] and B[b] are not - # the same; a change has - # occurred. - # - # #traverse_balanced might be a bit slower than #traverse_sequences, - # noticeable only while processing huge amounts of data. - # - # == Algorithm - # - # a---+ - # v - # A = a b c e h j l m n p - # B = b c d e f j k l m r s t - # ^ - # b---+ - # - # === Matches - # - # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ - # and +B+, the arrows will initially point to the first elements of their - # respective sequences. #traverse_sequences will advance the arrows through - # the sequences one element at a time, calling a method on the user-specified - # callback object before each advance. It will advance the arrows in such a - # way that if there are elements A[i] and B[j] which are - # both equal and part of the longest common subsequence, there will be some - # moment during the execution of #traverse_sequences when arrow +a+ is - # pointing to A[i] and arrow +b+ is pointing to B[j]. When - # this happens, #traverse_sequences will call callbacks#match and - # then it will advance both arrows. - # - # === Discards - # - # Otherwise, one of the arrows is pointing to an element of its sequence that - # is not part of the longest common subsequence. #traverse_sequences will - # advance that arrow and will call callbacks#discard_a or - # callbacks#discard_b, depending on which arrow it advanced. - # - # === Changes - # - # If both +a+ and +b+ point to elements that are not part of the longest - # common subsequence, then #traverse_sequences will try to call - # callbacks#change and advance both arrows. If - # callbacks#change is not implemented, then - # callbacks#discard_a and callbacks#discard_b will be - # called in turn. - # - # The methods for callbacks#match, callbacks#discard_a, - # callbacks#discard_b, and callbacks#change are invoked - # with an event comprising the action ("=", "+", "-", or "!", respectively), - # the indexes +i+ and +j+, and the elements A[i] and B[j]. - # Return values are discarded by #traverse_balanced. - # - # === Context - # - # Note that +i+ and +j+ may not be the same index position, even if +a+ and - # +b+ are considered to be pointing to matching or changed elements. - def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks) - matches = Diff::LCS::Internals.lcs(seq1, seq2) - a_size = seq1.size - b_size = seq2.size - ai = bj = mb = 0 - ma = -1 - string = seq1.is_a?(String) - - # Process all the lines in the match vector. - loop do - # Find next match indexes +ma+ and +mb+ - loop do - ma += 1 - break unless ma < matches.size && matches[ma].nil? - end - - break if ma >= matches.size # end of matches? - - mb = matches[ma] - - # Change(seq2) - while (ai < ma) || (bj < mb) - ax = string ? seq1[ai, 1] : seq1[ai] - bx = string ? seq2[bj, 1] : seq2[bj] - - case [(ai < ma), (bj < mb)] - when [true, true] - if callbacks.respond_to?(:change) - event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.change(event) - ai += 1 - else - event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_a(event) - ai += 1 - ax = string ? seq1[ai, 1] : seq1[ai] - event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_b(event) - end - - bj += 1 - when [true, false] - event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_a(event) - ai += 1 - when [false, true] - event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_b(event) - bj += 1 - end - end - - # Match - ax = string ? seq1[ai, 1] : seq1[ai] - bx = string ? seq2[bj, 1] : seq2[bj] - event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.match(event) - ai += 1 - bj += 1 - end - - while (ai < a_size) || (bj < b_size) - ax = string ? seq1[ai, 1] : seq1[ai] - bx = string ? seq2[bj, 1] : seq2[bj] - - case [(ai < a_size), (bj < b_size)] - when [true, true] - if callbacks.respond_to?(:change) - event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.change(event) - ai += 1 - else - event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_a(event) - ai += 1 - ax = string ? seq1[ai, 1] : seq1[ai] - event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_b(event) - end - - bj += 1 - when [true, false] - event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_a(event) - ai += 1 - when [false, true] - event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) - event = yield event if block_given? - callbacks.discard_b(event) - bj += 1 - end - end - end - - # standard:disable Style/HashSyntax - PATCH_MAP = { # :nodoc: - :patch => {"+" => "+", "-" => "-", "!" => "!", "=" => "="}.freeze, - :unpatch => {"+" => "-", "-" => "+", "!" => "!", "=" => "="}.freeze - }.freeze - # standard:enable Style/HashSyntax - - # Applies a +patchset+ to the sequence +src+ according to the +direction+ - # (:patch or :unpatch), producing a new sequence. - # - # If the +direction+ is not specified, Diff::LCS::patch will attempt to - # discover the direction of the +patchset+. - # - # A +patchset+ can be considered to apply forward (:patch) if the - # following expression is true: - # - # patch(s1, diff(s1, s2)) -> s2 - # - # A +patchset+ can be considered to apply backward (:unpatch) if the - # following expression is true: - # - # patch(s2, diff(s1, s2)) -> s1 - # - # If the +patchset+ contains no changes, the +src+ value will be returned as - # either src.dup or +src+. A +patchset+ can be deemed as having no - # changes if the following predicate returns true: - # - # patchset.empty? or - # patchset.flatten(1).all? { |change| change.unchanged? } - # - # === Patchsets - # - # A +patchset+ is always an enumerable sequence of changes, hunks of changes, - # or a mix of the two. A hunk of changes is an enumerable sequence of - # changes: - # - # [ # patchset - # # change - # [ # hunk - # # change - # ] - # ] - # - # The +patch+ method accepts patchsets that are enumerable sequences - # containing either Diff::LCS::Change objects (or a subclass) or the array - # representations of those objects. Prior to application, array - # representations of Diff::LCS::Change objects will be reified. - def patch(src, patchset, direction = nil) - # Normalize the patchset. - has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset) - - return src.respond_to?(:dup) ? src.dup : src unless has_changes - - string = src.is_a?(String) - # Start with a new empty type of the source's class - res = src.class.new - - direction ||= Diff::LCS::Internals.intuit_diff_direction(src, patchset) - - ai = bj = 0 - - patch_map = PATCH_MAP[direction] - - patchset.each do |change| - # Both Change and ContextChange support #action - action = patch_map[change.action] - - case change - when Diff::LCS::ContextChange - case direction - when :patch - el = change.new_element - op = change.old_position - np = change.new_position - when :unpatch - el = change.old_element - op = change.new_position - np = change.old_position - end - - case action - when "-" # Remove details from the old string - while ai < op - res << (string ? src[ai, 1] : src[ai]) - ai += 1 - bj += 1 - end - ai += 1 - when "+" - while bj < np - res << (string ? src[ai, 1] : src[ai]) - ai += 1 - bj += 1 - end - - res << el - bj += 1 - when "=" - # This only appears in sdiff output with the SDiff callback. - # Therefore, we only need to worry about dealing with a single - # element. - res << el - - ai += 1 - bj += 1 - when "!" - while ai < op - res << (string ? src[ai, 1] : src[ai]) - ai += 1 - bj += 1 - end - - bj += 1 - ai += 1 - - res << el - end - when Diff::LCS::Change - case action - when "-" - while ai < change.position - res << (string ? src[ai, 1] : src[ai]) - ai += 1 - bj += 1 - end - ai += 1 - when "+" - while bj < change.position - res << (string ? src[ai, 1] : src[ai]) - ai += 1 - bj += 1 - end - - bj += 1 - - res << change.element - end - end - end - - while ai < src.size - res << (string ? src[ai, 1] : src[ai]) - ai += 1 - bj += 1 - end - - res - end - - # Given a set of patchset, convert the current version to the prior version. - # Does no auto-discovery. - def unpatch!(src, patchset) - patch(src, patchset, :unpatch) - end - - # Given a set of patchset, convert the current version to the next version. - # Does no auto-discovery. - def patch!(src, patchset) - patch(src, patchset, :patch) - end -end - -require "diff/lcs/backports" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb deleted file mode 100644 index 663918a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -require "diff/lcs" - -class Array - include Diff::LCS -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb deleted file mode 100644 index 6543c8a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -unless 0.respond_to?(:positive?) - class Fixnum # standard:disable Lint/UnifiedInteger - def positive? - self > 0 - end - - def negative? - self < 0 - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb deleted file mode 100644 index 226ed6f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -# A block is an operation removing, adding, or changing a group of items. -# Basically, this is just a list of changes, where each change adds or -# deletes a single item. Used by bin/ldiff. -class Diff::LCS::Block - attr_reader :changes, :insert, :remove - - def initialize(chunk) - @changes = [] - @insert = [] - @remove = [] - - chunk.each do |item| - @changes << item - @remove << item if item.deleting? - @insert << item if item.adding? - end - end - - def diff_size - @insert.size - @remove.size - end - - def op - case [@remove.empty?, @insert.empty?] - when [false, false] - "!" - when [false, true] - "-" - when [true, false] - "+" - else # [true, true] - "^" - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb deleted file mode 100644 index 2c5a779..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb +++ /dev/null @@ -1,327 +0,0 @@ -# frozen_string_literal: true - -require "diff/lcs/change" - -module Diff::LCS - # This callback object implements the default set of callback events, - # which only returns the event itself. Note that #finished_a and - # #finished_b are not implemented -- I haven't yet figured out where they - # would be useful. - # - # Note that this is intended to be called as is, e.g., - # - # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks) - class DefaultCallbacks - class << self - # Called when two items match. - def match(event) - event - end - - # Called when the old value is discarded in favour of the new value. - def discard_a(event) - event - end - - # Called when the new value is discarded in favour of the old value. - def discard_b(event) - event - end - - # Called when both the old and new values have changed. - def change(event) - event - end - - private :new - end - end - - # An alias for DefaultCallbacks that is used in - # Diff::LCS#traverse_sequences. - # - # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks) - SequenceCallbacks = DefaultCallbacks - - # An alias for DefaultCallbacks that is used in - # Diff::LCS#traverse_balanced. - # - # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks) - BalancedCallbacks = DefaultCallbacks - - def self.callbacks_for(callbacks) - callbacks.new - rescue - callbacks - end -end - -# This will produce a compound array of simple diff change objects. Each -# element in the #diffs array is a +hunk+ or +hunk+ array, where each -# element in each +hunk+ array is a single Change object representing the -# addition or removal of a single element from one of the two tested -# sequences. The +hunk+ provides the full context for the changes. -# -# diffs = Diff::LCS.diff(seq1, seq2) -# # This example shows a simplified array format. -# # [ [ [ '-', 0, 'a' ] ], # 1 -# # [ [ '+', 2, 'd' ] ], # 2 -# # [ [ '-', 4, 'h' ], # 3 -# # [ '+', 4, 'f' ] ], -# # [ [ '+', 6, 'k' ] ], # 4 -# # [ [ '-', 8, 'n' ], # 5 -# # [ '-', 9, 'p' ], -# # [ '+', 9, 'r' ], -# # [ '+', 10, 's' ], -# # [ '+', 11, 't' ] ] ] -# -# There are five hunks here. The first hunk says that the +a+ at position 0 -# of the first sequence should be deleted ('-'). The second hunk -# says that the +d+ at position 2 of the second sequence should be inserted -# ('+'). The third hunk says that the +h+ at position 4 of the -# first sequence should be removed and replaced with the +f+ from position 4 -# of the second sequence. The other two hunks are described similarly. -# -# === Use -# -# This callback object must be initialised and is used by the Diff::LCS#diff -# method. -# -# cbo = Diff::LCS::DiffCallbacks.new -# Diff::LCS.LCS(seq1, seq2, cbo) -# cbo.finish -# -# Note that the call to #finish is absolutely necessary, or the last set of -# changes will not be visible. Alternatively, can be used as: -# -# cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } -# -# The necessary #finish call will be made. -# -# === Simplified Array Format -# -# The simplified array format used in the example above can be obtained -# with: -# -# require 'pp' -# pp diffs.map { |e| e.map { |f| f.to_a } } -class Diff::LCS::DiffCallbacks - # Returns the difference set collected during the diff process. - attr_reader :diffs - - def initialize # :yields: self - @hunk = [] - @diffs = [] - - return unless block_given? - - begin - yield self - ensure - finish - end - end - - # Finalizes the diff process. If an unprocessed hunk still exists, then it - # is appended to the diff list. - def finish - finish_hunk - end - - def match(_event) - finish_hunk - end - - def discard_a(event) - @hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element) - end - - def discard_b(event) - @hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element) - end - - def finish_hunk - @diffs << @hunk unless @hunk.empty? - @hunk = [] - end - private :finish_hunk -end - -# This will produce a compound array of contextual diff change objects. Each -# element in the #diffs array is a "hunk" array, where each element in each -# "hunk" array is a single change. Each change is a Diff::LCS::ContextChange -# that contains both the old index and new index values for the change. The -# "hunk" provides the full context for the changes. Both old and new objects -# will be presented for changed objects. +nil+ will be substituted for a -# discarded object. -# -# seq1 = %w(a b c e h j l m n p) -# seq2 = %w(b c d e f j k l m r s t) -# -# diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) -# # This example shows a simplified array format. -# # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1 -# # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2 -# # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3 -# # [ '+', [ 5, nil ], [ 4, 'f' ] ] ], -# # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4 -# # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5 -# # [ '+', [ 9, nil ], [ 9, 'r' ] ], -# # [ '-', [ 9, 'p' ], [ 10, nil ] ], -# # [ '+', [ 10, nil ], [ 10, 's' ] ], -# # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ] -# -# The five hunks shown are comprised of individual changes; if there is a -# related set of changes, they are still shown individually. -# -# This callback can also be used with Diff::LCS#sdiff, which will produce -# results like: -# -# diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks) -# # This example shows a simplified array format. -# # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1 -# # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2 -# # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3 -# # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4 -# # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5 -# # [ "!", [ 9, "p" ], [ 10, "s" ] ], -# # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ] -# -# The five hunks are still present, but are significantly shorter in total -# presentation, because changed items are shown as changes ("!") instead of -# potentially "mismatched" pairs of additions and deletions. -# -# The result of this operation is similar to that of -# Diff::LCS::SDiffCallbacks. They may be compared as: -# -# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } -# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) -# -# s == c # -> true -# -# === Use -# -# This callback object must be initialised and can be used by the -# Diff::LCS#diff or Diff::LCS#sdiff methods. -# -# cbo = Diff::LCS::ContextDiffCallbacks.new -# Diff::LCS.LCS(seq1, seq2, cbo) -# cbo.finish -# -# Note that the call to #finish is absolutely necessary, or the last set of -# changes will not be visible. Alternatively, can be used as: -# -# cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } -# -# The necessary #finish call will be made. -# -# === Simplified Array Format -# -# The simplified array format used in the example above can be obtained -# with: -# -# require 'pp' -# pp diffs.map { |e| e.map { |f| f.to_a } } -class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks - def discard_a(event) - @hunk << Diff::LCS::ContextChange.simplify(event) - end - - def discard_b(event) - @hunk << Diff::LCS::ContextChange.simplify(event) - end - - def change(event) - @hunk << Diff::LCS::ContextChange.simplify(event) - end -end - -# This will produce a simple array of diff change objects. Each element in -# the #diffs array is a single ContextChange. In the set of #diffs provided -# by SDiffCallbacks, both old and new objects will be presented for both -# changed and unchanged objects. +nil+ will be substituted -# for a discarded object. -# -# The diffset produced by this callback, when provided to Diff::LCS#sdiff, -# will compute and display the necessary components to show two sequences -# and their minimized differences side by side, just like the Unix utility -# +sdiff+. -# -# same same -# before | after -# old < - -# - > new -# -# seq1 = %w(a b c e h j l m n p) -# seq2 = %w(b c d e f j k l m r s t) -# -# diffs = Diff::LCS.sdiff(seq1, seq2) -# # This example shows a simplified array format. -# # [ [ "-", [ 0, "a"], [ 0, nil ] ], -# # [ "=", [ 1, "b"], [ 0, "b" ] ], -# # [ "=", [ 2, "c"], [ 1, "c" ] ], -# # [ "+", [ 3, nil], [ 2, "d" ] ], -# # [ "=", [ 3, "e"], [ 3, "e" ] ], -# # [ "!", [ 4, "h"], [ 4, "f" ] ], -# # [ "=", [ 5, "j"], [ 5, "j" ] ], -# # [ "+", [ 6, nil], [ 6, "k" ] ], -# # [ "=", [ 6, "l"], [ 7, "l" ] ], -# # [ "=", [ 7, "m"], [ 8, "m" ] ], -# # [ "!", [ 8, "n"], [ 9, "r" ] ], -# # [ "!", [ 9, "p"], [ 10, "s" ] ], -# # [ "+", [ 10, nil], [ 11, "t" ] ] ] -# -# The result of this operation is similar to that of -# Diff::LCS::ContextDiffCallbacks. They may be compared as: -# -# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } -# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) -# -# s == c # -> true -# -# === Use -# -# This callback object must be initialised and is used by the Diff::LCS#sdiff -# method. -# -# cbo = Diff::LCS::SDiffCallbacks.new -# Diff::LCS.LCS(seq1, seq2, cbo) -# -# As with the other initialisable callback objects, -# Diff::LCS::SDiffCallbacks can be initialised with a block. As there is no -# "fininishing" to be done, this has no effect on the state of the object. -# -# cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } -# -# === Simplified Array Format -# -# The simplified array format used in the example above can be obtained -# with: -# -# require 'pp' -# pp diffs.map { |e| e.to_a } -class Diff::LCS::SDiffCallbacks - # Returns the difference set collected during the diff process. - attr_reader :diffs - - def initialize # :yields: self - @diffs = [] - yield self if block_given? - end - - def match(event) - @diffs << Diff::LCS::ContextChange.simplify(event) - end - - def discard_a(event) - @diffs << Diff::LCS::ContextChange.simplify(event) - end - - def discard_b(event) - @diffs << Diff::LCS::ContextChange.simplify(event) - end - - def change(event) - @diffs << Diff::LCS::ContextChange.simplify(event) - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb deleted file mode 100644 index 714d78c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb +++ /dev/null @@ -1,174 +0,0 @@ -# frozen_string_literal: true - -# Represents a simplistic (non-contextual) change. Represents the removal or -# addition of an element from either the old or the new sequenced -# enumerable. -class Diff::LCS::Change - IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName - - # The only actions valid for changes are '+' (add), '-' (delete), '=' - # (no change), '!' (changed), '<' (tail changes from first sequence), or - # '>' (tail changes from second sequence). The last two ('<>') are only - # found with Diff::LCS::diff and Diff::LCS::sdiff. - VALID_ACTIONS = %w[+ - = ! > <].freeze - - def self.valid_action?(action) - VALID_ACTIONS.include? action - end - - # Returns the action this Change represents. - attr_reader :action - - # Returns the position of the Change. - attr_reader :position - # Returns the sequence element of the Change. - attr_reader :element - - def initialize(*args) - @action, @position, @element = *args - - fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) - fail "Invalid Position Type" unless @position.is_a? IntClass - end - - def inspect(*_args) - "#<#{self.class}: #{to_a.inspect}>" - end - - def to_a - [@action, @position, @element] - end - - alias_method :to_ary, :to_a - - def self.from_a(arr) - arr = arr.flatten(1) - case arr.size - when 5 - Diff::LCS::ContextChange.new(*arr[0...5]) - when 3 - Diff::LCS::Change.new(*arr[0...3]) - else - fail "Invalid change array format provided." - end - end - - include Comparable - - def ==(other) - (self.class == other.class) and - (action == other.action) and - (position == other.position) and - (element == other.element) - end - - def <=>(other) - r = action <=> other.action - r = position <=> other.position if r.zero? - r = element <=> other.element if r.zero? - r - end - - def adding? - @action == "+" - end - - def deleting? - @action == "-" - end - - def unchanged? - @action == "=" - end - - def changed? - @action == "!" - end - - def finished_a? - @action == ">" - end - - def finished_b? - @action == "<" - end -end - -# Represents a contextual change. Contains the position and values of the -# elements in the old and the new sequenced enumerables as well as the action -# taken. -class Diff::LCS::ContextChange < Diff::LCS::Change - # We don't need these two values. - undef :position - undef :element - - # Returns the old position being changed. - attr_reader :old_position - # Returns the new position being changed. - attr_reader :new_position - # Returns the old element being changed. - attr_reader :old_element - # Returns the new element being changed. - attr_reader :new_element - - def initialize(*args) - @action, @old_position, @old_element, @new_position, @new_element = *args - - fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) - fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass) - fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass) - end - - def to_a - [ - @action, - [@old_position, @old_element], - [@new_position, @new_element] - ] - end - - alias_method :to_ary, :to_a - - def self.from_a(arr) - Diff::LCS::Change.from_a(arr) - end - - # Simplifies a context change for use in some diff callbacks. '<' actions - # are converted to '-' and '>' actions are converted to '+'. - def self.simplify(event) - ea = event.to_a - - case ea[0] - when "-" - ea[2][1] = nil - when "<" - ea[0] = "-" - ea[2][1] = nil - when "+" - ea[1][1] = nil - when ">" - ea[0] = "+" - ea[1][1] = nil - end - - Diff::LCS::ContextChange.from_a(ea) - end - - def ==(other) - (self.class == other.class) and - (@action == other.action) and - (@old_position == other.old_position) and - (@new_position == other.new_position) and - (@old_element == other.old_element) and - (@new_element == other.new_element) - end - - def <=>(other) - r = @action <=> other.action - r = @old_position <=> other.old_position if r.zero? - r = @new_position <=> other.new_position if r.zero? - r = @old_element <=> other.old_element if r.zero? - r = @new_element <=> other.new_element if r.zero? - r - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb deleted file mode 100644 index 9073243..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb +++ /dev/null @@ -1,160 +0,0 @@ -# frozen_string_literal: true - -require "erb" - -# Produce a simple HTML diff view. -class Diff::LCS::HTMLDiff - class << self - # standard:disable ThreadSafety/ClassAndModuleAttributes - attr_accessor :can_expand_tabs # :nodoc: - # standard:enable ThreadSafety/ClassAndModuleAttributes - end - self.can_expand_tabs = true - - class Callbacks # :nodoc: - attr_accessor :output - attr_accessor :match_class - attr_accessor :only_a_class - attr_accessor :only_b_class - - def initialize(output, options = {}) - @output = output - options ||= {} - - @match_class = options[:match_class] || "match" - @only_a_class = options[:only_a_class] || "only_a" - @only_b_class = options[:only_b_class] || "only_b" - end - - def htmlize(element, css_class) - element = " " if element.empty? - %(

#{element}
\n) - end - private :htmlize - - # This will be called with both lines are the same - def match(event) - @output << htmlize(event.old_element, :match_class) - end - - # This will be called when there is a line in A that isn't in B - def discard_a(event) - @output << htmlize(event.old_element, :only_a_class) - end - - # This will be called when there is a line in B that isn't in A - def discard_b(event) - @output << htmlize(event.new_element, :only_b_class) - end - end - - # standard:disable Style/HashSyntax - DEFAULT_OPTIONS = { - :expand_tabs => nil, - :output => nil, - :css => nil, - :title => nil - }.freeze - # standard:enable Style/HashSyntax - - # standard:disable Layout/HeredocIndentation - DEFAULT_CSS = <<-CSS -body { margin: 0; } -.diff -{ - border: 1px solid black; - margin: 1em 2em; -} -p -{ - margin-left: 2em; -} -pre -{ - padding-left: 1em; - margin: 0; - font-family: Inconsolata, Consolas, Lucida, Courier, monospaced; - white-space: pre; -} -.match { } -.only_a -{ - background-color: #fdd; - color: red; - text-decoration: line-through; -} -.only_b -{ - background-color: #ddf; - color: blue; - border-left: 3px solid blue -} -h1 { margin-left: 2em; } - CSS - # standard:enable Layout/HeredocIndentation - - def initialize(left, right, options = nil) - @left = left - @right = right - @options = options - - @options = DEFAULT_OPTIONS.dup if @options.nil? - end - - def verify_options - @options[:expand_tabs] ||= 4 - @options[:expand_tabs] = 4 if @options[:expand_tabs].negative? - - @options[:output] ||= $stdout - - @options[:css] ||= DEFAULT_CSS.dup - - @options[:title] ||= "diff" - end - private :verify_options - - attr_reader :options - - def run - verify_options - - if @options[:expand_tabs].positive? && self.class.can_expand_tabs - formatter = Text::Format.new - formatter.tabstop = @options[:expand_tabs] - - @left.map! { |line| formatter.expand(line.chomp) } - @right.map! { |line| formatter.expand(line.chomp) } - end - - @left.map! { |line| ERB::Util.html_escape(line.chomp) } - @right.map! { |line| ERB::Util.html_escape(line.chomp) } - - # standard:disable Layout/HeredocIndentation - @options[:output] << <<-OUTPUT - - - #{@options[:title]} - - - -

#{@options[:title]}

-

Legend: Only in Old  - Only in New

-
- OUTPUT - # standard:enable Layout/HeredocIndentation - - callbacks = Callbacks.new(@options[:output]) - Diff::LCS.traverse_sequences(@left, @right, callbacks) - - # standard:disable Layout/HeredocIndentation - @options[:output] << <<-OUTPUT -
- - - OUTPUT - # standard:enable Layout/HeredocIndentation - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb deleted file mode 100644 index 24b33bc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb +++ /dev/null @@ -1,379 +0,0 @@ -# frozen_string_literal: true - -require "diff/lcs/block" - -# A Hunk is a group of Blocks which overlap because of the context surrounding -# each block. (So if we're not using context, every hunk will contain one -# block.) Used in the diff program (bin/ldiff). -class Diff::LCS::Hunk - OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: - ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: - - private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant) - - # Create a hunk using references to both the old and new data, as well as the - # piece of data. - def initialize(data_old, data_new, piece, flag_context, file_length_difference) - # At first, a hunk will have just one Block in it - @blocks = [Diff::LCS::Block.new(piece)] - - if @blocks[0].remove.empty? && @blocks[0].insert.empty? - fail "Cannot build a hunk from #{piece.inspect}; has no add or remove actions" - end - - if String.method_defined?(:encoding) - @preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding - end - - @data_old = data_old - @data_new = data_new - @old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?) - @new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?) - - before = after = file_length_difference - after += @blocks[0].diff_size - @file_length_difference = after # The caller must get this manually - @max_diff_size = @blocks.map { |e| e.diff_size.abs }.max - - # Save the start & end of each array. If the array doesn't exist (e.g., - # we're only adding items in this block), then figure out the line number - # based on the line number of the other file and the current difference in - # file lengths. - if @blocks[0].remove.empty? - a1 = a2 = nil - else - a1 = @blocks[0].remove[0].position - a2 = @blocks[0].remove[-1].position - end - - if @blocks[0].insert.empty? - b1 = b2 = nil - else - b1 = @blocks[0].insert[0].position - b2 = @blocks[0].insert[-1].position - end - - @start_old = a1 || (b1 - before) - @start_new = b1 || (a1 + before) - @end_old = a2 || (b2 - after) - @end_new = b2 || (a2 + after) - - self.flag_context = flag_context - end - - attr_reader :blocks - attr_reader :start_old, :start_new - attr_reader :end_old, :end_new - attr_reader :file_length_difference - - # Change the "start" and "end" fields to note that context should be added - # to this hunk. - attr_accessor :flag_context - undef :flag_context= - def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods - return if context.nil? || context.zero? - - add_start = (context > @start_old) ? @start_old : context - - @start_old -= add_start - @start_new -= add_start - - old_size = @data_old.size - - add_end = - if (@end_old + context) >= old_size - old_size - @end_old - 1 - else - context - end - - @end_old += add_end - @end_new += add_end - end - - # Merges this hunk and the provided hunk together if they overlap. Returns - # a truthy value so that if there is no overlap, you can know the merge - # was skipped. - def merge(hunk) - return unless overlaps?(hunk) - - @start_old = hunk.start_old - @start_new = hunk.start_new - blocks.unshift(*hunk.blocks) - end - alias_method :unshift, :merge - - # Determines whether there is an overlap between this hunk and the - # provided hunk. This will be true if the difference between the two hunks - # start or end positions is within one position of each other. - def overlaps?(hunk) - hunk and (((@start_old - hunk.end_old) <= 1) or - ((@start_new - hunk.end_new) <= 1)) - end - - # Returns a diff string based on a format. - def diff(format, last = false) - case format - when :old - old_diff(last) - when :unified - unified_diff(last) - when :context - context_diff(last) - when :ed - self - when :reverse_ed, :ed_finish - ed_diff(format, last) - else - fail "Unknown diff format #{format}." - end - end - - # Note that an old diff can't have any context. Therefore, we know that - # there's only one block in the hunk. - def old_diff(last = false) - warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 - - block = @blocks[0] - - if last - old_missing_newline = !@old_empty && missing_last_newline?(@data_old) - new_missing_newline = !@new_empty && missing_last_newline?(@data_new) - end - - # Calculate item number range. Old diff range is just like a context - # diff range, except the ranges are on one line with the action between - # them. - s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n") - # If removing anything, just print out all the remove lines in the hunk - # which is just all the remove lines in the block. - unless block.remove.empty? - @data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") } - end - - s << encode("\\ No newline at end of file\n") if old_missing_newline && !new_missing_newline - s << encode("---\n") if block.op == "!" - - unless block.insert.empty? - @data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") } - end - - s << encode("\\ No newline at end of file\n") if new_missing_newline && !old_missing_newline - - s - end - private :old_diff - - def unified_diff(last = false) - # Calculate item number range. - s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n") - - # Outlist starts containing the hunk of the old file. Removing an item - # just means putting a '-' in front of it. Inserting an item requires - # getting it from the new file and splicing it in. We splice in - # +num_added+ items. Remove blocks use +num_added+ because splicing - # changed the length of outlist. - # - # We remove +num_removed+ items. Insert blocks use +num_removed+ - # because their item numbers -- corresponding to positions in the NEW - # file -- don't take removed items into account. - lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0 - - # standard:disable Performance/UnfreezeString - outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } - # standard:enable Performance/UnfreezeString - - last_block = blocks[-1] - - if last - old_missing_newline = !@old_empty && missing_last_newline?(@data_old) - new_missing_newline = !@new_empty && missing_last_newline?(@data_new) - end - - @blocks.each do |block| - block.remove.each do |item| - op = item.action.to_s # - - offset = item.position - lo + num_added - outlist[offset][0, 1] = encode(op) - num_removed += 1 - end - - if last && block == last_block && old_missing_newline && !new_missing_newline - outlist << encode('\\ No newline at end of file') - num_removed += 1 - end - - block.insert.each do |item| - op = item.action.to_s # + - offset = item.position - @start_new + num_removed - outlist[offset, 0] = encode(op) + @data_new[item.position].chomp - num_added += 1 - end - end - - outlist << encode('\\ No newline at end of file') if last && new_missing_newline - - s << outlist.join(encode("\n")) - - s - end - private :unified_diff - - def context_diff(last = false) - s = encode("***************\n") - s << encode("*** #{context_range(:old, ",")} ****\n") - r = context_range(:new, ",") - - if last - old_missing_newline = missing_last_newline?(@data_old) - new_missing_newline = missing_last_newline?(@data_new) - end - - # Print out file 1 part for each block in context diff format if there - # are any blocks that remove items - lo, hi = @start_old, @end_old - removes = @blocks.reject { |e| e.remove.empty? } - - unless removes.empty? - # standard:disable Performance/UnfreezeString - outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } - # standard:enable Performance/UnfreezeString - - last_block = removes[-1] - - removes.each do |block| - block.remove.each do |item| - outlist[item.position - lo][0, 1] = encode(block.op) # - or ! - end - - if last && block == last_block && old_missing_newline - outlist << encode('\\ No newline at end of file') - end - end - - s << outlist.join(encode("\n")) << encode("\n") - end - - s << encode("--- #{r} ----\n") - lo, hi = @start_new, @end_new - inserts = @blocks.reject { |e| e.insert.empty? } - - unless inserts.empty? - # standard:disable Performance/UnfreezeString - outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } - # standard:enable Performance/UnfreezeString - - last_block = inserts[-1] - - inserts.each do |block| - block.insert.each do |item| - outlist[item.position - lo][0, 1] = encode(block.op) # + or ! - end - - if last && block == last_block && new_missing_newline - outlist << encode('\\ No newline at end of file') - end - end - s << outlist.join(encode("\n")) - end - - s - end - private :context_diff - - def ed_diff(format, last) - warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 - if last - # ed script doesn't support well incomplete lines - warn ": No newline at end of file\n" if !@old_empty && missing_last_newline?(@data_old) - warn ": No newline at end of file\n" if !@new_empty && missing_last_newline?(@data_new) - - if @blocks[0].op == "!" - return +"" if @blocks[0].changes[0].element == @blocks[0].changes[1].element + "\n" - return +"" if @blocks[0].changes[0].element + "\n" == @blocks[0].changes[1].element - end - end - - s = - if format == :reverse_ed - encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n") - else - encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n") - end - - unless @blocks[0].insert.empty? - @data_new[@start_new..@end_new].each do |e| - s << e.chomp + encode("\n") - end - s << encode(".\n") - end - s - end - private :ed_diff - - # Generate a range of item numbers to print. Only print 1 number if the - # range has only one item in it. Otherwise, it's 'start,end' - def context_range(mode, op) - case mode - when :old - s, e = (@start_old + 1), (@end_old + 1) - when :new - s, e = (@start_new + 1), (@end_new + 1) - end - - (s < e) ? "#{s}#{op}#{e}" : e.to_s - end - private :context_range - - # Generate a range of item numbers to print for unified diff. Print number - # where block starts, followed by number of lines in the block - # (don't print number of lines if it's 1) - def unified_range(mode) - case mode - when :old - return "0,0" if @old_empty - s, e = (@start_old + 1), (@end_old + 1) - when :new - return "0,0" if @new_empty - s, e = (@start_new + 1), (@end_new + 1) - end - - length = e - s + 1 - - (length <= 1) ? e.to_s : "#{s},#{length}" - end - private :unified_range - - def missing_last_newline?(data) - newline = encode("\n") - - if data[-2] - data[-2].end_with?(newline) && !data[-1].end_with?(newline) - elsif data[-1] - !data[-1].end_with?(newline) - else - true - end - end - - if String.method_defined?(:encoding) - def encode(literal, target_encoding = @preferred_data_encoding) - literal.encode target_encoding - end - - def encode_as(string, *args) - args.map { |arg| arg.encode(string.encoding) } - end - else - def encode(literal, _target_encoding = nil) - literal - end - - def encode_as(_string, *args) - args - end - end - - private :encode - private :encode_as -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb deleted file mode 100644 index 8a9160a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb +++ /dev/null @@ -1,308 +0,0 @@ -# frozen_string_literal: true - -class << Diff::LCS - def diff_traversal(method, seq1, seq2, callbacks, &block) - callbacks = callbacks_for(callbacks) - case method - when :diff - traverse_sequences(seq1, seq2, callbacks) - when :sdiff - traverse_balanced(seq1, seq2, callbacks) - end - callbacks.finish if callbacks.respond_to? :finish - - if block - callbacks.diffs.map do |hunk| - if hunk.is_a? Array - hunk.map { |hunk_block| block[hunk_block] } - else - block[hunk] - end - end - else - callbacks.diffs - end - end - private :diff_traversal -end - -module Diff::LCS::Internals # :nodoc: -end - -class << Diff::LCS::Internals - # Compute the longest common subsequence between the sequenced - # Enumerables +a+ and +b+. The result is an array whose contents is such - # that - # - # result = Diff::LCS::Internals.lcs(a, b) - # result.each_with_index do |e, i| - # assert_equal(a[i], b[e]) unless e.nil? - # end - def lcs(a, b) - a_start = b_start = 0 - a_finish = a.size - 1 - b_finish = b.size - 1 - vector = [] - - # Collect any common elements at the beginning... - while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_start] == b[b_start]) - vector[a_start] = b_start - a_start += 1 - b_start += 1 - end - - # Now the end... - while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_finish] == b[b_finish]) - vector[a_finish] = b_finish - a_finish -= 1 - b_finish -= 1 - end - - # Now, compute the equivalence classes of positions of elements. - # An explanation for how this works: https://codeforces.com/topic/92191 - b_matches = position_hash(b, b_start..b_finish) - - thresh = [] - links = [] - string = a.is_a?(String) - - (a_start..a_finish).each do |i| - ai = string ? a[i, 1] : a[i] - bm = b_matches[ai] - k = nil - bm.reverse_each do |j| - # Although the threshold check is not mandatory for this to work, - # it may have an optimization purpose - # An attempt to remove it: https://github.com/halostatue/diff-lcs/pull/72 - # Why it is reintroduced: https://github.com/halostatue/diff-lcs/issues/78 - if k && (thresh[k] > j) && (thresh[k - 1] < j) - thresh[k] = j - else - k = replace_next_larger(thresh, j, k) - end - links[k] = [k.positive? ? links[k - 1] : nil, i, j] unless k.nil? - end - end - - unless thresh.empty? - link = links[thresh.size - 1] - until link.nil? - vector[link[1]] = link[2] - link = link[0] - end - end - - vector - end - - # This method will analyze the provided patchset to provide a single-pass - # normalization (conversion of the array form of Diff::LCS::Change objects to - # the object form of same) and detection of whether the patchset represents - # changes to be made. - def analyze_patchset(patchset, depth = 0) - fail "Patchset too complex" if depth > 1 - - has_changes = false - new_patchset = [] - - # Format: - # [ # patchset - # # hunk (change) - # [ # hunk - # # change - # ] - # ] - - patchset.each do |hunk| - case hunk - when Diff::LCS::Change - has_changes ||= !hunk.unchanged? - new_patchset << hunk - when Array - # Detect if the 'hunk' is actually an array-format change object. - if Diff::LCS::Change.valid_action? hunk[0] - hunk = Diff::LCS::Change.from_a(hunk) - has_changes ||= !hunk.unchanged? - new_patchset << hunk - else - with_changes, hunk = analyze_patchset(hunk, depth + 1) - has_changes ||= with_changes - new_patchset.concat(hunk) - end - else - fail ArgumentError, "Cannot normalise a hunk of class #{hunk.class}." - end - end - - [has_changes, new_patchset] - end - - # Examine the patchset and the source to see in which direction the - # patch should be applied. - # - # WARNING: By default, this examines the whole patch, so this could take - # some time. This also works better with Diff::LCS::ContextChange or - # Diff::LCS::Change as its source, as an array will cause the creation - # of one of the above. - def intuit_diff_direction(src, patchset, limit = nil) - string = src.is_a?(String) - count = left_match = left_miss = right_match = right_miss = 0 - - patchset.each do |change| - count += 1 - - case change - when Diff::LCS::ContextChange - le = string ? src[change.old_position, 1] : src[change.old_position] - re = string ? src[change.new_position, 1] : src[change.new_position] - - case change.action - when "-" # Remove details from the old string - if le == change.old_element - left_match += 1 - else - left_miss += 1 - end - when "+" - if re == change.new_element - right_match += 1 - else - right_miss += 1 - end - when "=" - left_miss += 1 if le != change.old_element - right_miss += 1 if re != change.new_element - when "!" - if le == change.old_element - left_match += 1 - elsif re == change.new_element - right_match += 1 - else - left_miss += 1 - right_miss += 1 - end - end - when Diff::LCS::Change - # With a simplistic change, we can't tell the difference between - # the left and right on '!' actions, so we ignore those. On '=' - # actions, if there's a miss, we miss both left and right. - element = string ? src[change.position, 1] : src[change.position] - - case change.action - when "-" - if element == change.element - left_match += 1 - else - left_miss += 1 - end - when "+" - if element == change.element - right_match += 1 - else - right_miss += 1 - end - when "=" - if element != change.element - left_miss += 1 - right_miss += 1 - end - end - end - - break if !limit.nil? && (count > limit) - end - - no_left = left_match.zero? && left_miss.positive? - no_right = right_match.zero? && right_miss.positive? - - case [no_left, no_right] - when [false, true] - :patch - when [true, false] - :unpatch - else - case left_match <=> right_match - when 1 - if left_miss.zero? - :patch - else - :unpatch - end - when -1 - if right_miss.zero? - :unpatch - else - :patch - end - else - fail "The provided patchset does not appear to apply to the provided \ -enumerable as either source or destination value." - end - end - end - - # Find the place at which +value+ would normally be inserted into the - # Enumerable. If that place is already occupied by +value+, do nothing - # and return +nil+. If the place does not exist (i.e., it is off the end - # of the Enumerable), add it to the end. Otherwise, replace the element - # at that point with +value+. It is assumed that the Enumerable's values - # are numeric. - # - # This operation preserves the sort order. - def replace_next_larger(enum, value, last_index = nil) - # Off the end? - if enum.empty? || (value > enum[-1]) - enum << value - return enum.size - 1 - end - - # Binary search for the insertion point - last_index ||= enum.size - 1 - first_index = 0 - while first_index <= last_index - i = (first_index + last_index) >> 1 - - found = enum[i] - - return nil if value == found - - if value > found - first_index = i + 1 - else - last_index = i - 1 - end - end - - # The insertion point is in first_index; overwrite the next larger - # value. - enum[first_index] = value - first_index - end - private :replace_next_larger - - # If +vector+ maps the matching elements of another collection onto this - # Enumerable, compute the inverse of +vector+ that maps this Enumerable - # onto the collection. (Currently unused.) - def inverse_vector(a, vector) - inverse = a.dup - (0...vector.size).each do |i| - inverse[vector[i]] = i unless vector[i].nil? - end - inverse - end - private :inverse_vector - - # Returns a hash mapping each element of an Enumerable to the set of - # positions it occupies in the Enumerable, optionally restricted to the - # elements specified in the range of indexes specified by +interval+. - def position_hash(enum, interval) - string = enum.is_a?(String) - hash = Hash.new { |h, k| h[k] = [] } - interval.each do |i| - k = string ? enum[i, 1] : enum[i] - hash[k] << i - end - hash - end - private :position_hash -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb deleted file mode 100644 index 6442c9b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb +++ /dev/null @@ -1,189 +0,0 @@ -# frozen_string_literal: true - -require "optparse" -require "diff/lcs/hunk" - -class Diff::LCS::Ldiff # :nodoc: - # standard:disable Layout/HeredocIndentation - BANNER = <<-COPYRIGHT -ldiff #{Diff::LCS::VERSION} - Copyright 2004-2025 Austin Ziegler - - Part of Diff::LCS. - https://github.com/halostatue/diff-lcs - - This program is free software. It may be redistributed and/or modified under - the terms of the GPL version 2 (or later), the Perl Artistic licence, or the - MIT licence. - COPYRIGHT - # standard:enable Layout/HeredocIndentation - - InputInfo = Struct.new(:filename, :data, :stat) do - def initialize(filename) - super(filename, ::File.read(filename), ::File.stat(filename)) - end - end - - attr_reader :format, :lines # :nodoc: - attr_reader :file_old, :file_new # :nodoc: - attr_reader :data_old, :data_new # :nodoc: - - def self.run(args, input = $stdin, output = $stdout, error = $stderr) # :nodoc: - new.run(args, input, output, error) - end - - def initialize - @binary = nil - @format = :old - @lines = 0 - end - - def run(args, _input = $stdin, output = $stdout, error = $stderr) # :nodoc: - args.options do |o| - o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile" - o.separator "" - o.on( - "-c", "-C", "--context [LINES]", Integer, - "Displays a context diff with LINES lines", "of context. Default 3 lines." - ) do |ctx| - @format = :context - @lines = ctx || 3 - end - o.on( - "-u", "-U", "--unified [LINES]", Integer, - "Displays a unified diff with LINES lines", "of context. Default 3 lines." - ) do |ctx| - @format = :unified - @lines = ctx || 3 - end - o.on("-e", "Creates an 'ed' script to change", "oldfile to newfile.") do |_ctx| - @format = :ed - end - o.on("-f", "Creates an 'ed' script to change", "oldfile to newfile in reverse order.") do |_ctx| - @format = :reverse_ed - end - o.on( - "-a", "--text", - "Treat the files as text and compare them", "line-by-line, even if they do not seem", "to be text." - ) do |_txt| - @binary = false - end - o.on("--binary", "Treats the files as binary.") do |_bin| - @binary = true - end - o.on("-q", "--brief", "Report only whether or not the files", "differ, not the details.") do |_ctx| - @format = :report - end - o.on_tail("--help", "Shows this text.") do - error << o - return 0 - end - o.on_tail("--version", "Shows the version of Diff::LCS.") do - error << Diff::LCS::Ldiff::BANNER - return 0 - end - o.on_tail "" - o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.' - o.parse! - end - - unless args.size == 2 - error << args.options - return 127 - end - - # Defaults are for old-style diff - @format ||= :old - @lines ||= 0 - - file_old, file_new = *ARGV - diff?( - InputInfo.new(file_old), - InputInfo.new(file_new), - @format, - output, - binary: @binary, - lines: @lines - ) ? 1 : 0 - end - - def diff?(info_old, info_new, format, output, binary: nil, lines: 0) - case format - when :context - char_old = "*" * 3 - char_new = "-" * 3 - when :unified - char_old = "-" * 3 - char_new = "+" * 3 - end - - # After we've read up to a certain point in each file, the number of - # items we've read from each file will differ by FLD (could be 0). - file_length_difference = 0 - - # Test binary status - if binary.nil? - old_bin = info_old.data[0, 4096].include?("\0") - new_bin = info_new.data[0, 4096].include?("\0") - binary = old_bin || new_bin - end - - # diff yields lots of pieces, each of which is basically a Block object - if binary - has_diffs = (info_old.data != info_new.data) - if format != :report - if has_diffs - output << "Binary files #{info_old.filename} and #{info_new.filename} differ\n" - return true - end - return false - end - else - data_old = info_old.data.lines.to_a - data_new = info_new.data.lines.to_a - diffs = Diff::LCS.diff(data_old, data_new) - return false if diffs.empty? - end - - case format - when :report - output << "Files #{info_old.filename} and #{info_new.filename} differ\n" - return true - when :unified, :context - ft = info_old.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") - output << "#{char_old} #{info_old.filename}\t#{ft}\n" - ft = info_new.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") - output << "#{char_new} #{info_new.filename}\t#{ft}\n" - when :ed - real_output = output - output = [] - end - - # Loop over hunks. If a hunk overlaps with the last hunk, join them. - # Otherwise, print out the old one. - oldhunk = hunk = nil - diffs.each do |piece| - begin - hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, lines, file_length_difference) - file_length_difference = hunk.file_length_difference - - next unless oldhunk - next if lines.positive? && hunk.merge(oldhunk) - - output << oldhunk.diff(format) - output << "\n" if format == :unified - ensure - oldhunk = hunk - end - end - - last = oldhunk.diff(format, true) - last << "\n" unless last.is_a?(Diff::LCS::Hunk) || last.empty? || last.end_with?("\n") - - output << last - - output.reverse_each { |e| real_output << e.diff(:ed_finish, e == output[0]) } if format == :ed - - true - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb deleted file mode 100644 index 9ab32e9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class String - include Diff::LCS -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb deleted file mode 100644 index 82830e3..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Diff - module LCS - VERSION = "1.6.2" - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml deleted file mode 100644 index 22418cf..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml +++ /dev/null @@ -1,5 +0,0 @@ -[tools] -ruby = "3.4" - -[env] -MAINTENANCE = "true" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb deleted file mode 100644 index 42533ae..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Diff::LCS::Change do - describe "an add" do - subject { described_class.new("+", 0, "element") } - it { should_not be_deleting } - it { should be_adding } - it { should_not be_unchanged } - it { should_not be_changed } - it { should_not be_finished_a } - it { should_not be_finished_b } - end - - describe "a delete" do - subject { described_class.new("-", 0, "element") } - it { should be_deleting } - it { should_not be_adding } - it { should_not be_unchanged } - it { should_not be_changed } - it { should_not be_finished_a } - it { should_not be_finished_b } - end - - describe "an unchanged" do - subject { described_class.new("=", 0, "element") } - it { should_not be_deleting } - it { should_not be_adding } - it { should be_unchanged } - it { should_not be_changed } - it { should_not be_finished_a } - it { should_not be_finished_b } - end - - describe "a changed" do - subject { described_class.new("!", 0, "element") } - it { should_not be_deleting } - it { should_not be_adding } - it { should_not be_unchanged } - it { should be_changed } - it { should_not be_finished_a } - it { should_not be_finished_b } - end - - describe "a finished_a" do - subject { described_class.new(">", 0, "element") } - it { should_not be_deleting } - it { should_not be_adding } - it { should_not be_unchanged } - it { should_not be_changed } - it { should be_finished_a } - it { should_not be_finished_b } - end - - describe "a finished_b" do - subject { described_class.new("<", 0, "element") } - it { should_not be_deleting } - it { should_not be_adding } - it { should_not be_unchanged } - it { should_not be_changed } - it { should_not be_finished_a } - it { should be_finished_b } - end - - describe "as array" do - it "should be converted" do - action, position, element = described_class.new("!", 0, "element") - expect(action).to eq "!" - expect(position).to eq 0 - expect(element).to eq "element" - end - end -end - -describe Diff::LCS::ContextChange do - describe "as array" do - it "should be converted" do - action, (old_position, old_element), (new_position, new_element) = - described_class.new("!", 1, "old_element", 2, "new_element") - - expect(action).to eq "!" - expect(old_position).to eq 1 - expect(old_element).to eq "old_element" - expect(new_position).to eq 2 - expect(new_element).to eq "new_element" - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb deleted file mode 100644 index 869f098..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Diff::LCS, ".diff" do - include Diff::LCS::SpecHelper::Matchers - - it "correctly diffs seq1 to seq2" do - diff_s1_s2 = Diff::LCS.diff(seq1, seq2) - expect(change_diff(correct_forward_diff)).to eq(diff_s1_s2) - end - - it "correctly diffs seq2 to seq1" do - diff_s2_s1 = Diff::LCS.diff(seq2, seq1) - expect(change_diff(correct_backward_diff)).to eq(diff_s2_s1) - end - - it "correctly diffs against an empty sequence" do - diff = Diff::LCS.diff(word_sequence, []) - correct_diff = [ - [ - ["-", 0, "abcd"], - ["-", 1, "efgh"], - ["-", 2, "ijkl"], - ["-", 3, "mnopqrstuvwxyz"] - ] - ] - - expect(change_diff(correct_diff)).to eq(diff) - - diff = Diff::LCS.diff([], word_sequence) - correct_diff.each do |hunk| - hunk.each { |change| change[0] = "+" } - end - expect(change_diff(correct_diff)).to eq(diff) - end - - it "correctly diffs 'xx' and 'xaxb'" do - left = "xx" - right = "xaxb" - expect(Diff::LCS.patch(left, Diff::LCS.diff(left, right))).to eq(right) - end - - it "returns an empty diff with (hello, hello)" do - expect(Diff::LCS.diff(hello, hello)).to be_empty - end - - it "returns an empty diff with (hello_ary, hello_ary)" do - expect(Diff::LCS.diff(hello_ary, hello_ary)).to be_empty - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x deleted file mode 100644 index cd34c23..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x +++ /dev/null @@ -1,2 +0,0 @@ -123 -x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x deleted file mode 100644 index 9a823ac..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x +++ /dev/null @@ -1,2 +0,0 @@ -456 -x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX deleted file mode 100644 index 5765d6a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX +++ /dev/null @@ -1 +0,0 @@ -aX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX deleted file mode 100644 index a1c813d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX +++ /dev/null @@ -1 +0,0 @@ -bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv deleted file mode 100644 index 9ac8428..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv +++ /dev/null @@ -1,50 +0,0 @@ -1,3 -2,7 -3,13 -4,21 -5,31 -6,43 -7,57 -8,73 -9,91 -10,111 -11,133 -12,157 -13,183 -14,211 -15,241 -16,273 -17,307 -18,343 -19,381 -20,421 -21,463 -22,507 -23,553 -24,601 -25,651 -26,703 -27,757 -28,813 -29,871 -30,931 -31,993 -32,1057 -33,1123 -34,1191 -35,1261 -36,1333 -37,1407 -38,1483 -39,1561 -40,1641 -41,1723 -42,1807 -43,1893 -44,1981 -45,2071 -46,2163 -47,2257 -48,2353 -49,2451 -50,2500 \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv deleted file mode 100644 index 797de76..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv +++ /dev/null @@ -1,51 +0,0 @@ - 1,3 -2,7 -3,13 -4,21 -5,31 -6,42 -7,57 -8,73 -9,91 -10,111 -11,133 -12,157 -13,183 -14,211 -15,241 -16,273 -17,307 -18,343 -19,200 -20,421 -21,463 -22,507 -23,553 -24,601 -25,651 -26,703 -27,757 -28,813 -29,871 -30,931 -31,123 -32,1057 -33,1123 -34,1000 -35,1261 -36,1333 -37,1407 -38,1483 -39,1561 -40,1641 -41,1723 -42,1807 -43,1893 -44,1981 -45,2071 -46,2163 -47,1524 -48,2353 -49,2451 -50,2500 -51,2520 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin deleted file mode 100644 index ba18e3dcc474e720bdd955f81c8848324c862840..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 Ncmc~u&B@7U000O<0u=xN diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines deleted file mode 100644 index f384549..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines +++ /dev/null @@ -1,4 +0,0 @@ -one -two -three -four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line deleted file mode 100644 index c40a3bd..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line +++ /dev/null @@ -1,4 +0,0 @@ -one -two -three -four \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e deleted file mode 100644 index 1e8a89c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e +++ /dev/null @@ -1 +0,0 @@ -No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f deleted file mode 100644 index 1e8a89c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f +++ /dev/null @@ -1 +0,0 @@ -No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e deleted file mode 100644 index 1e8a89c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e +++ /dev/null @@ -1 +0,0 @@ -No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f deleted file mode 100644 index 1e8a89c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f +++ /dev/null @@ -1 +0,0 @@ -No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e deleted file mode 100644 index 8ed0319..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e +++ /dev/null @@ -1,2 +0,0 @@ -: No newline at end of file -: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f deleted file mode 100644 index 8ed0319..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f +++ /dev/null @@ -1,2 +0,0 @@ -: No newline at end of file -: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e deleted file mode 100644 index 397dd5b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e +++ /dev/null @@ -1 +0,0 @@ -: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f deleted file mode 100644 index 397dd5b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f +++ /dev/null @@ -1 +0,0 @@ -: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e deleted file mode 100644 index f9493ef..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e +++ /dev/null @@ -1 +0,0 @@ -: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f deleted file mode 100644 index f9493ef..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f +++ /dev/null @@ -1 +0,0 @@ -: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff deleted file mode 100644 index fa1a347..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff +++ /dev/null @@ -1,4 +0,0 @@ -1c1 -< aX ---- -> bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c deleted file mode 100644 index 0e1ad99..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c +++ /dev/null @@ -1,7 +0,0 @@ -*** spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 ---- spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 -*************** -*** 1 **** -! aX ---- 1 ---- -! bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e deleted file mode 100644 index 13e0f7f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e +++ /dev/null @@ -1,3 +0,0 @@ -1c -bXaX -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f deleted file mode 100644 index 77710c7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f +++ /dev/null @@ -1,3 +0,0 @@ -c1 -bXaX -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u deleted file mode 100644 index b84f718..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u +++ /dev/null @@ -1,5 +0,0 @@ ---- spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 -+++ spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 -@@ -1 +1 @@ --aX -+bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 deleted file mode 100644 index 41b625c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 +++ /dev/null @@ -1 +0,0 @@ -Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c deleted file mode 100644 index 41b625c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c +++ /dev/null @@ -1 +0,0 @@ -Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e deleted file mode 100644 index 41b625c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e +++ /dev/null @@ -1 +0,0 @@ -Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f deleted file mode 100644 index 41b625c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f +++ /dev/null @@ -1 +0,0 @@ -Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u deleted file mode 100644 index 41b625c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u +++ /dev/null @@ -1 +0,0 @@ -Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef deleted file mode 100644 index 8b98efb..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef +++ /dev/null @@ -1,4 +0,0 @@ -3c3 -< "description": "hi" ---- -> "description": "lo" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c deleted file mode 100644 index efbfa19..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c +++ /dev/null @@ -1,15 +0,0 @@ -*** spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 ---- spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 -*************** -*** 1,4 **** - { - "name": "x", -! "description": "hi" - } -\ No newline at end of file ---- 1,4 ---- - { - "name": "x", -! "description": "lo" - } -\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e deleted file mode 100644 index 775d881..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e +++ /dev/null @@ -1,3 +0,0 @@ -3c - "description": "lo" -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f deleted file mode 100644 index 9bf1e67..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f +++ /dev/null @@ -1,3 +0,0 @@ -c3 - "description": "lo" -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u deleted file mode 100644 index dbacd88..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u +++ /dev/null @@ -1,9 +0,0 @@ ---- spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 -+++ spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 -@@ -1,4 +1,4 @@ - { - "name": "x", -- "description": "hi" -+ "description": "lo" - } -\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 deleted file mode 100644 index 496b3dc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 +++ /dev/null @@ -1,7 +0,0 @@ -2d1 -< recipe[b::default] -14a14,17 -> recipe[o::new] -> recipe[p::new] -> recipe[q::new] -> recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c deleted file mode 100644 index 8349a7a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c +++ /dev/null @@ -1,20 +0,0 @@ -*** spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 ---- spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 -*************** -*** 1,5 **** - recipe[a::default] -- recipe[b::default] - recipe[c::default] - recipe[d::default] - recipe[e::default] ---- 1,4 ---- -*************** -*** 12,14 **** ---- 11,17 ---- - recipe[l::default] - recipe[m::default] - recipe[n::default] -+ recipe[o::new] -+ recipe[p::new] -+ recipe[q::new] -+ recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d deleted file mode 100644 index ca32a49..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d +++ /dev/null @@ -1,7 +0,0 @@ -d2 -a14 -recipe[o::new] -recipe[p::new] -recipe[q::new] -recipe[r::new] -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e deleted file mode 100644 index 89f3fa0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e +++ /dev/null @@ -1,7 +0,0 @@ -14a -recipe[o::new] -recipe[p::new] -recipe[q::new] -recipe[r::new] -. -2d diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f deleted file mode 100644 index ca32a49..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f +++ /dev/null @@ -1,7 +0,0 @@ -d2 -a14 -recipe[o::new] -recipe[p::new] -recipe[q::new] -recipe[r::new] -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u deleted file mode 100644 index ef025c7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u +++ /dev/null @@ -1,16 +0,0 @@ ---- spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 -+++ spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 -@@ -1,5 +1,4 @@ - recipe[a::default] --recipe[b::default] - recipe[c::default] - recipe[d::default] - recipe[e::default] -@@ -12,3 +11,7 @@ - recipe[l::default] - recipe[m::default] - recipe[n::default] -+recipe[o::new] -+recipe[p::new] -+recipe[q::new] -+recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines deleted file mode 100644 index e2afc31..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines +++ /dev/null @@ -1,5 +0,0 @@ -0a1,4 -> one -> two -> three -> four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c deleted file mode 100644 index be0e827..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +++ /dev/null @@ -1,9 +0,0 @@ -*** spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 ---- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 -*************** -*** 0 **** ---- 1,4 ---- -+ one -+ two -+ three -+ four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e deleted file mode 100644 index f8f92fe..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e +++ /dev/null @@ -1,6 +0,0 @@ -0a -one -two -three -four -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f deleted file mode 100644 index f02e5a0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f +++ /dev/null @@ -1,6 +0,0 @@ -a0 -one -two -three -four -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u deleted file mode 100644 index 60bd55c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +++ /dev/null @@ -1,7 +0,0 @@ ---- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 -+++ spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 -@@ -0,0 +1,4 @@ -+one -+two -+three -+four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty deleted file mode 100644 index 67d0a58..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty +++ /dev/null @@ -1,5 +0,0 @@ -1,4d0 -< one -< two -< three -< four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c deleted file mode 100644 index b216344..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +++ /dev/null @@ -1,9 +0,0 @@ -*** spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 ---- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 -*************** -*** 1,4 **** -- one -- two -- three -- four ---- 0 ---- diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e deleted file mode 100644 index c821d7c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e +++ /dev/null @@ -1 +0,0 @@ -1,4d diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f deleted file mode 100644 index 442bd5a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f +++ /dev/null @@ -1 +0,0 @@ -d1 4 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u deleted file mode 100644 index 79e6d75..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +++ /dev/null @@ -1,7 +0,0 @@ ---- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 -+++ spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 -@@ -1,4 +0,0 @@ --one --two --three --four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context deleted file mode 100644 index 4335560..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context +++ /dev/null @@ -1,4 +0,0 @@ -1c1 -< 123 ---- -> 456 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c deleted file mode 100644 index 4b759fa..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +++ /dev/null @@ -1,9 +0,0 @@ -*** spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 ---- spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 -*************** -*** 1,2 **** -! 123 - x ---- 1,2 ---- -! 456 - x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e deleted file mode 100644 index 7a8334b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e +++ /dev/null @@ -1,3 +0,0 @@ -1c -456 -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f deleted file mode 100644 index 97223a8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f +++ /dev/null @@ -1,3 +0,0 @@ -c1 -456 -. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u deleted file mode 100644 index 7fbf0e2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +++ /dev/null @@ -1,6 +0,0 @@ ---- spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 -+++ spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 -@@ -1,2 +1,2 @@ --123 -+456 - x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 deleted file mode 100644 index c5cb113..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 +++ /dev/null @@ -1,5 +0,0 @@ -4c4 -< four ---- -> four -\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c deleted file mode 100644 index 55d1ade..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c +++ /dev/null @@ -1,14 +0,0 @@ -*** spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 ---- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 -*************** -*** 1,4 **** - one - two - three -! four ---- 1,4 ---- - one - two - three -! four -\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u deleted file mode 100644 index 010518b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u +++ /dev/null @@ -1,9 +0,0 @@ ---- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 -+++ spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 -@@ -1,4 +1,4 @@ - one - two - three --four -+four -\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 deleted file mode 100644 index 10e4326..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 +++ /dev/null @@ -1,5 +0,0 @@ -4c4 -< four -\ No newline at end of file ---- -> four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c deleted file mode 100644 index b431030..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c +++ /dev/null @@ -1,14 +0,0 @@ -*** spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 ---- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 -*************** -*** 1,4 **** - one - two - three -! four -\ No newline at end of file ---- 1,4 ---- - one - two - three -! four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u deleted file mode 100644 index 2481a9e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u +++ /dev/null @@ -1,9 +0,0 @@ ---- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 -+++ spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 -@@ -1,4 +1,4 @@ - one - two - three --four -\ No newline at end of file -+four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef deleted file mode 100644 index d7babfe..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "x", - "description": "lo" -} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 deleted file mode 100644 index 8213c73..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 +++ /dev/null @@ -1,17 +0,0 @@ -recipe[a::default] -recipe[c::default] -recipe[d::default] -recipe[e::default] -recipe[f::default] -recipe[g::default] -recipe[h::default] -recipe[i::default] -recipe[j::default] -recipe[k::default] -recipe[l::default] -recipe[m::default] -recipe[n::default] -recipe[o::new] -recipe[p::new] -recipe[q::new] -recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef deleted file mode 100644 index 5f9e38b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "x", - "description": "hi" -} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 deleted file mode 100644 index 4a23407..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 +++ /dev/null @@ -1,14 +0,0 @@ -recipe[a::default] -recipe[b::default] -recipe[c::default] -recipe[d::default] -recipe[e::default] -recipe[f::default] -recipe[g::default] -recipe[h::default] -recipe[i::default] -recipe[j::default] -recipe[k::default] -recipe[l::default] -recipe[m::default] -recipe[n::default] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb deleted file mode 100644 index 7d91039..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb +++ /dev/null @@ -1,83 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -if String.method_defined?(:encoding) - require "diff/lcs/hunk" - - describe Diff::LCS::Hunk do - let(:old_data) { ["Tu a un carté avec {count} itéms".encode("UTF-16LE")] } - let(:new_data) { ["Tu a un carte avec {count} items".encode("UTF-16LE")] } - let(:pieces) { Diff::LCS.diff old_data, new_data } - let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) } - - it "produces a unified diff from the two pieces" do - expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp - @@ -1 +1 @@ - -Tu a un carté avec {count} itéms - +Tu a un carte avec {count} items - EXPECTED - - expect(hunk.diff(:unified)).to eq(expected) - end - - it "produces a unified diff from the two pieces (last entry)" do - expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp - @@ -1 +1 @@ - -Tu a un carté avec {count} itéms - +Tu a un carte avec {count} items - \\ No newline at end of file - EXPECTED - - expect(hunk.diff(:unified, true)).to eq(expected) - end - - it "produces a context diff from the two pieces" do - expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp - *************** - *** 1 **** - ! Tu a un carté avec {count} itéms - --- 1 ---- - ! Tu a un carte avec {count} items - EXPECTED - - expect(hunk.diff(:context)).to eq(expected) - end - - it "produces an old diff from the two pieces" do - expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp - 1c1 - < Tu a un carté avec {count} itéms - --- - > Tu a un carte avec {count} items - - EXPECTED - - expect(hunk.diff(:old)).to eq(expected) - end - - it "produces a reverse ed diff from the two pieces" do - expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp - c1 - Tu a un carte avec {count} items - . - - EXPECTED - - expect(hunk.diff(:reverse_ed)).to eq(expected) - end - - context "with empty first data set" do - let(:old_data) { [] } - - it "produces a unified diff" do - expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp - @@ -0,0 +1 @@ - +Tu a un carte avec {count} items - EXPECTED - - expect(hunk.diff(:unified)).to eq(expected) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb deleted file mode 100644 index 5b0fb2a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb +++ /dev/null @@ -1,160 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "diff/lcs/hunk" - -describe "Diff::LCS Issues" do - include Diff::LCS::SpecHelper::Matchers - - describe "issue #1" do - shared_examples "handles simple diffs" do |s1, s2, forward_diff| - before do - @diff_s1_s2 = Diff::LCS.diff(s1, s2) - end - - it "creates the correct diff" do - expect(change_diff(forward_diff)).to eq(@diff_s1_s2) - end - - it "creates the correct patch s1->s2" do - expect(Diff::LCS.patch(s1, @diff_s1_s2)).to eq(s2) - end - - it "creates the correct patch s2->s1" do - expect(Diff::LCS.patch(s2, @diff_s1_s2)).to eq(s1) - end - end - - describe "string" do - it_has_behavior "handles simple diffs", "aX", "bXaX", [ - [ - ["+", 0, "b"], - ["+", 1, "X"] - ] - ] - it_has_behavior "handles simple diffs", "bXaX", "aX", [ - [ - ["-", 0, "b"], - ["-", 1, "X"] - ] - ] - end - - describe "array" do - it_has_behavior "handles simple diffs", %w[a X], %w[b X a X], [ - [ - ["+", 0, "b"], - ["+", 1, "X"] - ] - ] - it_has_behavior "handles simple diffs", %w[b X a X], %w[a X], [ - [ - ["-", 0, "b"], - ["-", 1, "X"] - ] - ] - end - end - - describe "issue #57" do - it "should fail with a correct error" do - # standard:disable Style/HashSyntax - expect { - actual = {:category => "app.rack.request"} - expected = {:category => "rack.middleware", :title => "Anonymous Middleware"} - expect(actual).to eq(expected) - }.to raise_error(RSpec::Expectations::ExpectationNotMetError) - # standard:enable Style/HashSyntax - end - end - - describe "issue #65" do - def diff_lines(old_lines, new_lines) - file_length_difference = 0 - previous_hunk = nil - output = [] - - Diff::LCS.diff(old_lines, new_lines).each do |piece| - hunk = Diff::LCS::Hunk.new(old_lines, new_lines, piece, 3, file_length_difference) - file_length_difference = hunk.file_length_difference - maybe_contiguous_hunks = previous_hunk.nil? || hunk.merge(previous_hunk) - - output << "#{previous_hunk.diff(:unified)}\n" unless maybe_contiguous_hunks - - previous_hunk = hunk - end - output << "#{previous_hunk.diff(:unified, true)}\n" unless previous_hunk.nil? - output.join - end - - it "should not misplace the new chunk" do - old_data = [ - "recipe[a::default]", "recipe[b::default]", "recipe[c::default]", - "recipe[d::default]", "recipe[e::default]", "recipe[f::default]", - "recipe[g::default]", "recipe[h::default]", "recipe[i::default]", - "recipe[j::default]", "recipe[k::default]", "recipe[l::default]", - "recipe[m::default]", "recipe[n::default]" - ] - - new_data = [ - "recipe[a::default]", "recipe[c::default]", "recipe[d::default]", - "recipe[e::default]", "recipe[f::default]", "recipe[g::default]", - "recipe[h::default]", "recipe[i::default]", "recipe[j::default]", - "recipe[k::default]", "recipe[l::default]", "recipe[m::default]", - "recipe[n::default]", "recipe[o::new]", "recipe[p::new]", - "recipe[q::new]", "recipe[r::new]" - ] - - # standard:disable Layout/HeredocIndentation - expect(diff_lines(old_data, new_data)).to eq(<<-EODIFF) -@@ -1,5 +1,4 @@ - recipe[a::default] --recipe[b::default] - recipe[c::default] - recipe[d::default] - recipe[e::default] -@@ -12,3 +11,7 @@ - recipe[l::default] - recipe[m::default] - recipe[n::default] -+recipe[o::new] -+recipe[p::new] -+recipe[q::new] -+recipe[r::new] - EODIFF - # standard:enable Layout/HeredocIndentation - end - end - - describe "issue #107 (replaces issue #60)" do - it "should produce unified output with correct context" do - # standard:disable Layout/HeredocIndentation - old_data = <<-DATA_OLD.strip.split("\n").map(&:chomp) -{ - "name": "x", - "description": "hi" -} - DATA_OLD - - new_data = <<-DATA_NEW.strip.split("\n").map(&:chomp) -{ - "name": "x", - "description": "lo" -} - DATA_NEW - - diff = ::Diff::LCS.diff(old_data, new_data) - hunk = ::Diff::LCS::Hunk.new(old_data, new_data, diff.first, 3, 0) - - expect(hunk.diff(:unified)).to eq(<<-EXPECTED.chomp) -@@ -1,4 +1,4 @@ - { - "name": "x", -- "description": "hi" -+ "description": "lo" - } - EXPECTED - # standard:enable Layout/HeredocIndentation - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb deleted file mode 100644 index c17f22f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Diff::LCS::Internals, ".lcs" do - include Diff::LCS::SpecHelper::Matchers - - it "returns a meaningful LCS array with (seq1, seq2)" do - res = Diff::LCS::Internals.lcs(seq1, seq2) - # The result of the LCS (less the +nil+ values) must be as long as the - # correct result. - expect(res.compact.size).to eq(correct_lcs.size) - expect(res).to correctly_map_sequence(seq1).to_other_sequence(seq2) - - # Compact these transformations and they should be the correct LCS. - x_seq1 = (0...res.size).map { |ix| res[ix] ? seq1[ix] : nil }.compact - x_seq2 = (0...res.size).map { |ix| res[ix] ? seq2[res[ix]] : nil }.compact - - expect(x_seq1).to eq(correct_lcs) - expect(x_seq2).to eq(correct_lcs) - end - - it "returns all indexes with (hello, hello)" do - expect(Diff::LCS::Internals.lcs(hello, hello)).to \ - eq((0...hello.size).to_a) - end - - it "returns all indexes with (hello_ary, hello_ary)" do - expect(Diff::LCS::Internals.lcs(hello_ary, hello_ary)).to \ - eq((0...hello_ary.size).to_a) - end -end - -describe Diff::LCS, ".LCS" do - include Diff::LCS::SpecHelper::Matchers - - it "returns the correct compacted values from Diff::LCS.LCS" do - res = Diff::LCS.LCS(seq1, seq2) - expect(res).to eq(correct_lcs) - expect(res.compact).to eq(res) - end - - it "is transitive" do - res = Diff::LCS.LCS(seq2, seq1) - expect(res).to eq(correct_lcs) - expect(res.compact).to eq(res) - end - - it "returns %W(h e l l o) with (hello, hello)" do - expect(Diff::LCS.LCS(hello, hello)).to eq(hello.chars) - end - - it "returns hello_ary with (hello_ary, hello_ary)" do - expect(Diff::LCS.LCS(hello_ary, hello_ary)).to eq(hello_ary) - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb deleted file mode 100644 index e13b561..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -RSpec.describe "bin/ldiff" do - include CaptureSubprocessIO - - # standard:disable Style/HashSyntax - fixtures = [ - {:name => "diff", :left => "aX", :right => "bXaX", :diff => 1}, - {:name => "diff.missing_new_line1", :left => "four_lines", :right => "four_lines_with_missing_new_line", :diff => 1}, - {:name => "diff.missing_new_line2", :left => "four_lines_with_missing_new_line", :right => "four_lines", :diff => 1}, - {:name => "diff.issue95_trailing_context", :left => "123_x", :right => "456_x", :diff => 1}, - {:name => "diff.four_lines.vs.empty", :left => "four_lines", :right => "empty", :diff => 1}, - {:name => "diff.empty.vs.four_lines", :left => "empty", :right => "four_lines", :diff => 1}, - {:name => "diff.bin1", :left => "file1.bin", :right => "file1.bin", :diff => 0}, - {:name => "diff.bin2", :left => "file1.bin", :right => "file2.bin", :diff => 1}, - {:name => "diff.chef", :left => "old-chef", :right => "new-chef", :diff => 1}, - {:name => "diff.chef2", :left => "old-chef2", :right => "new-chef2", :diff => 1} - ].product([nil, "-e", "-f", "-c", "-u"]).map { |(fixture, flag)| - fixture = fixture.dup - fixture[:flag] = flag - fixture - } - # standard:enable Style/HashSyntax - - def self.test_ldiff(fixture) - desc = [ - fixture[:flag], - "spec/fixtures/#{fixture[:left]}", - "spec/fixtures/#{fixture[:right]}", - "#", - "=>", - "spec/fixtures/ldiff/output.#{fixture[:name]}#{fixture[:flag]}" - ].join(" ") - - it desc do - stdout, stderr, status = run_ldiff(fixture) - expect(status).to eq(fixture[:diff]) - expect(stderr).to eq(read_fixture(fixture, mode: "error", allow_missing: true)) - expect(stdout).to eq(read_fixture(fixture, mode: "output", allow_missing: false)) - end - end - - fixtures.each do |fixture| - test_ldiff(fixture) - end - - def read_fixture(options, mode: "output", allow_missing: false) - fixture = options.fetch(:name) - flag = options.fetch(:flag) - name = "spec/fixtures/ldiff/#{mode}.#{fixture}#{flag}" - - return "" if !::File.exist?(name) && allow_missing - - data = IO.__send__(IO.respond_to?(:binread) ? :binread : :read, name) - clean_data(data, flag) - end - - def clean_data(data, flag) - data = - case flag - when "-c", "-u" - clean_output_timestamp(data) - else - data - end - data.gsub(/\r\n?/, "\n") - end - - def clean_output_timestamp(data) - data.gsub( - %r{ - ^ - [-+*]{3} - \s* - spec/fixtures/(\S+) - \s* - \d{4}-\d\d-\d\d - \s* - \d\d:\d\d:\d\d(?:\.\d+) - \s* - (?:[-+]\d{4}|Z) - }x, - '*** spec/fixtures/\1 0000-00-00 :00 =>:00 =>00.000000000 -0000' - ) - end - - def run_ldiff(options) - flag = options.fetch(:flag) - left = options.fetch(:left) - right = options.fetch(:right) - - stdout, stderr = capture_subprocess_io do - system("ruby -Ilib bin/ldiff #{flag} spec/fixtures/#{left} spec/fixtures/#{right}") - end - - [clean_data(stdout, flag), stderr, $?.exitstatus] - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb deleted file mode 100644 index 8fc3ee2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb +++ /dev/null @@ -1,416 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Diff::LCS.patch" do - include Diff::LCS::SpecHelper::Matchers - - shared_examples "patch sequences correctly" do - it "correctly patches left-to-right (patch autodiscovery)" do - expect(Diff::LCS.patch(s1, patch_set)).to eq(s2) - end - - it "correctly patches left-to-right (explicit patch)" do - expect(Diff::LCS.patch(s1, patch_set, :patch)).to eq(s2) - expect(Diff::LCS.patch!(s1, patch_set)).to eq(s2) - end - - it "correctly patches right-to-left (unpatch autodiscovery)" do - expect(Diff::LCS.patch(s2, patch_set)).to eq(s1) - end - - it "correctly patches right-to-left (explicit unpatch)" do - expect(Diff::LCS.patch(s2, patch_set, :unpatch)).to eq(s1) - expect(Diff::LCS.unpatch!(s2, patch_set)).to eq(s1) - end - end - - describe "using a Diff::LCS.diff patchset" do - describe "an empty patchset returns the source" do - it "works on a string (hello)" do - diff = Diff::LCS.diff(hello, hello) - expect(Diff::LCS.patch(hello, diff)).to eq(hello) - end - - it "works on an array %W(h e l l o)" do - diff = Diff::LCS.diff(hello_ary, hello_ary) - expect(Diff::LCS.patch(hello_ary, diff)).to eq(hello_ary) - end - end - - describe "with default diff callbacks (DiffCallbacks)" do - describe "forward (s1 -> s2)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq1 } - let(:s2) { seq2 } - let(:patch_set) { Diff::LCS.diff(seq1, seq2) } - end - end - - describe "reverse (s2 -> s1)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq2 } - let(:s2) { seq1 } - let(:patch_set) { Diff::LCS.diff(seq2, seq1) } - end - end - end - - describe "with context diff callbacks (ContextDiffCallbacks)" do - describe "forward (s1 -> s2)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq1 } - let(:s2) { seq2 } - let(:patch_set) { - Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) - } - end - end - - describe "reverse (s2 -> s1)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq2 } - let(:s2) { seq1 } - let(:patch_set) { - Diff::LCS.diff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) - } - end - end - end - - describe "with sdiff callbacks (SDiffCallbacks)" do - describe "forward (s1 -> s2)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq1 } - let(:s2) { seq2 } - let(:patch_set) { - Diff::LCS.diff(seq1, seq2, Diff::LCS::SDiffCallbacks) - } - end - end - - describe "reverse (s2 -> s1)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq2 } - let(:s2) { seq1 } - let(:patch_set) { - Diff::LCS.diff(seq2, seq1, Diff::LCS::SDiffCallbacks) - } - end - end - end - end - - describe "using a Diff::LCS.sdiff patchset" do - describe "an empty patchset returns the source" do - it "works on a string (hello)" do - expect(Diff::LCS.patch(hello, Diff::LCS.sdiff(hello, hello))).to eq(hello) - end - - it "works on an array %W(h e l l o)" do - expect(Diff::LCS.patch(hello_ary, Diff::LCS.sdiff(hello_ary, hello_ary))).to eq(hello_ary) - end - end - - describe "with default diff callbacks (DiffCallbacks)" do - describe "forward (s1 -> s2)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq1 } - let(:s2) { seq2 } - let(:patch_set) { - Diff::LCS.sdiff(seq1, seq2, Diff::LCS::DiffCallbacks) - } - end - end - - describe "reverse (s2 -> s1)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq2 } - let(:s2) { seq1 } - let(:patch_set) { - Diff::LCS.sdiff(seq2, seq1, Diff::LCS::DiffCallbacks) - } - end - end - end - - describe "with context diff callbacks (DiffCallbacks)" do - describe "forward (s1 -> s2)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq1 } - let(:s2) { seq2 } - let(:patch_set) { - Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) - } - end - end - - describe "reverse (s2 -> s1)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq2 } - let(:s2) { seq1 } - let(:patch_set) { - Diff::LCS.sdiff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) - } - end - end - end - - describe "with sdiff callbacks (SDiffCallbacks)" do - describe "forward (s1 -> s2)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq1 } - let(:s2) { seq2 } - let(:patch_set) { Diff::LCS.sdiff(seq1, seq2) } - end - end - - describe "reverse (s2 -> s1)" do - it_has_behavior "patch sequences correctly" do - let(:s1) { seq2 } - let(:s2) { seq1 } - let(:patch_set) { Diff::LCS.sdiff(seq2, seq1) } - end - end - end - end - - # Note: because of the error in autodiscovery ("does not autodiscover s1 - # to s2 patches"), this cannot use the "patch sequences correctly" shared - # set. Once the bug in autodiscovery is fixed, this can be converted as - # above. - describe "fix bug 891: patchsets do not contain the last equal part" do - before :each do - @s1 = %w[a b c d e f g h i j k] # standard:disable Layout/SpaceInsideArrayPercentLiteral - @s2 = %w[a b c d D e f g h i j k] - end - - describe "using Diff::LCS.diff with default diff callbacks" do - before :each do - @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2) - @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1) - end - - it "autodiscovers s1 to s2 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 the left-to-right patches" do - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) - end - - it "correctly patches left-to-right (explicit patch)" do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) - expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) - expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) - end - - it "correctly patches right-to-left (explicit unpatch)" do - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) - expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) - expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) - end - end - - describe "using Diff::LCS.diff with context diff callbacks" do - before :each do - @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) - @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) - end - - it "autodiscovers s1 to s2 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 the left-to-right patches" do - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) - end - - it "correctly patches left-to-right (explicit patch)" do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) - expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) - expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) - end - - it "correctly patches right-to-left (explicit unpatch)" do - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) - expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) - expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) - end - end - - describe "using Diff::LCS.diff with sdiff callbacks" do - before(:each) do - @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::SDiffCallbacks) - @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::SDiffCallbacks) - end - - it "autodiscovers s1 to s2 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 the left-to-right patches" do - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) - end - - it "correctly patches left-to-right (explicit patch)" do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) - expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) - expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) - end - - it "correctly patches right-to-left (explicit unpatch)" do - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) - expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) - expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) - end - end - - describe "using Diff::LCS.sdiff with default sdiff callbacks" do - before(:each) do - @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2) - @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1) - end - - it "autodiscovers s1 to s2 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 the left-to-right patches" do - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) - end - - it "correctly patches left-to-right (explicit patch)" do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) - expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) - expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) - end - - it "correctly patches right-to-left (explicit unpatch)" do - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) - expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) - expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) - end - end - - describe "using Diff::LCS.sdiff with context diff callbacks" do - before(:each) do - @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) - @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) - end - - it "autodiscovers s1 to s2 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 the left-to-right patches" do - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) - end - - it "correctly patches left-to-right (explicit patch)" do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) - expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) - expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) - end - - it "correctly patches right-to-left (explicit unpatch)" do - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) - expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) - expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) - end - end - - describe "using Diff::LCS.sdiff with default diff callbacks" do - before(:each) do - @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::DiffCallbacks) - @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::DiffCallbacks) - end - - it "autodiscovers s1 to s2 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 patches" do - expect do - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) - end.to_not raise_error - end - - it "autodiscovers s2 to s1 the left-to-right patches" do - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) - end - - it "correctly patches left-to-right (explicit patch)" do - expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) - expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) - expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) - expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) - end - - it "correctly patches right-to-left (explicit unpatch)" do - expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) - expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) - expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) - expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb deleted file mode 100644 index aded301..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb +++ /dev/null @@ -1,216 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Diff::LCS.sdiff" do - include Diff::LCS::SpecHelper::Matchers - - shared_examples "compare sequences correctly" do - it "compares s1 -> s2 correctly" do - expect(Diff::LCS.sdiff(s1, s2)).to eq(context_diff(result)) - end - - it "compares s2 -> s1 correctly" do - expect(Diff::LCS.sdiff(s2, s1)).to eq(context_diff(reverse_sdiff(result))) - end - end - - describe "using seq1 & seq2" do - let(:s1) { seq1 } - let(:s2) { seq2 } - let(:result) { correct_forward_sdiff } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(abc def yyy xxx ghi jkl) & %w(abc dxf xxx ghi jkl)" do - let(:s1) { %w[abc def yyy xxx ghi jkl] } - let(:s2) { %w[abc dxf xxx ghi jkl] } - let(:result) { - # standard:disable Layout/ExtraSpacing - [ - ["=", [0, "abc"], [0, "abc"]], - ["!", [1, "def"], [1, "dxf"]], - ["-", [2, "yyy"], [2, nil]], - ["=", [3, "xxx"], [2, "xxx"]], - ["=", [4, "ghi"], [3, "ghi"]], - ["=", [5, "jkl"], [4, "jkl"]] - ] - # standard:enable Layout/ExtraSpacing - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(a b c d e) & %w(a e)" do - let(:s1) { %w[a b c d e] } - let(:s2) { %w[a e] } - let(:result) { - [ - ["=", [0, "a"], [0, "a"]], - ["-", [1, "b"], [1, nil]], - ["-", [2, "c"], [1, nil]], - ["-", [3, "d"], [1, nil]], - ["=", [4, "e"], [1, "e"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(a e) & %w(a b c d e)" do - let(:s1) { %w[a e] } - let(:s2) { %w[a b c d e] } - let(:result) { - [ - ["=", [0, "a"], [0, "a"]], - ["+", [1, nil], [1, "b"]], - ["+", [1, nil], [2, "c"]], - ["+", [1, nil], [3, "d"]], - ["=", [1, "e"], [4, "e"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(v x a e) & %w(w y a b c d e)" do - let(:s1) { %w[v x a e] } - let(:s2) { %w[w y a b c d e] } - let(:result) { - [ - ["!", [0, "v"], [0, "w"]], - ["!", [1, "x"], [1, "y"]], - ["=", [2, "a"], [2, "a"]], - ["+", [3, nil], [3, "b"]], - ["+", [3, nil], [4, "c"]], - ["+", [3, nil], [5, "d"]], - ["=", [3, "e"], [6, "e"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(x a e) & %w(a b c d e)" do - let(:s1) { %w[x a e] } - let(:s2) { %w[a b c d e] } - let(:result) { - [ - ["-", [0, "x"], [0, nil]], - ["=", [1, "a"], [0, "a"]], - ["+", [2, nil], [1, "b"]], - ["+", [2, nil], [2, "c"]], - ["+", [2, nil], [3, "d"]], - ["=", [2, "e"], [4, "e"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(a e) & %w(x a b c d e)" do - let(:s1) { %w[a e] } - let(:s2) { %w[x a b c d e] } - let(:result) { - [ - ["+", [0, nil], [0, "x"]], - ["=", [0, "a"], [1, "a"]], - ["+", [1, nil], [2, "b"]], - ["+", [1, nil], [3, "c"]], - ["+", [1, nil], [4, "d"]], - ["=", [1, "e"], [5, "e"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(a e v) & %w(x a b c d e w x)" do - let(:s1) { %w[a e v] } - let(:s2) { %w[x a b c d e w x] } - let(:result) { - [ - ["+", [0, nil], [0, "x"]], - ["=", [0, "a"], [1, "a"]], - ["+", [1, nil], [2, "b"]], - ["+", [1, nil], [3, "c"]], - ["+", [1, nil], [4, "d"]], - ["=", [1, "e"], [5, "e"]], - ["!", [2, "v"], [6, "w"]], - ["+", [3, nil], [7, "x"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w() & %w(a b c)" do - let(:s1) { %w[] } - let(:s2) { %w[a b c] } - let(:result) { - [ - ["+", [0, nil], [0, "a"]], - ["+", [0, nil], [1, "b"]], - ["+", [0, nil], [2, "c"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(a b c) & %w(1)" do - let(:s1) { %w[a b c] } - let(:s2) { %w[1] } - let(:result) { - [ - ["!", [0, "a"], [0, "1"]], - ["-", [1, "b"], [1, nil]], - ["-", [2, "c"], [1, nil]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(a b c) & %w(c)" do - let(:s1) { %w[a b c] } - let(:s2) { %w[c] } - let(:result) { - [ - ["-", [0, "a"], [0, nil]], - ["-", [1, "b"], [0, nil]], - ["=", [2, "c"], [0, "c"]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using %w(abcd efgh ijkl mnop) & []" do - let(:s1) { %w[abcd efgh ijkl mnop] } - let(:s2) { [] } - let(:result) { - [ - ["-", [0, "abcd"], [0, nil]], - ["-", [1, "efgh"], [0, nil]], - ["-", [2, "ijkl"], [0, nil]], - ["-", [3, "mnop"], [0, nil]] - ] - } - - it_has_behavior "compare sequences correctly" - end - - describe "using [[1,2]] & []" do - let(:s1) { [[1, 2]] } - let(:s2) { [] } - let(:result) { - [ - ["-", [0, [1, 2]], [0, nil]] - ] - } - - it_has_behavior "compare sequences correctly" - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb deleted file mode 100644 index baaa3d0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb +++ /dev/null @@ -1,376 +0,0 @@ -# frozen_string_literal: true - -require "rubygems" -require "pathname" - -require "psych" if RUBY_VERSION >= "1.9" - -if ENV["COVERAGE"] - require "simplecov" - require "simplecov-lcov" - - SimpleCov::Formatter::LcovFormatter.config do |config| - config.report_with_single_file = true - config.lcov_file_name = "lcov.info" - end - - SimpleCov.start "test_frameworks" do - enable_coverage :branch - primary_coverage :branch - formatter SimpleCov::Formatter::MultiFormatter.new([ - SimpleCov::Formatter::HTMLFormatter, - SimpleCov::Formatter::LcovFormatter, - SimpleCov::Formatter::SimpleFormatter - ]) - end -end - -file = Pathname.new(__FILE__).expand_path -path = file.parent -parent = path.parent - -$:.unshift parent.join("lib") - -module CaptureSubprocessIO - def _synchronize - yield - end - - def capture_subprocess_io - _synchronize { _capture_subprocess_io { yield } } - end - - def _capture_subprocess_io - require "tempfile" - - captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err") - - orig_stdout, orig_stderr = $stdout.dup, $stderr.dup - $stdout.reopen captured_stdout - $stderr.reopen captured_stderr - - yield - - $stdout.rewind - $stderr.rewind - - [captured_stdout.read, captured_stderr.read] - ensure - captured_stdout.unlink - captured_stderr.unlink - $stdout.reopen orig_stdout - $stderr.reopen orig_stderr - end - private :_capture_subprocess_io -end - -require "diff-lcs" - -module Diff::LCS::SpecHelper - def hello - "hello" - end - - def hello_ary - %w[h e l l o] - end - - def seq1 - %w[a b c e h j l m n p] - end - - def skipped_seq1 - %w[a h n p] - end - - def seq2 - %w[b c d e f j k l m r s t] - end - - def skipped_seq2 - %w[d f k r s t] - end - - def word_sequence - %w[abcd efgh ijkl mnopqrstuvwxyz] - end - - def correct_lcs - %w[b c e j l m] - end - - # standard:disable Layout/ExtraSpacing - def correct_forward_diff - [ - [ - ["-", 0, "a"] - ], - [ - ["+", 2, "d"] - ], - [ - ["-", 4, "h"], - ["+", 4, "f"] - ], - [ - ["+", 6, "k"] - ], - [ - ["-", 8, "n"], - ["+", 9, "r"], - ["-", 9, "p"], - ["+", 10, "s"], - ["+", 11, "t"] - ] - ] - end - - def correct_backward_diff - [ - [ - ["+", 0, "a"] - ], - [ - ["-", 2, "d"] - ], - [ - ["-", 4, "f"], - ["+", 4, "h"] - ], - [ - ["-", 6, "k"] - ], - [ - ["-", 9, "r"], - ["+", 8, "n"], - ["-", 10, "s"], - ["+", 9, "p"], - ["-", 11, "t"] - ] - ] - end - - def correct_forward_sdiff - [ - ["-", [0, "a"], [0, nil]], - ["=", [1, "b"], [0, "b"]], - ["=", [2, "c"], [1, "c"]], - ["+", [3, nil], [2, "d"]], - ["=", [3, "e"], [3, "e"]], - ["!", [4, "h"], [4, "f"]], - ["=", [5, "j"], [5, "j"]], - ["+", [6, nil], [6, "k"]], - ["=", [6, "l"], [7, "l"]], - ["=", [7, "m"], [8, "m"]], - ["!", [8, "n"], [9, "r"]], - ["!", [9, "p"], [10, "s"]], - ["+", [10, nil], [11, "t"]] - ] - end - # standard:enable Layout/ExtraSpacing - - def reverse_sdiff(forward_sdiff) - forward_sdiff.map { |line| - line[1], line[2] = line[2], line[1] - case line[0] - when "-" then line[0] = "+" - when "+" then line[0] = "-" - end - line - } - end - - def change_diff(diff) - map_diffs(diff, Diff::LCS::Change) - end - - def context_diff(diff) - map_diffs(diff, Diff::LCS::ContextChange) - end - - def format_diffs(diffs) - diffs.map { |e| - if e.is_a?(Array) - e.map { |f| f.to_a.join }.join(", ") - else - e.to_a.join - end - }.join("\n") - end - - def map_diffs(diffs, klass = Diff::LCS::ContextChange) - diffs.map do |chunks| - if klass == Diff::LCS::ContextChange - klass.from_a(chunks) - else - chunks.map { |changes| klass.from_a(changes) } - end - end - end - - def balanced_traversal(s1, s2, callback_type) - callback = __send__(callback_type) - Diff::LCS.traverse_balanced(s1, s2, callback) - callback - end - - def balanced_reverse(change_result) - new_result = [] - change_result.each do |line| - line = [line[0], line[2], line[1]] - case line[0] - when "<" - line[0] = ">" - when ">" - line[0] = "<" - end - new_result << line - end - new_result.sort_by { |line| [line[1], line[2]] } - end - - def map_to_no_change(change_result) - new_result = [] - change_result.each do |line| - case line[0] - when "!" - new_result << ["<", line[1], line[2]] - new_result << [">", line[1] + 1, line[2]] - else - new_result << line - end - end - new_result - end - - class SimpleCallback - def initialize - reset - end - - attr_reader :matched_a - attr_reader :matched_b - attr_reader :discards_a - attr_reader :discards_b - attr_reader :done_a - attr_reader :done_b - - def reset - @matched_a = [] - @matched_b = [] - @discards_a = [] - @discards_b = [] - @done_a = [] - @done_b = [] - self - end - - def match(event) - @matched_a << event.old_element - @matched_b << event.new_element - end - - def discard_b(event) - @discards_b << event.new_element - end - - def discard_a(event) - @discards_a << event.old_element - end - - def finished_a(event) - @done_a << [ - event.old_element, event.old_position, - event.new_element, event.new_position - ] - end - - def finished_b(event) - @done_b << [ - event.old_element, event.old_position, - event.new_element, event.new_position - ] - end - end - - def simple_callback - SimpleCallback.new - end - - class SimpleCallbackNoFinishers < SimpleCallback - undef :finished_a - undef :finished_b - end - - def simple_callback_no_finishers - SimpleCallbackNoFinishers.new - end - - class BalancedCallback - def initialize - reset - end - - attr_reader :result - - def reset - @result = [] - end - - def match(event) - @result << ["=", event.old_position, event.new_position] - end - - def discard_a(event) - @result << ["<", event.old_position, event.new_position] - end - - def discard_b(event) - @result << [">", event.old_position, event.new_position] - end - - def change(event) - @result << ["!", event.old_position, event.new_position] - end - end - - def balanced_callback - BalancedCallback.new - end - - class BalancedCallbackNoChange < BalancedCallback - undef :change - end - - def balanced_callback_no_change - BalancedCallbackNoChange.new - end - - module Matchers - extend RSpec::Matchers::DSL - - matcher :be_nil_or_match_values do |ii, s1, s2| - match do |ee| - expect(ee).to(satisfy { |vee| vee.nil? || s1[ii] == s2[ee] }) - end - end - - matcher :correctly_map_sequence do |s1| - match do |actual| - actual.each_index { |ii| expect(actual[ii]).to be_nil_or_match_values(ii, s1, @s2) } - end - - chain :to_other_sequence do |s2| - @s2 = s2 - end - end - end -end - -RSpec.configure do |conf| - conf.include Diff::LCS::SpecHelper - conf.alias_it_should_behave_like_to :it_has_behavior, "has behavior:" - # standard:disable Style/HashSyntax - conf.filter_run_excluding :broken => true - # standard:enable Style/HashSyntax -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb deleted file mode 100644 index 3a3f677..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb +++ /dev/null @@ -1,312 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Diff::LCS.traverse_balanced" do - include Diff::LCS::SpecHelper::Matchers - - shared_examples "with a #change callback" do |s1, s2, result| - it "traverses s1 -> s2 correctly" do - traversal = balanced_traversal(s1, s2, :balanced_callback) - expect(traversal.result).to eq(result) - end - - it "traverses s2 -> s1 correctly" do - traversal = balanced_traversal(s2, s1, :balanced_callback) - expect(traversal.result).to eq(balanced_reverse(result)) - end - end - - shared_examples "without a #change callback" do |s1, s2, result| - it "traverses s1 -> s2 correctly" do - traversal = balanced_traversal(s1, s2, :balanced_callback_no_change) - expect(traversal.result).to eq(map_to_no_change(result)) - end - - it "traverses s2 -> s1 correctly" do - traversal = balanced_traversal(s2, s1, :balanced_callback_no_change) - expect(traversal.result).to eq(map_to_no_change(balanced_reverse(result))) - end - end - - describe "identical string sequences ('abc')" do - s1 = s2 = "abc" - - result = [ - ["=", 0, 0], - ["=", 1, 1], - ["=", 2, 2] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "identical array sequences %w(a b c)" do - s1 = s2 = %w[a b c] - - result = [ - ["=", 0, 0], - ["=", 1, 1], - ["=", 2, 2] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(a b c) & %w(a x c)" do - s1 = %w[a b c] - s2 = %w[a x c] - - result = [ - ["=", 0, 0], - ["!", 1, 1], - ["=", 2, 2] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(a x y c) & %w(a v w c)" do - s1 = %w[a x y c] - s2 = %w[a v w c] - - result = [ - ["=", 0, 0], - ["!", 1, 1], - ["!", 2, 2], - ["=", 3, 3] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(x y c) & %w(v w c)" do - s1 = %w[x y c] - s2 = %w[v w c] - result = [ - ["!", 0, 0], - ["!", 1, 1], - ["=", 2, 2] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(a x y z) & %w(b v w)" do - s1 = %w[a x y z] - s2 = %w[b v w] - result = [ - ["!", 0, 0], - ["!", 1, 1], - ["!", 2, 2], - ["<", 3, 3] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(a z) & %w(a)" do - s1 = %w[a z] - s2 = %w[a] - result = [ - ["=", 0, 0], - ["<", 1, 1] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(z a) & %w(a)" do - s1 = %w[z a] - s2 = %w[a] - result = [ - ["<", 0, 0], - ["=", 1, 0] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(a b c) & %w(x y z)" do - s1 = %w[a b c] - s2 = %w[x y z] - result = [ - ["!", 0, 0], - ["!", 1, 1], - ["!", 2, 2] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "sequences %w(abcd efgh ijkl mnoopqrstuvwxyz) & []" do - s1 = %w[abcd efgh ijkl mnopqrstuvwxyz] - s2 = [] - result = [ - ["<", 0, 0], - ["<", 1, 0], - ["<", 2, 0], - ["<", 3, 0] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(a b c) & %q(a x c)" do - s1 = "a b c" - s2 = "a x c" - - result = [ - ["=", 0, 0], - ["=", 1, 1], - ["!", 2, 2], - ["=", 3, 3], - ["=", 4, 4] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(a x y c) & %q(a v w c)" do - s1 = "a x y c" - s2 = "a v w c" - - result = [ - ["=", 0, 0], - ["=", 1, 1], - ["!", 2, 2], - ["=", 3, 3], - ["!", 4, 4], - ["=", 5, 5], - ["=", 6, 6] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(x y c) & %q(v w c)" do - s1 = "x y c" - s2 = "v w c" - result = [ - ["!", 0, 0], - ["=", 1, 1], - ["!", 2, 2], - ["=", 3, 3], - ["=", 4, 4] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(a x y z) & %q(b v w)" do - s1 = "a x y z" - s2 = "b v w" - result = [ - ["!", 0, 0], - ["=", 1, 1], - ["!", 2, 2], - ["=", 3, 3], - ["!", 4, 4], - ["<", 5, 5], - ["<", 6, 5] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(a z) & %q(a)" do - s1 = "a z" - s2 = "a" - result = [ - ["=", 0, 0], - ["<", 1, 1], - ["<", 2, 1] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(z a) & %q(a)" do - s1 = "z a" - s2 = "a" - result = [ - ["<", 0, 0], - ["<", 1, 0], - ["=", 2, 0] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(a b c) & %q(x y z)" do - s1 = "a b c" - s2 = "x y z" - result = [ - ["!", 0, 0], - ["=", 1, 1], - ["!", 2, 2], - ["=", 3, 3], - ["!", 4, 4] - ] - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end - - describe "strings %q(abcd efgh ijkl mnopqrstuvwxyz) & %q()" do - s1 = "abcd efgh ijkl mnopqrstuvwxyz" - s2 = "" - # standard:disable Layout/ExtraSpacing - result = [ - ["<", 0, 0], - ["<", 1, 0], - ["<", 2, 0], - ["<", 3, 0], - ["<", 4, 0], - ["<", 5, 0], - ["<", 6, 0], - ["<", 7, 0], - ["<", 8, 0], - ["<", 9, 0], - ["<", 10, 0], - ["<", 11, 0], - ["<", 12, 0], - ["<", 13, 0], - ["<", 14, 0], - ["<", 15, 0], - ["<", 16, 0], - ["<", 17, 0], - ["<", 18, 0], - ["<", 19, 0], - ["<", 20, 0], - ["<", 21, 0], - ["<", 22, 0], - ["<", 23, 0], - ["<", 24, 0], - ["<", 25, 0], - ["<", 26, 0], - ["<", 27, 0], - ["<", 28, 0] - ] - # standard:enable Layout/ExtraSpacing - - it_has_behavior "with a #change callback", s1, s2, result - it_has_behavior "without a #change callback", s1, s2, result - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb deleted file mode 100644 index 8e9928f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb +++ /dev/null @@ -1,137 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Diff::LCS.traverse_sequences" do - describe "callback with no finishers" do - describe "over (seq1, seq2)" do - before(:each) do - @callback_s1_s2 = simple_callback_no_finishers - Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) - - @callback_s2_s1 = simple_callback_no_finishers - Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) - end - - it "has the correct LCS result on left-matches" do - expect(@callback_s1_s2.matched_a).to eq(correct_lcs) - expect(@callback_s2_s1.matched_a).to eq(correct_lcs) - end - - it "has the correct LCS result on right-matches" do - expect(@callback_s1_s2.matched_b).to eq(correct_lcs) - expect(@callback_s2_s1.matched_b).to eq(correct_lcs) - end - - it "has the correct skipped sequences with the left sequence" do - expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) - expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) - end - - it "has the correct skipped sequences with the right sequence" do - expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) - expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) - end - - it "does not have anything done markers from the left or right sequences" do - expect(@callback_s1_s2.done_a).to be_empty - expect(@callback_s1_s2.done_b).to be_empty - expect(@callback_s2_s1.done_a).to be_empty - expect(@callback_s2_s1.done_b).to be_empty - end - end - - describe "over (hello, hello)" do - before(:each) do - @callback = simple_callback_no_finishers - Diff::LCS.traverse_sequences(hello, hello, @callback) - end - - it "has the correct LCS result on left-matches" do - expect(@callback.matched_a).to eq(hello.chars) - end - - it "has the correct LCS result on right-matches" do - expect(@callback.matched_b).to eq(hello.chars) - end - - it "has the correct skipped sequences with the left sequence" do - expect(@callback.discards_a).to be_empty - end - - it "has the correct skipped sequences with the right sequence" do - expect(@callback.discards_b).to be_empty - end - - it "does not have anything done markers from the left or right sequences" do - expect(@callback.done_a).to be_empty - expect(@callback.done_b).to be_empty - end - end - - describe "over (hello_ary, hello_ary)" do - before(:each) do - @callback = simple_callback_no_finishers - Diff::LCS.traverse_sequences(hello_ary, hello_ary, @callback) - end - - it "has the correct LCS result on left-matches" do - expect(@callback.matched_a).to eq(hello_ary) - end - - it "has the correct LCS result on right-matches" do - expect(@callback.matched_b).to eq(hello_ary) - end - - it "has the correct skipped sequences with the left sequence" do - expect(@callback.discards_a).to be_empty - end - - it "has the correct skipped sequences with the right sequence" do - expect(@callback.discards_b).to be_empty - end - - it "does not have anything done markers from the left or right sequences" do - expect(@callback.done_a).to be_empty - expect(@callback.done_b).to be_empty - end - end - end - - describe "callback with finisher" do - before(:each) do - @callback_s1_s2 = simple_callback - Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) - @callback_s2_s1 = simple_callback - Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) - end - - it "has the correct LCS result on left-matches" do - expect(@callback_s1_s2.matched_a).to eq(correct_lcs) - expect(@callback_s2_s1.matched_a).to eq(correct_lcs) - end - - it "has the correct LCS result on right-matches" do - expect(@callback_s1_s2.matched_b).to eq(correct_lcs) - expect(@callback_s2_s1.matched_b).to eq(correct_lcs) - end - - it "has the correct skipped sequences for the left sequence" do - expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) - expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) - end - - it "has the correct skipped sequences for the right sequence" do - expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) - expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) - end - - it "has done markers differently-sized sequences" do - expect(@callback_s1_s2.done_a).to eq([["p", 9, "t", 11]]) - expect(@callback_s1_s2.done_b).to be_empty - - expect(@callback_s2_s1.done_a).to be_empty - expect(@callback_s2_s1.done_b).to eq([["t", 11, "p", 9]]) - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc deleted file mode 100644 index 51e9f71..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/History.rdoc +++ /dev/null @@ -1,2454 +0,0 @@ -=== 13.2.1 - -* Suppressed "internal:array:52:in 'Array#each'" from backtrace by @hsbt in #554 -* Bump actions/configure-pages from 4 to 5 by @dependabot in #553 - -=== 13.2.0 - -* Fix rule example to be correct by @zenspider in #525 -* Switch to use test-unit by @hsbt in #536 -* Removed redundant block by @hsbt in #537 -* Use Struct instead of OpenStruct. by @hsbt in #545 -* Accept FileList object as directory task's target by @gemmaro in #530 -* Fix exception when exception has nil backtrace by @janbiedermann in #451 -* Add TruffleRuby on CI by @andrykonchin in #551 - -=== 13.1.0 - -* Added dependabot.yml for actions by @hsbt in #416 -* Add Ruby 3.1 to the CI matrix by @petergoldstein in #415 -* (Performance) Remove unnecessary I/O syscalls for FileTasks by @da2x in #393 -* Skip test failure with JRuby by @hsbt in #418 -* Remove bin/rdoc by @tnir in #421 -* Remove bin/rake by @tnir in #422 -* Remove bin/bundle by @tnir in #425 -* Apply RuboCop linting for Ruby 2.3 by @tnir in #423 -* Update rubocop to work with Ruby 2.4 compatible by @tnir in #424 -* chore: fix typo in comments by @tnir in #429 -* Use 'test' as workflow name on Actions by @tnir in #427 -* docs: update CONTRIBUTING.rdoc by @tnir in #428 -* Add RuboCop job to Actions by @tnir in #426 -* Lock minitest-5.15.0 for Ruby 2.2 by @hsbt in #442 -* Eagerly require set in thread_pool.rb by @jeremyevans in #440 -* Avoid creating an unnecessary thread pool by @jeremyevans in #441 -* Add credit for maintenance in Rake 12/13 by @tnir in #443 -* Sh fully echoes commands which error exit by @MarkDBlackwell in #147 -* Correct RuboCop offenses by @deivid-rodriguez in #444 -* [StepSecurity] ci: Harden GitHub Actions by @step-security-bot in #450 -* Add ruby 3.2 to test matrix by @hanneskaeufler in #458 -* Missing 'do' on example by @zzak in #467 -* Try to use dependabot automerge by @hsbt in #470 -* Rewrite auto-merge feature for dependabot by @hsbt in #471 -* Update bundler in Dependabot by @ono-max in #472 -* Fix grammar in help text by @mebezac in #381 -* Try to use ruby/ruby/.github/workflows/ruby_versions.yml@master by @hsbt in #475 -* Use GitHub Pages Action for generating rdoc page by @hsbt in #477 -* Support #detailed_message when task failed by @ksss in #486 -* Debug at stop when task fail by @ksss in #489 -* Drop to support Ruby 2.2 by @hsbt in #492 -* Bump up setup-ruby by @hsbt in #497 -* Update development dependencies by @hsbt in #505 - -=== 13.0.6 - -* Additional fix for #389 - Pull request #390 by hsbt - -=== 13.0.5 - -* Fixed the regression of #388 - Pull request #389 by hsbt - -=== 13.0.4 - -* Fix rake test loader swallowing useful error information. - Pull request #367 by deivid-rodriguez -* Add -C/--directory option the same as GNU make. - Pull request #376 by nobu - -=== 13.0.3 - -* Fix breaking change of execution order on TestTask. - Pull request #368 by ysakasin - -=== 13.0.2 - -==== Enhancements - -* Fix tests to work with current FileUtils - Pull Request #358 by jeremyevans -* Simplify default rake test loader - Pull Request #357 by deivid-rodriguez -* Update rdoc - Pull Request #366 by bahasalien -* Update broken links to rake articles from Avdi in README - Pull Request #360 by svl7 - -=== 13.0.1 - -==== Bug fixes - -* Fixed bug: Reenabled task raises previous exception on second invokation - Pull Request #271 by thorsteneckel -* Fix an incorrectly resolved arg pattern - Pull Request #327 by mjbellantoni - -=== 13.0.0 - -==== Enhancements - -* Follows recent changes on keyword arguments in ruby 2.7. - Pull Request #326 by nobu -* Make `PackageTask` be able to omit parent directory while packing files - Pull Request #310 by tonytonyjan -* Add order only dependency - Pull Request #269 by take-cheeze - -==== Compatibility changes - -* Drop old ruby versions(< 2.2) - -=== 12.3.3 - -==== Bug fixes - -* Use the application's name in error message if a task is not found. - Pull Request #303 by tmatilai - -==== Enhancements: - -* Use File.open explicitly. - -=== 12.3.2 - -==== Bug fixes - -* Fixed test fails caused by 2.6 warnings. - Pull Request #297 by hsbt - -==== Enhancements: - -* Rdoc improvements. - Pull Request #293 by colby-swandale -* Improve multitask performance. - Pull Request #273 by jsm -* Add alias `prereqs`. - Pull Request #268 by take-cheeze - -=== 12.3.1 - -==== Bug fixes - -* Support did_you_mean >= v1.2.0 which has a breaking change on formatters. - Pull request #262 by FUJI Goro. - -==== Enhancements: - -* Don't run task if it depends on already invoked but failed task. - Pull request #252 by Gonzalo Rodriguez. -* Make space trimming consistent for all task arguments. - Pull request #259 by Gonzalo Rodriguez. -* Removes duplicated inclusion of Rake::DSL in tests. - Pull request #254 by Gonzalo Rodriguez. -* Re-raise a LoadError that didn't come from require in the test loader. - Pull request #250 by Dylan Thacker-Smith. - -=== 12.3.0 - -==== Compatibility Changes - -* Bump `required_ruby_version` to Ruby 2.0.0. Rake has already - removed support for Ruby 1.9.x. - -==== Enhancements: - -* Support `test-bundled-gems` task on ruby core. - -=== 12.2.1 - -==== Bug fixes - -* Fixed to break Capistrano::Application on capistrano3. - -=== 12.2.0 - -==== Enhancements: - -* Make rake easier to use as a library - Pull request #211 by @drbrain -* Fix quadratic performance in FileTask#out_of_date? - Pull request #224 by @doudou -* Clarify output when printing nested exception traces - Pull request #232 by @urbanautomaton - -==== Bug fixes - -* Account for a file that match 2 or more patterns. - Pull request #231 by @styd - -=== 12.1.0 - -==== Enhancements: - -* Added did_you_mean feature for invalid rake task. - Pull request #221 by @xtina-starr -* Enabled to dependency chained by extensions. Pull request #39 by Petr Skocik. -* Make all of string literals to frozen objects on Ruby 2.4 or later. - -==== Bug fixes - -* Typo fixes in rakefile.rdoc. Pull request #180 by Yuta Kurotaki. -* Fix unexpected behavior of file task with dryrun option. - Pull request #183 by @aycabta. -* Make LoadError from running tests more obvious. Pull request #195 - by Eric Hodel. -* Fix unexpected TypeError with hash style option. Pull request #202 - by Kuniaki IGARASHI. - -=== 12.0.0 - -==== Compatibility Changes - -* Removed arguments on clear #157 by Jesse Bowes -* Removed `rake/contrib` packages. These are extracted to `rake-contrib` gem. -* Removed deprecated method named `last\_comment`. - -==== Enhancements: - -* Re-use trace option on `cleanup` task. #164 by Brian Henderson -* Actions adore keyword arguments #174 by Josh Cheek -* Rake::TaskArguments#key? alias of #has_key? #175 by Paul Annesley - -=== 11.3.0 / 2016-09-20 - -==== Enhancements: - -* Remove to reference `Fixnum` constant. Pull request #160 by nobu - -=== 11.2.2 / 2016-06-12 - -==== Bug fixes - -* Fix unexpected behavior with multiple dependencies on Rake::TestTask - -=== 11.2.1 / 2016-06-12 - -==== Bug fixes - -* Fix regression of dependencies handling on Rake::TestTask. Report #139 - -=== 11.2.0 / 2016-06-11 - -==== Bug fixes - -* Fix unexpected cut-out behavior on task description using triple dots - and exclamation. Report #106 from Stephan Kämper and Pull request #134 by Lee -* Fix empty argument assignment with `with_defaults` option. Pull request #135 - by bakunyo -* Ignore to use `hwprefs` on Darwin platform. Use sysctl now. Report #128 - -==== Enhancements - -* Spawn options for sh Pull equest #138 by Eric Hodel. -* Allow to specify dependencies(prerequisites) for Rake::TestTask - Pull request #117 by Tim Maslyuchenko -* Use Bundler task instead of hoe for gem release. -* Remove explicitly load to rubygems for Ruby 1.8. -* Unify to declare `Rake::VERSION`. -* Support xz format for PackageTask. - -=== 11.1.2 / 2016-03-28 - -==== Bug fixes - -* Remove `-W` option when Rake::TestTask#verbose enabled. It's misunderstanding - specification change with Rake 11. Partly revert #67 - -=== 11.1.1 / 2016-03-14 - -==== Bug fixes - -* Use `-W` instead of `--verbose` when Rake::TestTask#verbose enabled. - JRuby doesn't have `--verbose` option. - -=== 11.1.0 / 2016-03-11 - -==== Compatibility Changes - -* Revert to remove `last\_comment`. It will remove Rake 12. - -=== 11.0.1 / 2016-03-09 - -==== Bug fixes - -* Fixed packaging manifest. - -=== 11.0.0 / 2016-03-09 - -==== Bug fixes - -* Correctly handle bad encoding in exception messages. Pull request #113 - by Tomer Brisker -* Fix verbose option at TestTask. Pull request #67 by Mike Blumtritt - -==== Enhancements - -* Make FileList#exclude more analogous to FileList#include. -* Use IO.open instead of Open3.popen3 for CPU counter. -* Make Rake::Task#already_invoked publicly accessible. - Pull request #93 by Joe Rafaniello -* Lookup prerequisites with same name outside of scope instead of - matching self. Pull request #96 by Sandy Vanderbleek -* Make FileList#pathmap behave like String#pathmap. - Pull request #61 by Daniel Tamai -* Add fetch method to task arguments. - Pull request #12 by Chris Keathley -* Use ruby warnings by default. Pull request #97 by Harold Giménez - -==== Compatibility Changes - -* Removed to support Ruby 1.8.x -* Removed constant named `RAKEVERSION` -* Removed Rake::AltSystem -* Removed Rake::RubyForgePublisher -* Removed Rake::TaskManager#last\_comment. Use last\_description. -* Removed Rake::TaskLib#paste -* Removed Top-level SshDirPublisher, SshFreshDirPublisher, SshFilePublisher - and CompositePublisher from lib/rake/contrib/publisher.rb -* Removed "rake/runtest.rb" - -=== 10.5.0 / 2016-01-13 - -==== Enhancements - -* Removed monkey patching for Ruby 1.8. Pull request #46 by Pablo Herrero. -* Inheritance class of Rake::FileList returns always self class. - Pull request #74 by Thomas Scholz - -=== 10.4.2 / 2014-12-02 - -==== Bug fixes - -* Rake no longer edits ARGV. This allows you to re-exec rake from a rake - task. Pull requset #9 by Matt Palmer. -* Documented how Rake::DSL#desc handles sentences in task descriptions. - Issue #7 by Raza Sayed. -* Fixed test error on 1.9.3 with legacy RubyGems. Issue #8 by Matt Palmer. -* Deleted duplicated History entry. Pull request #10 by Yuji Yamamoto. - -=== 10.4.1 / 2014-12-01 - -==== Bug fixes - -* Reverted fix for #277 as it caused numerous issues for rake users. - rails/spring issue #366 by Gustavo Dutra. - -=== 10.4.0 / 2014-11-22 - -==== Enhancements - -* Upgraded to minitest 5. Pull request #292 by Teo Ljungberg. -* Added support for Pathname in rake tasks. Pull request #271 by Randy - Coulman. -* Rake now ignores falsy dependencies which allows for easier programmatic - creation of tasks. Pull request #273 by Manav. -* Rake no longer edits ARGV. This allows you to re-exec rake from a rake - task. Issue #277 by Matt Palmer. -* Etc.nprocessors is used for counting the number of CPUs. - -==== Bug fixes - -* Updated rake manpage. Issue #283 by Nathan Long, pull request #291 by - skittleys. -* Add Rake::LATE to allow rebuilding of files that depend on deleted files. - Bug #286, pull request #287 by David Grayson. -* Fix relinking of files when repackaging. Bug #276 by Muenze. -* Fixed some typos. Pull request #280 by Jed Northridge. -* Try counting CPUs via cpuinfo if host_os was not matched. Pull request - #282 by Edouard B. - -=== 10.3.2 / 2014-05-15 - -==== Bug fixes - -* Rake no longer infinitely loops when showing exception causes that refer to - each other. Bug #272 by Chris Bandy. -* Fixed documentation typos. Bug #275 by Jake Worth. - -=== 10.3.1 / 2014-04-17 - -==== Bug fixes - -* Really stop reporting an error when cleaning already-deleted files. Pull - request #269 by Randy Coulman -* Fixed infinite loop when cleaning already-deleted files on windows. - -=== 10.3 / 2014-04-15 - -==== Enhancements - -* Added --build-all option to rake which treats all file prerequisites as - out-of-date. Pull request #254 by Andrew Gilbert. -* Added Rake::NameSpace#scope. Issue #263 by Jon San Miguel. - -==== Bug fixes - -* Suppress org.jruby package files in rake error messages for JRuby users. - Issue #213 by Charles Nutter. -* Fixed typo, removed extra "h". Pull request #267 by Hsing-Hui Hsu. -* Rake no longer reports an error when cleaning already-deleted files. Pull - request #266 by Randy Coulman. -* Consume stderr while determining CPU count to avoid hang. Issue #268 by - Albert Sun. - -=== 10.2.2 / 2014-03-27 - -==== Bug fixes - -* Restored Ruby 1.8.7 compatibility - -=== 10.2.1 / 2014-03-25 - -==== Bug fixes - -* File tasks including a ':' are now top-level tasks again. Issue #262 by - Josh Holtrop. -* Use sysctl for CPU count for all BSDs. Pull request #261 by Joshua Stein. -* Fixed CPU detection for unknown platforms. - -=== 10.2.0 / 2014-03-24 - -==== Enhancements - -* Rake now requires Ruby 1.9 or newer. For me, this is a breaking change, but - it seems that Jim planned to release it with Rake 10.2. See also pull - request #247 by Philip Arndt. -* Rake now allows you to declare tasks under a namespace like: - - task 'a:b' do ... end - - Pull request #232 by Judson Lester. -* Task#source defaults to the first prerequisite in non-rule tasks. Pull - request #215 by Avdi Grimm. -* Rake now automatically rebuilds and reloads imported files. Pull request - #209 by Randy Coulman. -* The rake task arguments can contain escaped commas. Pull request #214 by - Filip Hrbek. -* Rake now prints the exception class on errors. Patch #251 by David Cornu. - -==== Bug fixes - -* Fixed typos. Pull request #256 by Valera Rozuvan, #250 via Jake Worth, #260 - by Zachary Scott. -* Fixed documentation for calling tasks with arguments. Pull request #235 by - John Varghese. -* Clarified `rake -f` usage message. Pull request #252 by Marco Pfatschbacher. -* Fixed a test failure on windows. Pull request #231 by Hiroshi Shirosaki. -* Fixed corrupted rake.1.gz. Pull request #225 by Michel Boaventura. -* Fixed bug in can\_detect\_signals? in test. Patch from #243 by Alexey - Borzenkov. - -=== 10.1.1 - -* Use http://github.com/jimweirich/rake instead of http://rake.rubyforge.org for - canonical project url. - -=== 10.1.0 - -==== Changes - -===== New Features - -* Add support for variable length task argument lists. If more actual - arguments are supplied than named arguments, then the extra - arguments values will be in args.extras. - -* Application name is not displayed in the help banner. (Previously - "rake" was hardcoded, now rake-based applications can display their - own names). - -===== Bug Fixes - -Bug fixes include: - -* Fix backtrace suppression issues. - -* Rules now explicit get task arguments passed to them. - -* Rename FileList#exclude? to FileList#exclude\_from\_list? to avoid - conflict with new Rails method. - -* Clean / Clobber tasks now report failure to remove files. - -* Plus heaps of internal code cleanup. - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. -The following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Michael Nikitochkin (general code cleanup) -* Vipul A M (general code cleanup) -* Dennis Bell (variable length task argument lists) -* Jacob Swanner (rules arguments) -* Rafael Rosa Fu (documentation typo) -* Stuart Nelson (install.rb fixes) -* Lee Hambley (application name in help banner) - --- Jim Weirich - -=== 10.0.3 - - "Jim, when will Rake reach version 1.0?" - -Over the past several years I've been asked that question at -conferences, panels and over twitter. Due to historical reasons (or -maybe just plain laziness) Rake has (incorrectly) been treating the -second digit of the version as the major release number. So in my head -Rake was already at version 9. - -Well, it's time to fix things. This next version of Rake drops old, -crufty, backwards compatibility hacks such as top level constants, DSL -methods defined in Object and numerous other features that are just no -longer desired. It's also time to drop the leading zero from the -version number as well and call this new version of rake what it -really is: Version 10. - -So, welcome to Rake 10.0! - -Rake 10 is actually feature identical to the latest version of Rake 9 -(that would be the version spelled 0.9.3), *except* that Rake 10 drops -all the sundry deprecated features that have accumulated over the years. - -If your Rakefile is up to date and current with all the new features -of Rake 10, you are ready to go. If your Rakefile still uses a few -deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same -feature set. Just be aware that future features will be in Rake 10 -family line. - -==== Changes - -As mentioned above, there are no new features in Rake 10. However, -there are a number of features missing: - -* Classic namespaces are now gone. Rake is no longer able to reflect - the options settings in the global variables ($rakefile, $show\_tasks, - $show\_prereqs, $trace, $dryrun and $silent). The - --classic-namespace option is no longer supported. - -* Global constants are no longer supported. This includes - Task, FileTask, FileCreationTask and - RakeApp). The constant missing hook to warn about using - global rake constants has been removed. - -* The Rake DSL methods (task, file, directory, etc) are in their own - module (Rake::DSL). The stub versions of these methods (that printed - warnings) in Object have been removed. However, the DSL methods are - added to the top-level main object. Since main is - not in the inheritance tree, the presence of the DSL methods in main - should be low impact on other libraries. - - If you want to use the Rake DSL commands from your own code, just - include Rake::DSL into your own classes and modules. - -* The deprecated syntax for task arguments (the one using - :needs) has been removed. - -* The --reduce-compat flag has been removed (it's not needed - anymore). - -* The deprecated rake/sys.rb library has been removed. - -* The deprecated rake/rdoctask.rb library has been removed. - RDoc supplies its own rake task now. - -* The deprecated rake/gempackagetask.rb library has been - removed. Gem supplies its own package task now. - -There is one small behavioral change: - -* Non-file tasks now always report the current time as their time - stamp. This is different from the previous behavior where non-file - tasks reported current time only if there were no prerequisites, and - the max prerequisite timestamp otherwise. This lead to inconsistent - and surprising behavior when adding prerequisites to tasks that in - turn were prequisites to file tasks. The new behavior is more - consistent and predictable. - -==== Changes (from 0.9.3, 0.9.4, 0.9.5) - -Since Rake 10 includes the changes from the last version of Rake 9, -we'll repeat the changes for versions 0.9.3 through 0.9.5 here. - -===== New Features (in 0.9.3) - -* Multitask tasks now use a thread pool. Use -j to limit the number of - available threads. - -* Use -m to turn regular tasks into multitasks (use at your own risk). - -* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to - programatically add rake task libraries. - -* You can specific backtrace suppression patterns (see - --suppress-backtrace) - -* Directory tasks can now take prerequisites and actions - -* Use --backtrace to request a full backtrace without the task trace. - -* You can say "--backtrace=stdout" and "--trace=stdout" to route trace - output to standard output rather than standard error. - -* Optional 'phony' target (enable with 'require 'rake/phony'") for - special purpose builds. - -* Task#clear now clears task comments as well as actions and - prerequisites. Task#clear_comment will specifically target comments. - -* The --all option will force -T and -D to consider all the tasks, - with and without descriptions. - -===== Bug Fixes (in 0.9.3) - -* Semi-colons in windows rakefile paths now work. - -* Improved Control-C support when invoking multiple test suites. - -* egrep method now reads files in text mode (better support for - Windows) - -* Better deprecation line number reporting. - -* The -W option now works with all tasks, whether they have a - description or not. - -* File globs in rake should not be sorted alphabetically, independent - of file system and platform. - -* Numerous internal improvements. - -* Documentation typos and fixes. - -===== Bug Fixes (in 0.9.4) - -* Exit status with failing tests is not correctly set to non-zero. - -* Simplified syntax for phony task (for older versions of RDoc). - -* Stand alone FileList usage gets glob function (without loading in - extra dependencies) - -===== Bug Fixes (in 0.9.5) - -* --trace and --backtrace no longer swallow following task names. - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 10.0.2 - -==== Changes - -===== Bug Fixes - -* --trace and --backtrace no longer swallow following task names. - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 10.0.1 - -==== Changes - -===== Bug Fixes - -* Exit status with failing tests is not correctly set to non-zero. - -* Simplified syntax for phony task (for older versions of RDoc). - -* Stand alone FileList usage gets glob function (without loading in - extra dependencies) - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 10.0.0 - - "Jim, when will Rake reach version 1.0?" - -Over the past several years I've been asked that question at -conferences, panels and over twitter. Due to historical reasons (or -maybe just plain laziness) Rake has (incorrectly) been treating the -second digit of the version as the major release number. So in my head -Rake was already at version 9. - -Well, it's time to fix things. This next version of Rake drops old, -crufty, backwards compatibility hacks such as top level constants, DSL -methods defined in Object and numerous other features that are just no -longer desired. It's also time to drop the leading zero from the -version number as well and call this new version of rake what it -really is: Version 10. - -So, welcome to Rake 10.0! - -Rake 10 is actually feature identical to the latest version of Rake 9 -(that would be the version spelled 0.9.3), *except* that Rake 10 drops -all the sundry deprecated features that have accumulated over the years. - -If your Rakefile is up to date and current with all the new features -of Rake 10, you are ready to go. If your Rakefile still uses a few -deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same -feature set. Just be aware that future features will be in Rake 10 -family line. - -==== Changes in 10.0 - -As mentioned above, there are no new features in Rake 10. However, -there are a number of features missing: - -* Classic namespaces are now gone. Rake is no longer able to reflect - the options settings in the global variables ($rakefile, $show\_tasks, - $show\_prereqs, $trace, $dryrun and $silent). The - --classic-namespace option is no longer supported. - -* Global constants are no longer supported. This includes - Task, FileTask, FileCreationTask and - RakeApp). The constant missing hook to warn about using - global rake constants has been removed. - -* The Rake DSL methods (task, file, directory, etc) are in their own - module (Rake::DSL). The stub versions of these methods (that printed - warnings) in Object have been removed. However, the DSL methods are - added to the top-level main object. Since main is - not in the inheritance tree, the presence of the DSL methods in main - should be low impact on other libraries. - - If you want to use the Rake DSL commands from your own code, just - include Rake::DSL into your own classes and modules. - -* The deprecated syntax for task arguments (the one using - :needs) has been removed. - -* The --reduce-compat flag has been removed (it's not needed - anymore). - -* The deprecated rake/sys.rb library has been removed. - -* The deprecated rake/rdoctask.rb library has been removed. - RDoc supplies its own rake task now. - -* The deprecated rake/gempackagetask.rb library has been - removed. Gem supplies its own package task now. - -There is one small behavioral change: - -* Non-file tasks now always report the current time as their time - stamp. This is different from the previous behavior where non-file - tasks reported current time only if there were no prerequisites, and - the max prerequisite timestamp otherwise. This lead to inconsistent - and surprising behavior when adding prerequisites to tasks that in - turn were prequisites to file tasks. The new behavior is more - consistent and predictable. - -==== Changes (from 0.9.3) - -Since Rake 10 includes the changes from the last version of Rake 9, -we'll repeat the changes for version 0.9.3 here. - -===== New Features - -* Multitask tasks now use a thread pool. Use -j to limit the number of - available threads. - -* Use -m to turn regular tasks into multitasks (use at your own risk). - -* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to - programatically add rake task libraries. - -* You can specific backtrace suppression patterns (see - --suppress-backtrace) - -* Directory tasks can now take prerequisites and actions - -* Use --backtrace to request a full backtrace without the task trace. - -* You can say "--backtrace=stdout" and "--trace=stdout" to route trace - output to standard output rather than standard error. - -* Optional 'phony' target (enable with 'require 'rake/phony'") for - special purpose builds. - -* Task#clear now clears task comments as well as actions and - prerequisites. Task#clear_comment will specifically target comments. - -* The --all option will force -T and -D to consider all the tasks, - with and without descriptions. - -===== Bug Fixes - -* Semi-colons in windows rakefile paths now work. - -* Improved Control-C support when invoking multiple test suites. - -* egrep method now reads files in text mode (better support for - Windows) - -* Better deprecation line number reporting. - -* The -W option now works with all tasks, whether they have a - description or not. - -* File globs in rake should not be sorted alphabetically, independent - of file system and platform. - -* Numerous internal improvements. - -* Documentation typos and fixes. - - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.6 - -Rake version 0.9.6 contains a number of fixes mainly for merging -Rake into the Ruby source tree and fixing tests. - -==== Changes - -===== Bug Fixes (0.9.6) - -* Better trace output when using a multi-threaded Rakefile. -* Arg parsing is now consistent for tasks and multitasks. -* Skip exit code test in versions of Ruby that don't support it well. - -Changes for better integration with the Ruby source tree: - -* Fix version literal for Ruby source tree build. -* Better loading of libraries for testing in Ruby build. -* Use the ruby version provided by Ruby's tests. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.5 - -Rake version 0.9.5 contains a number of bug fixes. - -==== Changes - -===== Bug Fixes (0.9.5) - -* --trace and --backtrace no longer swallow following task names. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.4 - -Rake version 0.9.4 contains a number of bug fixes. - -==== Changes - -===== Bug Fixes (0.9.4) - -* Exit status with failing tests is not correctly set to non-zero. - -* Simplified syntax for phony task (for older versions of RDoc). - -* Stand alone FileList usage gets glob function (without loading in - extra dependencies) - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.3 - -Rake version 0.9.3 contains some new, backwards compatible features and -a number of bug fixes. - -==== Changes - -===== New Features - -* Multitask tasks now use a thread pool. Use -j to limit the number of - available threads. - -* Use -m to turn regular tasks into multitasks (use at your own risk). - -* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to - programatically add rake task libraries. - -* You can specific backtrace suppression patterns (see - --suppress-backtrace) - -* Directory tasks can now take prerequisites and actions - -* Use --backtrace to request a full backtrace without the task trace. - -* You can say "--backtrace=stdout" and "--trace=stdout" to route trace - output to standard output rather than standard error. - -* Optional 'phony' target (enable with 'require 'rake/phony'") for - special purpose builds. - -* Task#clear now clears task comments as well as actions and - prerequisites. Task#clear_comment will specifically target comments. - -* The --all option will force -T and -D to consider all the tasks, - with and without descriptions. - -===== Bug Fixes - -* Semi-colons in windows rakefile paths now work. - -* Improved Control-C support when invoking multiple test suites. - -* egrep method now reads files in text mode (better support for - Windows) - -* Better deprecation line number reporting. - -* The -W option now works with all tasks, whether they have a - description or not. - -* File globs in rake should not be sorted alphabetically, independent - of file system and platform. - -* Numerous internal improvements. - -* Documentation typos and fixes. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== Rake 0.9.2.2 - -Rake version 0.9.2.2 is mainly bug fixes. - -==== Changes - -* The rake test loader now removes arguments it has processed. Issue #51 -* Rake::TaskArguments now responds to #values\_at -* RakeFileUtils.verbose_flag = nil silences output the same as 0.8.7 -* Rake tests are now directory-independent -* Rake tests are no longer require flexmock -* Commands constant is no longer polluting top level namespace. -* Show only the interesting portion of the backtrace by default (James M. Lawrence). -* Added --reduce-compat option to remove backward compatible DSL hacks (James M. Lawrence). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - -=== 0.9.2 - -Rake version 0.9.2 has a few small fixes. See below for details. - -==== Changes - -* Support for Ruby 1.8.6 was fixed. -* Global DSL warnings now honor --no-deprecate - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - -=== 0.9.1 - -Rake version 0.9.1 has a number of bug fixes and enhancments (see -below for more details). Additionally, the internals have be slightly -restructured and improved. - -==== Changes - -Rake 0.9.1 adds back the global DSL methods, but with deprecation -messages. This allows Rake 0.9.1 to be used with older rakefiles with -warning messages. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - -=== 0.9.0 - -Rake version 0.9.0 has a number of bug fixes and enhancments (see -below for more details). Additionally, the internals have be slightly -restructured and improved. - -==== Changes - -===== New Features / Enhancements / Bug Fixes in Version 0.9.0 - -* Rake now warns when the deprecated :needs syntax used (and suggests - the proper syntax in the warning). - -* Moved Rake DSL commands to top level ruby object 'main'. Rake DSL - commands are no longer private methods in Object. (Suggested by - James M. Lawrence/quix) - -* Rake now uses case-insensitive comparisons to find the Rakefile on Windows. - Based on patch by Roger Pack. - -* Rake now requires (instead of loads) files in the test task. Patch by Cezary - Baginski. - -* Fixed typos. Patches by Sean Scot August Moon and R.T. Lechow. - -* Rake now prints the Rakefile directory only when it's different from the - current directory. Patch by Alex Chaffee. - -* Improved rakefile_location discovery on Windows. Patch by James Tucker. - -* Rake now recognizes "Windows Server" as a windows system. Patch by Matthias - Lüdtke - -* Rake::RDocTask is deprecated. Use RDoc::Task from RDoc 2.4.2+ (require - 'rdoc/task') - -* Rake::GemPackageTask is deprecated. Use Gem::PackageTask (require - 'rubygems/package\_task') - -* Rake now outputs various messages to $stderr instead of $stdout. - -* Rake no longer emits warnings for Config. Patch by Santiago Pastorino. - -* Removed Rake's DSL methods from the top level scope. If you need to - call 'task :xzy' in your code, include Rake::DSL into your class, or - put the code in a Rake::DSL.environment do ... end block. - -* Split rake.rb into individual files. - -* Support for the --where (-W) flag for showing where a task is defined. - -* Fixed quoting in test task. - (http://onestepback.org/redmine/issues/show/44, - http://www.pivotaltracker.com/story/show/1223138) - -* Fixed the silent option parsing problem. - (http://onestepback.org/redmine/issues/show/47) - -* Fixed :verbose=>false flag on sh and ruby commands. - -* Rake command line options may be given by default in a RAKEOPT - environment variable. - -* Errors in Rake will now display the task invocation chain in effect - at the time of the error. - -* Accepted change by warnickr to not expand test patterns in shell - (allowing more files in the test suite). - -* Fixed that file tasks did not perform prereq lookups in scope - (Redmine #57). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - - -=== 0.8.7 - -Rake version 0.8.5 introduced greatly improved support for executing -commands on Windows. The "sh" command now has the same semantics on -Windows that it has on Unix based platforms. - -Rake version 0.8.6 includes minor fixes the the RDoc generation. -Rake version 0.8.7 includes a minor fix for JRuby running on windows. - -==== Changes - -===== New Features / Enhancements in Version 0.8.5 - -* Improved implementation of the Rake system command for Windows. - (patch from James M. Lawrence/quix) - -* Support for Ruby 1.9's improved system command. (patch from James - M. Lawrence/quix) - -* Rake now includes the configured extension when invoking an - executable (Config::CONFIG['EXEEXT]) - -===== Bug Fixes in Version 0.8.5 - -* Environment variable keys are now correctly cased (it matters in - some implementations). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Charles Nutter - --- Jim Weirich - -=== 0.8.6 - -Rake version 0.8.5 introduced greatly improved support for executing -commands on Windows. The "sh" command now has the same semantics on -Windows that it has on Unix based platforms. - -Rake version 0.8.5 includes minor fixes the the RDoc generation. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence/quix -* Luis Lavena - --- Jim Weirich - -=== 0.8.5 - -Rake version 0.8.5 is a new release of Rake with greatly improved -support for executing commands on Windows. The "sh" command now has -the same semantics on Windows that it has on Unix based platforms. - -==== Changes - -===== New Features / Enhancements in Version 0.8.5 - -* Improved implementation of the Rake system command for Windows. - (patch from James M. Lawrence/quix) - -* Support for Ruby 1.9's improved system command. (patch from James - M. Lawrence/quix) - -* Rake now includes the configured extension when invoking an - executable (Config::CONFIG['EXEEXT]) - -===== Bug Fixes in Version 0.8.5 - -* Environment variable keys are now correctly cased (it matters in - some implementations). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence/quix -* Luis Lavena - --- Jim Weirich - -=== 0.8.4 - -Rake version 0.8.4 is a bug-fix release of rake. - -NOTE: The version of Rake that comes with Ruby 1.9 has diverged - slightly from the core Rake code base. Rake 0.8.4 will work - with Ruby 1.9, but is not a strict upgrade for the Rake that - comes with Ruby 1.9. A (near) future release of Rake will unify - those two codebases. - -==== Letter Writing Campaign - -Thanks to Aaron Patterson (@tenderlove) and Eric Hodel (@drbrain) for -their encouraging support in organizing a letter writing campaign to -lobby for the "Warning Free" release of rake 0.8.4. A special callout -goes to Jonathan D. Lord, Sr (Dr. Wingnut) whose postcard was the -first to actually reach me. (see -http://tenderlovemaking.com/2009/02/26/we-need-a-new-version-of-rake/ -for details) - -==== Changes - -===== New Features / Enhancements in Version 0.8.4 - -* Case is preserved on rakefile names. (patch from James - M. Lawrence/quix) - -* Improved Rakefile case insensitivity testing (patch from Luis - Lavena). - -* Windows system dir search order is now: HOME, HOMEDRIVE + HOMEPATH, - APPDATA, USERPROFILE (patch from Luis Lavena) - -* MingGW is now recognized as a windows platform. (patch from Luis - Lavena) - -===== Bug Fixes in Version 0.8.4 - -* Removed reference to manage_gem to fix the warning produced by the - gem package task. - -* Fixed stray ARGV option problem that was interfering with - Test::Unit::Runner. (patch from Pivotal Labs) - -===== Infrastructure Improvements in Version 0.8.4 - -* Numerous fixes to the windows test suite (patch from Luis Lavena). - -* Improved Rakefile case insensitivity testing (patch from Luis - Lavena). - -* Better support for windows paths in the test task (patch from Simon - Chiang/bahuvrihi) - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence/quix -* Luis Lavena -* Pivotal Labs -* Simon Chiang/bahuvrihi - --- Jim Weirich - -=== 0.8.3 - -Rake version 0.8.3 is a bug-fix release of rake. - -==== Changes - -===== Bug Fixes in Version 0.8.3 - -* Enhanced the system directory detection in windows. We now check - HOMEDRIVE/HOMEPATH and USERPROFILE if APPDATA isn't found. (Patch - supplied by James Tucker). Rake no long aborts if it can't find the - directory. - -* Added fix to handle ruby installations in directories with spaces in - their name. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Edwin Pratomo -* Gavin Stark -* Adam Q. Salter -* Adam Majer -* Emanuel Indermühle -* Ittay Dror -* Bheeshmar Redheendran (for spending an afternoon with me debugging - windows issues) - --- Jim Weirich - - -=== 0.8.2 - -Rake version 0.8.2 is a new release of rake that includes a number of -new features and numerous bug fixes. - -==== Changes - -===== New Features in Version 0.8.2 - -* Switched from getoptlong to optparse (patches supplied by Edwin - Pratomo). - -* The -T option will now attempt to dynamically sense the size of the - terminal. The -T output will only self-truncate if the output is a - tty. However, if RAKE_COLUMNS is explicitly set, it will be honored - in any case. (Patch provided by Gavin Stark). - -* The following public methods have been added to rake task objects: - - * task.clear -- Clear both the prerequisites and actions of the - target rake task. - * task.clear_prerequisites -- Clear all the existing prerequisites - from the target rake task. - * task.clear_actions -- Clear all the existing actions from the - target rake task. - * task.reenable -- Re-enable a task, allowing its actions to be - executed again if the task is invoked. - -* Changed RDoc test task to have no default template. This makes it - easier for the tempate to pick up the template from the environment. - -* Default values for task arguments can easily be specified with the - :with_defaults method. (Idea for default argument merging supplied - by (Adam Q. Salter) - -===== Bug Fixes in Version 0.8.2 - -* Fixed bug in package task so that it will include the subdir - directory in the package for testing. (Bug found by Adam Majer) - -* Fixed filename dependency order bug in test\_inspect\_pending and - test\_to\_s\_pending. (Bug found by Adam Majer) - -* Fixed check for file utils options to make them immune to the - symbol/string differences. (Patch supplied by Edwin Pratomo) - -* Fixed bug with rules involving multiple source, where only the first - dependency of a rule has any effect (Patch supplied by Emanuel - Indermühle) - -* FileList#clone and FileList#dup have better sematics w.r.t. taint - and freeze. - -* Changed from using Mutex to Monitor. Evidently Mutex causes thread - join errors when Ruby is compiled with -disable-pthreads. (Patch - supplied by Ittay Dror) - -* Fixed bug in makefile parser that had problems with extra spaces in - file task names. (Patch supplied by Ittay Dror) - -==== Other changes in Version 0.8.2 - -* Added ENV var to rake's own Rakefile to prevent OS X from including - extended attribute junk in the rake package tar file. (Bug found by - Adam Majer) - -* Added a performance patch for reading large makefile dependency - files. (Patch supplied by Ittay Dror) - -==== Task Argument Examples - -Prior to version 0.8.0, rake was only able to handle command line -arguments of the form NAME=VALUE that were passed into Rake via the -ENV hash. Many folks had asked for some kind of simple command line -arguments, perhaps using "--" to separate regular task names from -argument values on the command line. The problem is that there was no -easy way to associate positional arguments on the command line with -different tasks. Suppose both tasks :a and :b expect a command line -argument: does the first value go with :a? What if :b is run first? -Should it then get the first command line argument. - -Rake 0.8.0 solves this problem by explicitly passing values directly -to the tasks that need them. For example, if I had a release task -that required a version number, I could say: - - rake release[0.8.2] - -And the string "0.8.2" will be passed to the :release task. Multiple -arguments can be passed by separating them with a comma, for example: - - rake name[john,doe] - -Just a few words of caution. The rake task name and its arguments -need to be a single command line argument to rake. This generally -means no spaces. If spaces are needed, then the entire rake + -argument string should be quoted. Something like this: - - rake "name[billy bob, smith]" - -(Quoting rules vary between operating systems and shells, so make sure -you consult the proper docs for your OS/shell). - -===== Tasks that Expect Parameters - -Parameters are only given to tasks that are setup to expect them. In -order to handle named parameters, the task declaration syntax for -tasks has been extended slightly. - -For example, a task that needs a first name and last name might be -declared as: - - task :name, :first_name, :last_name - -The first argument is still the name of the task (:name in this case). -The next to argumements are the names of the parameters expected by -:name (:first_name and :last_name in the example). - -To access the values of the parameters, the block defining the task -behaviour can now accept a second parameter: - - task :name, :first_name, :last_name do |t, args| - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -The first argument of the block "t" is always bound to the current -task object. The second argument "args" is an open-struct like object -that allows access to the task arguments. Extra command line -arguments to a task are ignored. Missing command line arguments are -given the nil value. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Edwin Pratomo -* Gavin Stark -* Adam Q. Salter -* Adam Majer -* Emanuel Indermühle -* Ittay Dror -* Bheeshmar Redheendran (for spending an afternoon with me debugging - windows issues) - --- Jim Weirich - -=== 0.8.0/0.8.1 - -Rake version 0.8.0 is a new release of rake that includes serveral new -features. - -==== Changes - -===== New Features in Version 0.8.0 - -* Tasks can now receive command line parameters. See the examples - below for more details. - -* Comments are limited to 80 columns on output, but full comments can - be seen by using the -D parameter. (feature suggested by Jamis - Buck). - -* Explicit exit(n) calls will now set the exit status to n. (patch - provided by Stephen Touset). - -* Rake is now compatible with Ruby 1.9. - -Version 0.8.1 is a minor update that includes additional Ruby 1.9 -compatibility fixes. - -==== Task Argument Examples - -Prior to version 0.8.0, rake was only able to handle command line -arguments of the form NAME=VALUE that were passed into Rake via the -ENV hash. Many folks had asked for some kind of simple command line -arguments, perhaps using "--" to separate regular task names from -argument values on the command line. The problem is that there was no -easy way to associate positional arguments on the command line with -different tasks. Suppose both tasks :a and :b expect a command line -argument: does the first value go with :a? What if :b is run first? -Should it then get the first command line argument. - -Rake 0.8.0 solves this problem by explicitly passing values directly -to the tasks that need them. For example, if I had a release task -that required a version number, I could say: - - rake release[0.8.0] - -And the string "0.8.0" will be passed to the :release task. Multiple -arguments can be passed by separating them with a comma, for example: - - rake name[john,doe] - -Just a few words of caution. The rake task name and its arguments -need to be a single command line argument to rake. This generally -means no spaces. If spaces are needed, then the entire rake + -argument string should be quoted. Something like this: - - rake "name[billy bob, smith]" - -(Quoting rules vary between operating systems and shells, so make sure -you consult the proper docs for your OS/shell). - -===== Tasks that Expect Parameters - -Parameters are only given to tasks that are setup to expect them. In -order to handle named parameters, the task declaration syntax for -tasks has been extended slightly. - -For example, a task that needs a first name and last name might be -declared as: - - task :name, :first_name, :last_name - -The first argument is still the name of the task (:name in this case). -The next to argumements are the names of the parameters expected by -:name (:first_name and :last_name in the example). - -To access the values of the parameters, the block defining the task -behaviour can now accept a second parameter: - - task :name, :first_name, :last_name do |t, args| - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -The first argument of the block "t" is always bound to the current -task object. The second argument "args" is an open-struct like object -that allows access to the task arguments. Extra command line -arguments to a task are ignored. Missing command line arguments are -given the nil value. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Jamis Buck (for comment formatting suggestions) -* Stephen Touset (for exit status patch). - --- Jim Weirich - - -=== 0.7.3 - -Rake version 0.7.3 is a minor release that includes some refactoring to better -support custom Rake applications. - -==== Changes - -===== New Features in Version 0.7.3 - -* Added the +init+ and +top_level+ methods to make the creation of custom Rake applications a bit easier. E.g. - - gem 'rake', ">= 0.7.3" - require 'rake' - - Rake.application.init('myrake') - - task :default do - something_interesting - end - - Rake.application.top_level - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - --- Jim Weirich - - -=== 0.7.2 - - -Version 0.7.2 supplies a bug fix and a few minor enhancements. In -particular, the new version fixes an incompatibility with the soon to -be released Ruby 1.8.6. We strongly recommend upgrading to Rake 0.7.2 -in order to be compatible with the new version of Ruby. - -==== Changes - -===== Bug Fixes in 0.7.2 - -There are quite a number of bug fixes in the new 0.7.2 version of -Rake: - -* Removed dependency on internal fu_xxx functions from FileUtils. - -* Error messages are now send to stderr rather than stdout (from - Payton Quackenbush). - -* Better error handling on invalid command line arguments (from Payton - Quackenbush). - -* Fixed some bugs where the application object was going to the global - appliation instead of using its own data. - -* Fixed the method name leak from FileUtils (bug found by Glenn - Vanderburg). - -* Added test for noop, bad_option and verbose flags to sh command. - -* Added a description to the gem task in GemPackageTask. - -* Fixed a bug when rules have multiple prerequisites (patch by Joel - VanderWerf) - -* Added the handful of RakeFileUtils to the private method as well. - -===== New Features in 0.7.2 - -The following new features are available in Rake version 0.7.2: - -* Added square and curly bracket patterns to FileList#include (Tilman - Sauerbeck). - -* FileLists can now pass a block to FileList#exclude to exclude files - based on calculated values. - -* Added plain filename support to rule dependents (suggested by Nobu - Nakada). - -* Added pathmap support to rule dependents. In other words, if a - pathmap format (beginning with a '%') is given as a Rake rule - dependent, then the name of the depend will be the name of the - target with the pathmap format applied. - -* Added a 'tasks' method to a namespace to get a list of tasks - associated with the namespace. - -* Added tar_command and zip_command options to the Package task. - -* The clean task will no longer delete 'core' if it is a directory. - -===== Internal Rake Improvements - -The following changes will are mainly internal improvements and -refactorings and have little effect on the end user. But they may be -of interest to the general public. - -* Added rcov task and updated unit testing for better code coverage. - -* Added a 'shame' task to the Rakefile. - -* Added rake_extension to handle detection of extension collisions. - -* Added a protected 'require "rubygems"' to test/test_application to - unbreak cruisecontrol.rb. - -* Removed rake\_dup. Now we just simply rescue a bad dup. - -* Refactored the FileList reject logic to remove duplication. - -* Removed if \_\_FILE\_\_ at the end of the rake.rb file. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* Payton Quackenbush -- For several error handling improvements. - -* Glenn Vanderburg -- For finding and fixing the method name leak from - FileUtils. - -* Joel VanderWerf -- for finding and fixing a bug in the handling of - multiple prerequisites. - -* Tilman Sauerbeck -- For some enhancing FileList to support more - advanced file globbing. - -* Nobu Nakada -- For suggesting plain file name support to rule dependents. - --- Jim Weirich - -=== 0.7.1 - -Version 0.7.1 supplies a bug fix and a few minor enhancements. - -==== Changes - -===== Bug Fixes in 0.7.1 - -* Changes in the exception reported for the FileUtils.ln caused - safe_ln to fail with a NotImplementedError. Rake 0.7.1 will now - catch that error or any StandardError and properly fall back to - using +cp+. - -===== New Features in 0.7.1 - -* You can filter the results of the --task option by supplying an - optional regular expression. This allows the user to easily find a - particular task name in a long list of possible names. - -* Transforming procs in a rule may now return a list of prerequisites. - This allows more flexible rule formation. - -* FileList and String now support a +pathmap+ melthod that makes the - transforming paths a bit easier. See the API docs for +pathmap+ for - details. - -* The -f option without a value will disable the search for a - Rakefile. This allows the Rakefile to be defined entirely in a - library (and loaded with the -r option). The current working - directory is not changed when this is done. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* James Britt and Assaph Mehr for reporting and helping to debug the - safe_ln issue. - --- Jim Weirich - - -=== 0.7.0 - -These changes for Rake have been brewing for a long time. Here they -are, I hope you enjoy them. - -==== Changes - -===== New Features - -* Name space support for task names (see below). -* Prerequisites can be executed in parallel (see below). -* Added safe_ln support for openAFS (via Ludvig Omholt). -* RDoc defaults to internal (in-process) invocation. The old behavior - is still available by setting the +external+ flag to true. -* Rakefiles are now loaded with the expanded path to prevent - accidental pollution from the Ruby load path. -* Task objects my now be used in prerequisite lists directly. -* Task objects (in addition to task names) may now be included in the - prerequisite list of a task. -* Internals cleanup and refactoring. - -===== Bug Fixes - -* Compatibility fixes for Ruby 1.8.4 FileUtils changes. - -===== Namespaces - -Tasks can now be nested inside their own namespaces. Tasks within one -namespace will not accidentally interfer with tasks named in a different -namespace. - -For example: - - namespace "main" do - task :build do - # Build the main program - end - end - - namespace "samples" do - task :build do - # Build the sample programs - end - end - - task :build_all => ["main:build", "samples:build"] - -Even though both tasks are named :build, they are separate tasks in -their own namespaces. The :build_all task (defined in the toplevel -namespace) references both build tasks in its prerequisites. - -You may invoke each of the individual build tasks with the following -commands: - - rake main:build - rake samples:build - -Or invoke both via the :build_all command: - - rake build_all - -Namespaces may be nested arbitrarily. Since the name of file tasks -correspond to the name of a file in the external file system, -FileTasks are not affected by the namespaces. - -See the Rakefile format documentation (in the Rake API documents) for -more information. - -===== Parallel Tasks - -Sometimes you have several tasks that can be executed in parallel. By -specifying these tasks as prerequisites to a +multitask+ task. - -In the following example the tasks copy\_src, copy\_doc and copy\_bin -will all execute in parallel in their own thread. - - multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do - puts "All Copies Complete" - end - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* Doug Young (inspiration for the parallel task) -* David Heinemeier Hansson (for --trace message enhancement and for - pushing for namespace support). -* Ludvig Omholt (for the openAFS fix) - --- Jim Weirich - -=== 0.6.1 - -* Rebuilt 0.6.0 gem without signing. - -=== 0.6.0 - -Its time for some long requested enhancements and lots of bug fixes -... And a whole new web page. - -==== New Web Page - -The primary documentation for rake has moved from the RubyForge based -wiki to its own Hieraki based web site. Constant spam on the wiki -made it a difficult to keep clean. The new site will be easier to -update and organize. - -Check out the new documentation at: http://docs.rubyrake.org - -We will be adding new documentation to the site as time goes on. - -In addition to the new docs page, make sure you check out Martin -Fowlers article on rake at http://martinfowler.com/articles/rake.html - -==== Changes - -===== New Features - -* Multiple prerequisites on Rake rules now allowed. However, keep the - following in mind: - - 1. All the prerequisites of a rule must be available before a rule - is triggered, where "enabled" means (a) an existing file, (b) a - defined rule, or (c) another rule which also must be - trigger-able. - 2. Rules are checked in order of definition, so it is important to - order your rules properly. If a file can be created by two - different rules, put the more specific rule first (otherwise the - more general rule will trigger first and the specific one will - never be triggered). - 3. The source method now returns the name of the first - prerequisite listed in the rule. sources returns the - names of all the rule prerequisites, ordered as they are defined - in the rule. If the task has other prerequisites not defined in - the rule (but defined in an explicit task definition), then they - will _not_ be included in the sources list. - -* FileLists may now use the egrep command. This popular enhancement - is now a core part of the FileList object. If you want to get a - list of all your to-dos, fixmes and TBD comments, add the following - to your Rakefile. - - desc "Look for TODO and FIXME tags in the code" - task :todo do - FileList['**/*.rb'].egrep /#.*(FIXME|TODO|TBD)/ - end - -* The investigation method was added to task object to dump - out some important values. This makes it a bit easier to debug Rake - tasks. - - For example, if you are having problems with a particular task, just - print it out: - - task :huh do - puts Rake::Task['huh'].investigation - end - -* The Rake::TestTask class now supports a "ruby\_opts" option to pass - arbitrary ruby options to a test subprocess. - -===== Some Incompatibilities - -* When using the ruby command to start a Ruby subprocess, the - Ruby interpreter that is currently running rake is used by default. - This makes it easier to use rake in an environment with multiple - ruby installation. (Previously, the first ruby command found in the - PATH was used). - - If you wish to chose a different Ruby interpreter, you can - explicitly choose the interpreter via the sh command. - -* The major rake classes (Task, FileTask, FileCreationTask, RakeApp) - have been moved out of the toplevel scope and are now accessible as - Rake::Task, Rake::FileTask, Rake::FileCreationTask and - Rake::Application. If your Rakefile - directly references any one of these tasks, you may: - - 1. Update your Rakefile to use the new classnames - 2. Use the --classic-namespace option on the rake command to get the - old behavior, - 3. Add require 'rake/classic_namespace' to the - Rakefile to get the old behavior. - - rake will print a rather annoying warning whenever a - deprecated class name is referenced without enabling classic - namespace. - -===== Bug Fixes - -* Several unit tests and functional tests were fixed to run better - under windows. - -* Directory tasks are now a specialized version of a File task. A - directory task will only be triggered if it doesn't exist. It will - not be triggered if it is out of date w.r.t. any of its - prerequisites. - -* Fixed a bug in the Rake::GemPackageTask class so that the gem now - properly contains the platform name. - -* Fixed a bug where a prerequisite on a file task would cause - an exception if the prerequisite did not exist. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* Greg Fast (better ruby_opt test options) -* Kelly Felkins (requested by better namespace support) -* Martin Fowler (suggested Task.investigation) -* Stuart Jansen (send initial patch for multiple prerequisites). -* Masao Mutch (better support for non-ruby Gem platforms) -* Philipp Neubeck (patch for file task exception fix) - --- Jim Weirich - -=== 0.5.4 - -Time for some minor bug fixes and small enhancements - -==== Changes - -Here are the changes for version 0.5.4 ... - -* Added double quotes to the test runner. This allows the location of - the tests (and runner) to be in a directory path that contains - spaces (e.g. "C:/Program Files/ruby/bin"). -* Added .svn to default ignore list. Now subversion project metadata - is automatically ignored by Rake's FileList. -* Updated FileList#include to support nested arrays and filelists. - FileLists are flat lists of file names. Using a FileList in an - include will flatten out the nested file names. - -== Thanks - -As usual, it was input from users that drove a alot of these changes. -Thanks to ... - -* Tilman Sauerbeck for the nested FileList suggestion. -* Josh Knowles for pointing out the spaces in directory name problem. - --- Jim Weirich - -=== 0.5.3 - -Although it has only been two weeks since the last release, we have -enough updates to the Rake program to make it time for another -release. - -==== Changes - -Here are the changes for version 0.5.3 ... - -* FileLists have been extensively changed so that they mimic the - behavior of real arrays even more closely. In particular, - operations on FileLists that return a new collection (e.g. collect, - reject) will now return a FileList rather than an array. In - addition, several places where FileLists were not properly expanded - before use have been fixed. -* A method (+ext+) to simplify the handling of file extensions was - added to String and to Array. -* The 'testrb' script in test/unit tends to silently swallow syntax - errors in test suites. Because of that, the default test loader is - now a rake-provided script. You can still use 'testrb' by setting - the loader flag in the test task to :testrb. (See the API documents - for TestTask for all the loader flag values). -* FileUtil methods (e.g. cp, mv, install) are now declared to be - private. This will cut down on the interference with user defined - methods of the same name. -* Fixed the verbose flag in the TestTask so that the test code is - controlled by the flag. Also shortened up some failure messages. - (Thanks to Tobias Luetke for the suggestion). -* Rules will now properly detect a task that can generate a source - file. Previously rules would only consider source files that were - already present. -* Added an +import+ command that allows Rake to dynamically import - dependendencies into a running Rake session. The +import+ command - can run tasks to update the dependency file before loading them. - Dependency files can be in rake or make format, allowing rake to - work with tools designed to generate dependencies for make. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -Thanks to ... - -* Brian Gernhardt for the rules fix (especially for the patience to - explain the problem to me until I got what he was talking about). -* Stefan Lang for pointing out problems in the dark corners of the - FileList implementation. -* Alexey Verkhovsky pointing out the silently swallows syntax errors - in tests. -* Tobias Luetke for beautifying the test task output. -* Sam Roberts for some of the ideas behind dependency loading. - --- Jim Weirich - - -=== 0.5.0 - -It has been a long time in coming, but we finally have a new version -of Rake available. - -==== Changes - -* Fixed documentation that was lacking the Rake module name (Tilman - Sauerbeck). -* Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck). -* Recursive rules are now supported (Tilman Sauerbeck). -* Added warning option for the Test Task (requested by Eric Hodel). -* The jamis rdoc template is only used if it exists. -* Added fix for Ruby 1.8.2 test/unit and rails problem. -* Added contributed rake man file (Jani Monoses). -* Added Brian Candler's fix for problems in --trace and --dry-run - mode. - -==== Thanks - -Lots of people provided input to this release. Thanks to Tilman -Sauerbeck for numerous patches, documentation fixes and suggestions. -And for also pushing me to get this release out. Also, thanks to -Brian Candler for the finding and fixing --trace/dry-run fix. That -was an obscure bug. Also to Eric Hodel for some good suggestions. - --- Jim Weirich - -=== 0.4.15 - -==== Changes - -Version 0.4.15 is a bug fix update for the Ruby 1.8.2 compatibility -changes. This release includes: - -* Fixed a bug that prevented the TESTOPTS flag from working with the - revised for 1.8.2 test task. -* Updated the docs on --trace to indicate that it also enables a full - backtrace on errors. -* Several fixes for new warnings generated. - -==== Mini-Roadmap - -I will continue to issue Rake updates in the 0.4.xx series as new -Ruby-1.8.2 issues become manifest. Once the codebase stabilizes, I -will release a 0.5.0 version incorporating all the changes. If you -are not using Ruby-1.8.2 and wish to avoid version churn, I recommend -staying with a release prior to Rake-0.4.14. - -=== 0.4.14 - -Version 0.4.14 is a compatibility fix to allow Rake's test task to -work under Ruby 1.8.2. A change in the Test::Unit autorun feature -prevented Rake from running any tests. This release fixes the -problem. - -Rake 0.4.14 is the recommended release for anyone using Ruby 1.8.2. - -=== 0.4.13 - -* Fixed the dry-run flag so it is operating again. -* Multiple arguments to sh and ruby commands will not be interpreted - by the shell (patch provided by Jonathan Paisley). - -=== 0.4.12 - -* Added --silent (-s) to suppress the (in directory) rake message. - -=== 0.4.11 - -* Changed the "don't know how to rake" message (finally) -* Changes references to a literal "Rakefile" to reference the global - variable $rakefile (which contains the actual name of the rakefile). - -=== 0.4.10 - -* Added block support to the "sh" command, allowing users to take - special actions on the result of the system call. E.g. - - sh "shell_command" do |ok, res| - puts "Program returned #{res.exitstatus}" if ! ok - end - -=== 0.4.9 - -* Switched to Jamis Buck's RDoc template. -* Removed autorequire from Rake's gem spec. This prevents the Rake - libraries from loading while using rails. - -=== 0.4.8 - -* Added support for .rb versions of Rakefile. -* Removed \\\n's from test task. -* Fixed Ruby 1.9 compatibility issue with FileList. - -=== 0.4.7 - -* Fixed problem in FileList that caused Ruby 1.9 to go into infinite - recursion. Since to_a was removed from Object, it does not need to - added back into the list of methods to rewrite in FileList. (Thanks - to Kent Sibilev for pointing this out). - -=== 0.4.6 -* Removed test version of ln in FileUtils that prevented safe_ln from - using ln. - -=== 0.4.5 -* Upgraded comments in TestTask. -* FileList to_s and inspect now automatically resolve pending changes. -* FileList#exclude properly returns the FileList. - -=== 0.4.4 -* Fixed initialization problem with @comment. -* Now using multi -r technique in TestTask. Switch Rakefile back to - using the built-in test task macros because the rake runtime is no - longer needed. -* Added 'TEST=filename' and 'TESTOPTS=options' to the Test Task - macros. -* Allow a +test_files+ attribute in test tasks. This allows more - flexibility in specifying test files. - -=== 0.4.3 -* Fixed Comment leakage. - -=== 0.4.2 -* Added safe_ln that falls back to a copy if a file link is not supported. -* Package builder now uses safe\_ln. - -=== 0.4.1 -* Task comments are now additive, combined with "/". -* Works with (soon to be released) rubygems 0.6.2 (or 0.7.0) - -=== 0.4.0 -* FileList now uses deferred loading. The file system is not searched - until the first call that needs the file names. -* VAR=VALUE options are now accepted on the command line and are - treated like environment variables. The values may be tested in a - Rakefile by referencing ENV['VAR']. -* File.mtime is now used (instead of File.new().mtime). - -=== 0.3.2.x - -* Removed some hidden dependencies on rubygems. Tests now will test - gems only if they are installed. -* Removed Sys from some example files. I believe that is that last - reference to Sys outside of the contrib area. -* Updated all copyright notices to include 2004. - -=== 0.3.2 - -* GEM Installation now works with the application stub. - -=== 0.3.1 - -* FileLists now automatically ignore CVS, .bak, ! -* GEM Installation now works. - -=== 0.3.0 - -Promoted 0.2.10. - -=== 0.2.10 -General - -* Added title to Rake's rdocs -* Contrib packages are no longer included in the documentation. - -RDoc Issues - -* Removed default for the '--main' option -* Fixed rendering of the rdoc options -* Fixed clean/clobber confusion with rerdoc -* 'title' attribute added - -Package Task Library Issues - -* Version (or explicit :noversion) is required. -* +package_file+ attribute is now writable - -FileList Issues - -* Dropped bang version of exclude. Now using ant-like include/exclude semantics. -* Enabled the "yield self" idiom in FileList#initialize. - -=== 0.2.9 - -This version contains numerous changes as the RubyConf.new(2003) -presentation was being prepared. The changes include: - -* The monolithic rubyapp task library is in the process of being - dropped in favor of lighter weight task libraries. - -=== 0.2.7 - -* Added "desc" for task descriptions. -* -T will now display tasks with descriptions. -* -P will display tasks and prerequisites. -* Dropped the Sys module in favor of the 1.8.x FileUtils module. Sys - is still supported in the contrib area. - -=== 0.2.6 - -* Moved to RubyForge - -=== 0.2.5 - -* Switched to standard ruby app builder. -* Added no_match option to file matcher. - -=== 0.2.4 - -* Fixed indir, which neglected to actually change directories. - -=== 0.2.3 - -* Added rake module for a help target -* Added 'for\_files' to Sys -* Added a $rakefile constant -* Added test for selecting proper rule with multiple targets. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE deleted file mode 100644 index 4292f3b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/MIT-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) Jim Weirich - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc deleted file mode 100644 index b31fe37..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/README.rdoc +++ /dev/null @@ -1,155 +0,0 @@ -= RAKE -- Ruby Make - -home :: https://github.com/ruby/rake -bugs :: https://github.com/ruby/rake/issues -docs :: https://ruby.github.io/rake - -== Description - -Rake is a Make-like program implemented in Ruby. Tasks and dependencies are -specified in standard Ruby syntax. - -Rake has the following features: - -* Rakefiles (rake's version of Makefiles) are completely defined in - standard Ruby syntax. No XML files to edit. No quirky Makefile - syntax to worry about (is that a tab or a space?) - -* Users can specify tasks with prerequisites. - -* Rake supports rule patterns to synthesize implicit tasks. - -* Flexible FileLists that act like arrays but know about manipulating - file names and paths. - -* A library of prepackaged tasks to make building rakefiles easier. For example, - tasks for building tarballs. (Formerly - tasks for building RDoc, Gems, and publishing to FTP were included in rake but they're now - available in RDoc, RubyGems, and rake-contrib respectively.) - -* Supports parallel execution of tasks. - -== Installation - -=== Gem Installation - -Download and install rake with the following. - - gem install rake - -== Usage - -=== Simple Example - -First, you must write a "Rakefile" file which contains the build rules. Here's -a simple example: - - task default: %w[test] - - task :test do - ruby "test/unittest.rb" - end - -This Rakefile has two tasks: - -* A task named "test", which -- upon invocation -- will run a unit test file - in Ruby. -* A task named "default". This task does nothing by itself, but it has exactly - one dependency, namely the "test" task. Invoking the "default" task will - cause Rake to invoke the "test" task as well. - -Running the "rake" command without any options will cause it to run the -"default" task in the Rakefile: - - % ls - Rakefile test/ - % rake - (in /home/some_user/Projects/rake) - ruby test/unittest.rb - ....unit test output here... - -Type "rake --help" for all available options. - -== Resources - -=== Rake Information - -* {Rake command-line}[rdoc-ref:doc/command_line_usage.rdoc] -* {Writing Rakefiles}[rdoc-ref:doc/rakefile.rdoc] -* The original {Rake announcement}[rdoc-ref:doc/rational.rdoc] -* Rake {glossary}[rdoc-ref:doc/glossary.rdoc] - -=== Presentations and Articles about Rake - -* Avdi Grimm's rake series: - 1. {Rake Basics}[https://avdi.codes/rake-part-1-basics/] - 2. {Rake File Lists}[https://avdi.codes/rake-part-2-file-lists-2/] - 3. {Rake Rules}[https://avdi.codes/rake-part-3-rules/] - 4. {Rake Pathmap}[https://avdi.codes/rake-part-4-pathmap/] - 5. {File Operations}[https://avdi.codes/rake-part-5-file-operations/] - 6. {Clean and Clobber}[https://avdi.codes/rake-part-6-clean-and-clobber/] - 7. {MultiTask}[https://avdi.codes/rake-part-7-multitask/] -* {Jim Weirich's 2003 RubyConf presentation}[https://web.archive.org/web/20140221123354/http://onestepback.org/articles/buildingwithrake/] -* Martin Fowler's article on Rake: https://martinfowler.com/articles/rake.html - -== Other Make Re-envisionings ... - -Rake is a late entry in the make replacement field. Here are links to -other projects with similar (and not so similar) goals. - -* https://directory.fsf.org/wiki/Bras -- Bras, one of earliest - implementations of "make in a scripting language". -* http://www.a-a-p.org -- Make in Python -* https://ant.apache.org -- The Ant project -* https://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System -* https://www.rubydoc.info/gems/rant/0.5.7/frames -- Rant, another Ruby make tool. - -== Credits - -[Jim Weirich] Who originally created Rake. - -[Ryan Dlugosz] For the initial conversation that sparked Rake. - -[Nobuyoshi Nakada ] For the initial patch for rule support. - -[Tilman Sauerbeck ] For the recursive rule patch. - -[Eric Hodel] For aid in maintaining rake. - -[Hiroshi SHIBATA] Maintainer of Rake 10 and later - -== License - -Rake is available under an MIT-style license. - -:include: MIT-LICENSE - ---- - -= Other stuff - -Author:: Jim Weirich -Requires:: Ruby 2.0.0 or later -License:: Copyright Jim Weirich. - Released under an MIT-style license. See the MIT-LICENSE - file included in the distribution. - -== Warranty - -This software is provided "as is" and without any express or implied -warranties, including, without limitation, the implied warranties of -merchantability and fitness for a particular purpose. - -== Historical - -Rake was originally created by Jim Weirich, who unfortunately passed away in -February 2014. This repository was originally hosted at -{github.com/jimweirich/rake}[https://github.com/jimweirich/rake/], however -with his passing, has been moved to {ruby/rake}[https://github.com/ruby/rake]. - -You can view Jim's last commit here: -https://github.com/jimweirich/rake/commit/336559f28f55bce418e2ebcc0a57548dcbac4025 - -You can {read more about Jim}[https://en.wikipedia.org/wiki/Jim_Weirich] at Wikipedia. - -Thank you for this great tool, Jim. We'll remember you. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc deleted file mode 100644 index c1ff39d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/command_line_usage.rdoc +++ /dev/null @@ -1,171 +0,0 @@ -= Rake Command Line Usage - -Rake is invoked from the command line using: - - % rake [options ...] [VAR=VALUE ...] [targets ...] - -Options are: - -[name=value] - Set the environment variable name to value - during the execution of the rake command. You can access - the value by using ENV['name']. - -[--all (-A)] - Used in combination with the -T and -D options, will force - those options to show all the tasks, even the ones without comments. - -[--backtrace{=_output_} (-n)] - Enable a full backtrace (i.e. like --trace, but without the task - tracing details). The _output_ parameter is optional, but if - specified it controls where the backtrace output is sent. If - _output_ is stdout, then backtrace output is directed to - standard output. If _output_ is stderr, or if it is - missing, then the backtrace output is sent to standard error. - -[--comments] - Used in combination with the -W options to force the output to - contain commented options only. This is the reverse of - --all. - -[--describe _pattern_ (-D)] - Describe the tasks (matching optional PATTERN), then exit. - -[--dry-run (-n)] - Do a dry run. Print the tasks invoked and executed, but do not - actually execute any of the actions. - -[--execute _code_ (-e)] - Execute some Ruby code and exit. - -[--execute-print _code_ (-p)] - Execute some Ruby code, print the result, and exit. - -[--execute-continue _code_ (-E)] - Execute some Ruby code, then continue with normal task processing. - -[--help (-H)] - Display some help text and exit. - -[--jobs _number_ (-j)] - - Specifies the maximum number of concurrent threads allowed. Rake - will allocate threads as needed up to this maximum number. - - If omitted, Rake will attempt to estimate the number of CPUs on - the system and add 4 to that number. - - The concurrent threads are used to execute the multitask - prerequisites. Also see the -m option which turns all - tasks into multitasks. - - Sample values: - (no -j) : Allow up to (# of CPUs + 4) number of threads - --jobs : Allow unlimited number of threads - --jobs=1 : Allow only one thread (the main thread) - --jobs=16 : Allow up to 16 concurrent threads - -[--job-stats _level_] - - Display job statistics at the completion of the run. By default, - this will display the requested number of active threads (from the - -j options) and the maximum number of threads in play at any given - time. - - If the optional _level_ is history, then a complete trace - of task history will be displayed on standard output. - -[--libdir _directory_ (-I)] - Add _directory_ to the list of directories searched for require. - -[--multitask (-m)] - Treat all tasks as multitasks. ('make/drake' semantics) - -[--nosearch (-N)] - Do not search for a Rakefile in parent directories. - -[--prereqs (-P)] - Display a list of all tasks and their immediate prerequisites. - -[--quiet (-q)] - Do not echo commands from FileUtils. - -[--rakefile _filename_ (-f)] - Use _filename_ as the name of the rakefile. The default rakefile - names are +rakefile+ and +Rakefile+ (with +rakefile+ taking - precedence). If the rakefile is not found in the current - directory, +rake+ will search parent directories for a match. The - directory where the Rakefile is found will become the current - directory for the actions executed in the Rakefile. - -[--rakelibdir _rakelibdir_ (-R)] - Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') - -[--require _name_ (-r)] - Require _name_ before executing the Rakefile. - -[--rules] - Trace the rules resolution. - -[--silent (-s)] - Like --quiet, but also suppresses the 'in directory' announcement. - -[--suppress-backtrace _pattern_ ] - Line matching the regular expression _pattern_ will be removed - from the backtrace output. Note that the --backtrace option is the - full backtrace without these lines suppressed. - -[--system (-g)] - Use the system wide (global) rakefiles. The project Rakefile is - ignored. By default, the system wide rakefiles are used only if no - project Rakefile is found. On Unix-like system, the system wide - rake files are located in $HOME/.rake. On a windows system they - are stored in $APPDATA/Rake. - -[--no-system (-G)] - Use the project level Rakefile, ignoring the system-wide (global) - rakefiles. - -[--tasks pattern (-T)] - Display a list of the major tasks and their comments. Comments - are defined using the "desc" command. If a pattern is given, then - only tasks matching the pattern are displayed. - -[--trace{=_output_} (-t)] - Turn on invoke/execute tracing. Also enable full backtrace on - errors. The _output_ parameter is optional, but if specified it - controls where the trace output is sent. If _output_ is - stdout, then trace output is directed to standard output. - If _output_ is stderr, or if it is missing, then trace - output is sent to standard error. - -[--verbose (-v)] - Echo the Sys commands to standard output. - -[--version (-V)] - Display the program version and exit. - -[--where pattern (-W)] - Display tasks that match pattern and the file and line - number where the task is defined. By default this option will - display all tasks, not just the tasks that have descriptions. - -[--no-deprecation-warnings (-X)] - Do not display the deprecation warnings. - -== Environment Variables - -[RAKEOPT] - Command line options can be specified in the RAKEOPT - environment variable. These options will be processed as if they - were given on the command line. This is useful for setting default - options that you want to use with every rake invocation. - - For example, setting: - export RAKEOPT="-s --trace" - - would cause rake to run silently with tracing enabled by default. - -In addition, any command line option of the form -VAR=VALUE will be added to the environment hash -ENV and may be tested in the Rakefile. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 deleted file mode 100644 index 39f8bcc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile1 +++ /dev/null @@ -1,38 +0,0 @@ -# Example Rakefile -*- ruby -*- - -task :default => [:main] - -file "a.o" => ["a.c"] do |t| - src = t.name.sub(/\.o$/, '.c') - sh "gcc #{src} -c -o #{t.name}" -end - -file "b.o" => ["b.c"] do |t| - src = t.name.sub(/\.o$/, '.c') - sh "gcc #{src} -c -o #{t.name}" -end - -file "main.o" => ["main.c"] do |t| - src = t.name.sub(/\.o$/, '.c') - sh "gcc #{src} -c -o #{t.name}" -end - -OBJFILES = ["a.o", "b.o", "main.o"] -task :obj => OBJFILES - -file "main" => OBJFILES do |t| - sh "gcc -o #{t.name} main.o a.o b.o" -end - -task :clean do - rm_f FileList['*.o'] - Dir['*~'].each { |fn| rm_f fn } -end - -task :clobber => [:clean] do - rm_f "main" -end - -task :run => ["main"] do - sh "./main" -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 deleted file mode 100644 index 35310ec..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/Rakefile2 +++ /dev/null @@ -1,35 +0,0 @@ -# Example Rakefile -*- ruby -*- -# Using the power of Ruby - -task :default => [:main] - -def ext(fn, newext) - fn.sub(/\.[^.]+$/, newext) -end - -SRCFILES = Dir['*.c'] -OBJFILES = SRCFILES.collect { |fn| ext(fn,".o") } - -OBJFILES.each do |objfile| - srcfile = ext(objfile, ".c") - file objfile => [srcfile] do |t| - sh "gcc #{srcfile} -c -o #{t.name}" - end -end - -file "main" => OBJFILES do |t| - sh "gcc -o #{t.name} main.o a.o b.o" -end - -task :clean do - rm_f FileList['*.o'] - Dir['*~'].each { |fn| rm_f fn } -end - -task :clobber => [:clean] do - rm_f "main" -end - -task :run => ["main"] do - sh "./main" -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c deleted file mode 100644 index 620e6f8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/a.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void a() -{ - printf ("In function a\n"); -} diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c deleted file mode 100644 index 9b24aa1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/b.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void b() -{ - printf ("In function b\n"); -} diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c deleted file mode 100644 index a04558a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/example/main.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -extern void a(); -extern void b(); - -int main () -{ - a(); - b(); - return 0; -} diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc deleted file mode 100644 index 9d592b0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/glossary.rdoc +++ /dev/null @@ -1,42 +0,0 @@ -= Glossary - -action :: - Code to be executed in order to perform a task. Actions in a Rakefile are - specified in a code block. (Usually delimited by +do+/+end+ pairs.) - -execute :: - When a task is executed, all of its actions are performed in the order they - were defined. Note that, unlike invoke, execute always - executes the actions (without invoking or executing the prerequisites). - -file task (Rake::FileTask) :: - A file task is a task whose purpose is to create a file (which has the same - name as the task). When invoked, a file task will only execute if one or - more of the following conditions are true. - - 1. The associated file does not exist. - 2. A prerequisite has a later time stamp than the existing file. - - Because normal Tasks always have the current time as timestamp, a FileTask - that has a normal Task prerequisite will always execute. - -invoke :: - When a task is invoked, first we check to see if it has been invoked before. - If it has been, then nothing else is done. If this is the first time it has - been invoked, then we invoke each of its prerequisites. Finally, we check - to see if we need to execute the actions of this task by calling - Rake::Task#needed?. If the task is needed, we execute its actions. - - NOTE: Prerequisites are still invoked even if the task is not needed. - -prerequisites :: - Every task has a (possibly empty) set of prerequisites. A prerequisite P to - Task T is itself a task that must be invoked before Task T. - -rule :: - A rule is a recipe for synthesizing a task when no task is explicitly - defined. Rules generally synthesize file tasks. - -task (Rake::Task) :: - The basic unit of work in a Rakefile. A task has a name, a set of - prerequisites, and a list of actions to be performed. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb deleted file mode 100644 index 531aa75..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/jamis.rb +++ /dev/null @@ -1,592 +0,0 @@ -# frozen_string_literal: true -module RDoc -module Page - -FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif" - -STYLE = < pre { - padding: 0.5em; - border: 1px dotted black; - background: #FFE; -} - -CSS - -XHTML_PREAMBLE = %{ - -} - -HEADER = XHTML_PREAMBLE + < - - %title% - - - - - - - -ENDHEADER - -FILE_PAGE = < - - - - -
File
%short_name%
- - - - - - - - - -
Path:%full_path% -IF:cvsurl -  (CVS) -ENDIF:cvsurl -
Modified:%dtm_modified%
-
- -
-HTML - -################################################################### - -CLASS_PAGE = < - %classmod%
%full_name% - - - - - - -IF:parent - - - - -ENDIF:parent -
In: -START:infiles -HREF:full_path_url:full_path: -IF:cvsurl - (CVS) -ENDIF:cvsurl -END:infiles -
Parent: -IF:par_url - -ENDIF:par_url -%parent% -IF:par_url - -ENDIF:par_url -
- - - -HTML - -################################################################### - -METHOD_LIST = < -IF:diagram -
- %diagram% -
-ENDIF:diagram - -IF:description -
%description%
-ENDIF:description - -IF:requires -
Required Files
-
    -START:requires -
  • HREF:aref:name:
  • -END:requires -
-ENDIF:requires - -IF:toc -
Contents
- -ENDIF:toc - -IF:methods -
Methods
-
    -START:methods -
  • HREF:aref:name:
  • -END:methods -
-ENDIF:methods - -IF:includes -
Included Modules
-
    -START:includes -
  • HREF:aref:name:
  • -END:includes -
-ENDIF:includes - -START:sections -IF:sectitle - -IF:seccomment -
-%seccomment% -
-ENDIF:seccomment -ENDIF:sectitle - -IF:classlist -
Classes and Modules
- %classlist% -ENDIF:classlist - -IF:constants -
Constants
- -START:constants - - - - - -IF:desc - - - - -ENDIF:desc -END:constants -
%name%=%value%
 %desc%
-ENDIF:constants - -IF:attributes -
Attributes
- -START:attributes - - - - - -END:attributes -
-IF:rw -[%rw%] -ENDIF:rw - %name%%a_desc%
-ENDIF:attributes - -IF:method_list -START:method_list -IF:methods -
%type% %category% methods
-START:methods -
-
-IF:callseq - %callseq% -ENDIF:callseq -IFNOT:callseq - %name%%params% -ENDIF:callseq -IF:codeurl -[ source ] -ENDIF:codeurl -
-IF:m_desc -
- %m_desc% -
-ENDIF:m_desc -IF:aka -
- This method is also aliased as -START:aka - %name% -END:aka -
-ENDIF:aka -IF:sourcecode -
- -
-
-%sourcecode%
-
-
-
-ENDIF:sourcecode -
-END:methods -ENDIF:methods -END:method_list -ENDIF:method_list -END:sections - -HTML - -FOOTER = < - -ENDFOOTER - -BODY = HEADER + < - -
- #{METHOD_LIST} -
- - #{FOOTER} -ENDBODY - -########################## Source code ########################## - -SRC_PAGE = XHTML_PREAMBLE + < -%title% - - - - -
%code%
- - -HTML - -########################## Index ################################ - -FR_INDEX_BODY = < - - - - - - - -
-START:entries -%name%
-END:entries -
- -HTML - -CLASS_INDEX = FILE_INDEX -METHOD_INDEX = FILE_INDEX - -INDEX = XHTML_PREAMBLE + < - - %title% - - - - - - - - - -IF:inline_source - -ENDIF:inline_source -IFNOT:inline_source - - - - -ENDIF:inline_source - - <body bgcolor="white"> - Click <a href="html/index.html">here</a> for a non-frames - version of this page. - </body> - - - - -HTML - -end -end - - diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc deleted file mode 100644 index a9e33d1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/proto_rake.rdoc +++ /dev/null @@ -1,127 +0,0 @@ -= Original Prototype Rake - -This is the original 100 line prototype rake program. - ---- - #!/usr/bin/env ruby - - require 'ftools' - - class Task - TASKS = Hash.new - - attr_reader :prerequisites - - def initialize(task_name) - @name = task_name - @prerequisites = [] - @actions = [] - end - - def enhance(deps=nil, &block) - @prerequisites |= deps if deps - @actions << block if block_given? - self - end - - def name - @name.to_s - end - - def invoke - @prerequisites.each { |n| Task[n].invoke } - execute if needed? - end - - def execute - return if @triggered - @triggered = true - @actions.collect { |act| result = act.call(self) }.last - end - - def needed? - true - end - - def timestamp - Time.now - end - - class << self - def [](task_name) - TASKS[intern(task_name)] or fail "Don't know how to rake #{task_name}" - end - - def define_task(args, &block) - case args - when Hash - fail "Too Many Target Names: #{args.keys.join(' ')}" if args.size > 1 - fail "No Task Name Given" if args.size < 1 - task_name = args.keys[0] - deps = args[task_name] - else - task_name = args - deps = [] - end - deps = deps.collect {|d| intern(d) } - get(task_name).enhance(deps, &block) - end - - def get(task_name) - name = intern(task_name) - TASKS[name] ||= self.new(name) - end - - def intern(task_name) - (Symbol === task_name) ? task_name : task_name.intern - end - end - end - - class FileTask < Task - def needed? - return true unless File.exist?(name) - latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max - return false if latest_prereq.nil? - timestamp < latest_prereq - end - - def timestamp - File.new(name.to_s).mtime - end - end - - def task(args, &block) - Task.define_task(args, &block) - end - - def file(args, &block) - FileTask.define_task(args, &block) - end - - def sys(cmd) - puts cmd - system(cmd) or fail "Command Failed: [#{cmd}]" - end - - def rake - begin - here = Dir.pwd - while ! File.exist?("Rakefile") - Dir.chdir("..") - fail "No Rakefile found" if Dir.pwd == here - here = Dir.pwd - end - puts "(in #{Dir.pwd})" - load "./Rakefile" - ARGV.push("default") if ARGV.size == 0 - ARGV.each { |task_name| Task[task_name].invoke } - rescue Exception => ex - puts "rake aborted ... #{ex.message}" - puts ex.backtrace.find {|str| str =~ /Rakefile/ } || "" - end - end - - if __FILE__ == $0 then - rake - end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 deleted file mode 100644 index c6bfa25..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rake.1 +++ /dev/null @@ -1,156 +0,0 @@ -.Dd June 12, 2016 -.Dt RAKE 1 -.Os rake 11.2.2 -.Sh NAME -.Nm rake -.Nd make-like build utility for Ruby -.Sh SYNOPSIS -.Nm -.Op Fl f Ar rakefile -.Op Ar options -.Ar targets ... -.Sh DESCRIPTION -.Nm -is a -.Xr make 1 Ns -like -build utility for Ruby. -Tasks and dependencies are specified in standard Ruby syntax. -.Sh OPTIONS -.Bl -tag -width Ds -.It Fl m , Fl -multitask -Treat all tasks as multitasks. -.It Fl B , Fl -build-all -Build all prerequisites, including those which are up\-to\-date. -.It Fl j , Fl -jobs Ar num_jobs -Specifies the maximum number of tasks to execute in parallel (default is number of CPU cores + 4). -.El -.Ss Modules -.Bl -tag -width Ds -.It Fl I , Fl -libdir Ar libdir -Include -.Ar libdir -in the search path for required modules. -.It Fl r , Fl -require Ar module -Require -.Ar module -before executing -.Pa rakefile . -.El -.Ss Rakefile location -.Bl -tag -width Ds -.It Fl f , Fl -rakefile Ar filename -Use -.Ar filename -as the rakefile to search for. -.It Fl N , Fl -no-search , Fl -nosearch -Do not search parent directories for the Rakefile. -.It Fl G , Fl -no-system , Fl -nosystem -Use standard project Rakefile search paths, ignore system wide rakefiles. -.It Fl R , Fl -rakelib Ar rakelibdir , Fl -rakelibdir Ar rakelibdir -Auto-import any .rake files in -.Ar rakelibdir -(default is -.Sq rakelib ) -.It Fl g , Fl -system -Use system-wide (global) rakefiles (usually -.Pa ~/.rake/*.rake ) . -.El -.Ss Debugging -.Bl -tag -width Ds -.It Fl -backtrace Ns = Ns Ar out -Enable full backtrace. -.Ar out -can be -.Dv stderr -(default) or -.Dv stdout . -.It Fl t , Fl -trace Ns = Ns Ar out -Turn on invoke/execute tracing, enable full backtrace. -.Ar out -can be -.Dv stderr -(default) or -.Dv stdout . -.It Fl -suppress-backtrace Ar pattern -Suppress backtrace lines matching regexp -.Ar pattern . -Ignored if -.Fl -trace -is on. -.It Fl -rules -Trace the rules resolution. -.It Fl n , Fl -dry-run -Do a dry run without executing actions. -.It Fl T , Fl -tasks Op Ar pattern -Display the tasks (matching optional -.Ar pattern ) -with descriptions, then exit. -.It Fl D , Fl -describe Op Ar pattern -Describe the tasks (matching optional -.Ar pattern ) , -then exit. -.It Fl W , Fl -where Op Ar pattern -Describe the tasks (matching optional -.Ar pattern ) , -then exit. -.It Fl P , Fl -prereqs -Display the tasks and dependencies, then exit. -.It Fl e , Fl -execute Ar code -Execute some Ruby code and exit. -.It Fl p , Fl -execute-print Ar code -Execute some Ruby code, print the result, then exit. -.It Fl E , Fl -execute-continue Ar code -Execute some Ruby code, then continue with normal task processing. -.El -.Ss Information -.Bl -tag -width Ds -.It Fl v , Fl -verbose -Log message to standard output. -.It Fl q , Fl -quiet -Do not log messages to standard output. -.It Fl s , Fl -silent -Like -.Fl -quiet , -but also suppresses the -.Sq in directory -announcement. -.It Fl X , Fl -no-deprecation-warnings -Disable the deprecation warnings. -.It Fl -comments -Show commented tasks only -.It Fl A , Fl -all -Show all tasks, even uncommented ones (in combination with -.Fl T -or -.Fl D ) -.It Fl -job-stats Op Ar level -Display job statistics. -If -.Ar level -is -.Sq history , -displays a complete job list. -.It Fl V , Fl -version -Display the program version. -.It Fl h , Fl H , Fl -help -Display a help message. -.El -.Sh SEE ALSO -The complete documentation for -.Nm rake -has been installed at -.Pa /usr/share/doc/rake-doc/html/index.html . -It is also available online at -.Lk https://ruby.github.io/rake . -.Sh AUTHORS -.An -nosplit -.Nm -was written by -.An Jim Weirich Aq Mt jim@weirichhouse.org . -.Pp -This manual was created by -.An Caitlin Matos Aq Mt caitlin.matos@zoho.com -for the Debian project (but may be used by others). -It was inspired by the manual by -.An Jani Monoses Aq Mt jani@iv.ro -for the Ubuntu project. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc deleted file mode 100644 index 4014306..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rakefile.rdoc +++ /dev/null @@ -1,622 +0,0 @@ -= Rakefile Format - -First of all, there is no special format for a Rakefile. A Rakefile -contains executable Ruby code. Anything legal in a ruby script is -allowed in a Rakefile. - -Now that we understand there is no special syntax in a Rakefile, there -are some conventions that are used in a Rakefile that are a little -unusual in a typical Ruby program. Since a Rakefile is tailored to -specifying tasks and actions, the idioms used in a Rakefile are -designed to support that. - -So, what goes into a Rakefile? - -== Tasks - -Tasks are the main unit of work in a Rakefile. Tasks have a name -(usually given as a symbol or a string), a list of prerequisites (more -symbols or strings) and a list of actions (given as a block). - -=== Simple Tasks - -A task is declared by using the +task+ method. +task+ takes a single -parameter that is the name of the task. - - task :name - -=== Tasks with Prerequisites - -Any prerequisites are given as a list (enclosed in square brackets) -following the name and an arrow (=>). - - task name: [:prereq1, :prereq2] - -*NOTE:* Although this syntax looks a little funky, it is legal -Ruby. We are constructing a hash where the key is :name and the value -for that key is the list of prerequisites. It is equivalent to the -following ... - - hash = Hash.new - hash[:name] = [:prereq1, :prereq2] - task(hash) - -You can also use strings for task names and prerequisites, rake doesn't care. -This is the same task definition: - - task 'name' => %w[prereq1 prereq2] - -As is this: - - task name: %w[prereq1 prereq2] - -We'll prefer this style for regular tasks with prerequisites throughout the -rest of the document. Using an array of strings for the prerequisites means -you will need to make fewer changes if you need to move tasks into namespaces -or perform other refactorings. - -=== Tasks with Actions - -Actions are defined by passing a block to the +task+ method. Any Ruby -code can be placed in the block. The block may reference the task -object via the block parameter. - - task name: [:prereq1, :prereq2] do |t| - # actions (may reference t) - end - -=== Multiple Definitions - -A task may be specified more than once. Each specification adds its -prerequisites and actions to the existing definition. This allows one -part of a rakefile to specify the actions and a different rakefile -(perhaps separately generated) to specify the dependencies. - -For example, the following is equivalent to the single task -specification given above. - - task :name - task name: :prereq1 - task name: %w[prereq2] - task :name do |t| - # actions - end - -== File Tasks - -Some tasks are designed to create a file from one or more other files. -Tasks that generate these files may be skipped if the file already -exists. File tasks are used to specify file creation tasks. - -File tasks are declared using the +file+ method (instead of the +task+ -method). In addition, file tasks are usually named with a string -rather than a symbol. - -The following file task creates a executable program (named +prog+) -given two object files named +a.o+ and +b.o+. The tasks -for creating +a.o+ and +b.o+ are not shown. - - file "prog" => ["a.o", "b.o"] do |t| - sh "cc -o #{t.name} #{t.prerequisites.join(' ')}" - end - -== Directory Tasks - -It is common to need to create directories upon demand. The -+directory+ convenience method is a short-hand for creating a FileTask -that creates the directory. For example, the following declaration -... - - directory "testdata/examples/doc" - -is equivalent to ... - - file "testdata" do |t| mkdir t.name end - file "testdata/examples" => ["testdata"] do |t| mkdir t.name end - file "testdata/examples/doc" => ["testdata/examples"] do |t| mkdir t.name end - -The +directory+ method does not accept prerequisites or actions, but -both prerequisites and actions can be added later. For example ... - - directory "testdata" - file "testdata" => ["otherdata"] - file "testdata" do - cp Dir["standard_data/*.data"], "testdata" - end - -== Tasks with Parallel Prerequisites - -Rake allows parallel execution of prerequisites using the following syntax: - - multitask copy_files: %w[copy_src copy_doc copy_bin] do - puts "All Copies Complete" - end - -In this example, +copy_files+ is a normal rake task. Its actions are -executed whenever all of its prerequisites are done. The big -difference is that the prerequisites (+copy_src+, +copy_bin+ and -+copy_doc+) are executed in parallel. Each of the prerequisites are -run in their own Ruby thread, possibly allowing faster overall runtime. - -=== Secondary Prerequisites - -If any of the primary prerequisites of a multitask have common secondary -prerequisites, all of the primary/parallel prerequisites will wait -until the common prerequisites have been run. - -For example, if the copy_xxx tasks have the -following prerequisites: - - task copy_src: :prep_for_copy - task copy_bin: :prep_for_copy - task copy_doc: :prep_for_copy - -Then the +prep_for_copy+ task is run before starting all the copies in -parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+, -and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is -run only once, even though it is referenced in multiple threads. - -=== Thread Safety - -The Rake internal data structures are thread-safe with respect -to the multitask parallel execution, so there is no need for the user -to do extra synchronization for Rake's benefit. However, if there are -user data structures shared between the parallel prerequisites, the -user must do whatever is necessary to prevent race conditions. - -== Tasks with Arguments - -Prior to version 0.8.0, rake was only able to handle command line -arguments of the form NAME=VALUE that were passed into Rake via the -ENV hash. Many folks had asked for some kind of simple command line -arguments, perhaps using "--" to separate regular task names from -argument values on the command line. The problem is that there was no -easy way to associate positional arguments on the command line with -different tasks. Suppose both tasks :a and :b expect a command line -argument: does the first value go with :a? What if :b is run first? -Should it then get the first command line argument. - -Rake 0.8.0 solves this problem by explicitly passing values directly -to the tasks that need them. For example, if I had a release task -that required a version number, I could say: - - rake release[0.8.2] - -And the string "0.8.2" will be passed to the :release task. Multiple -arguments can be passed by separating them with a comma, for example: - - rake name[john,doe] - -Just a few words of caution. The rake task name and its arguments -need to be a single command line argument to rake. This generally -means no spaces. If spaces are needed, then the entire name + -argument string should be quoted. Something like this: - - rake "name[billy bob, smith]" - -(Quoting rules vary between operating systems and shells, so make sure -you consult the proper docs for your OS/shell). - -=== Tasks that Expect Parameters - -Parameters are only given to tasks that are setup to expect them. In -order to handle named parameters, the task declaration syntax for -tasks has been extended slightly. - -For example, a task that needs a first name and last name might be -declared as: - - task :name, [:first_name, :last_name] - -The first argument is still the name of the task (:name in this case). -The next two arguments are the names of the parameters expected by -:name in an array (:first_name and :last_name in the example). - -To access the values of the parameters, the block defining the task -behaviour can now accept a second parameter: - - task :name, [:first_name, :last_name] do |t, args| - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -The first argument of the block "t" is always bound to the current -task object. The second argument "args" is an open-struct like object -that allows access to the task arguments. Extra command line -arguments to a task are ignored. - -If you wish to specify default values for the arguments, you can use -the with_defaults method in the task body. Here is the above example -where we specify default values for the first and last names: - - task :name, [:first_name, :last_name] do |t, args| - args.with_defaults(:first_name => "John", :last_name => "Dough") - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -=== Tasks that Expect Parameters and Have Prerequisites - -Tasks that use parameters have a slightly different format for -prerequisites. Use the arrow notation to indicate the prerequisites -for tasks with arguments. For example: - - task :name, [:first_name, :last_name] => [:pre_name] do |t, args| - args.with_defaults(:first_name => "John", :last_name => "Dough") - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -=== Tasks that take Variable-length Parameters - -Tasks that need to handle a list of values as a parameter can use the -extras method of the args variable. This allows for tasks that can -loop over a variable number of values, and its compatible with named -parameters as well: - - task :email, [:message] do |t, args| - mail = Mail.new(args.message) - recipients = args.extras - recipients.each do |target| - mail.send_to(target) - end - end - -There is also the convenience method to_a that returns all parameters -in the sequential order they were given, including those associated -with named parameters. - -=== Deprecated Task Parameters Format - -There is an older format for declaring task parameters that omitted -the task argument array and used the :needs keyword to introduce the -dependencies. That format is still supported for compatibility, but -is not recommended for use. The older format may be dropped in future -versions of rake. - -== Accessing Task Programmatically - -Sometimes it is useful to manipulate tasks programmatically in a -Rakefile. To find a task object use Rake::Task.[]. - -=== Programmatic Task Example - -For example, the following Rakefile defines two tasks. The :doit task -simply prints a simple "DONE" message. The :dont class will lookup -the doit class and remove (clear) all of its prerequisites and -actions. - - task :doit do - puts "DONE" - end - - task :dont do - Rake::Task[:doit].clear - end - -Running this example: - - $ rake doit - (in /Users/jim/working/git/rake/x) - DONE - $ rake dont doit - (in /Users/jim/working/git/rake/x) - $ - -The ability to programmatically manipulate tasks gives rake very -powerful meta-programming capabilities w.r.t. task execution, but -should be used with caution. - -== Rules - -When a file is named as a prerequisite, but does not have a file task -defined for it, Rake will attempt to synthesize a task by looking at a -list of rules supplied in the Rakefile. - -Suppose we were trying to invoke task "mycode.o", but no task is -defined for it. But the rakefile has a rule that look like this ... - - rule '.o' => ['.c'] do |t| - sh "cc #{t.source} -c -o #{t.name}" - end - -This rule will synthesize any task that ends in ".o". It has a -prerequisite a source file with an extension of ".c" must exist. If -Rake is able to find a file named "mycode.c", it will automatically -create a task that builds "mycode.o" from "mycode.c". - -If the file "mycode.c" does not exist, rake will attempt -to recursively synthesize a rule for it. - -When a task is synthesized from a rule, the +source+ attribute of the -task is set to the matching source file. This allows us to write -rules with actions that reference the source file. - -=== Advanced Rules - -Any regular expression may be used as the rule pattern. Additionally, -a proc may be used to calculate the name of the source file. This -allows for complex patterns and sources. - -The following rule is equivalent to the example above. - - rule( /\.o$/ => [ - proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') } - ]) do |t| - sh "cc #{t.source} -c -o #{t.name}" - end - -*NOTE:* Because of a _quirk_ in Ruby syntax, parenthesis are -required on *rule* when the first argument is a regular expression. - -The following rule might be used for Java files ... - - rule '.class' => [ - proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') } - ] do |t| - java_compile(t.source, t.name) - end - -*NOTE:* +java_compile+ is a hypothetical method that invokes the -java compiler. - -== Importing Dependencies - -Any ruby file (including other rakefiles) can be included with a -standard Ruby +require+ command. The rules and declarations in the -required file are just added to the definitions already accumulated. - -Because the files are loaded _before_ the rake targets are evaluated, -the loaded files must be "ready to go" when the rake command is -invoked. This makes generated dependency files difficult to use. By -the time rake gets around to updating the dependencies file, it is too -late to load it. - -The +import+ command addresses this by specifying a file to be loaded -_after_ the main rakefile is loaded, but _before_ any targets on the -command line are invoked. In addition, if the file name matches an -explicit task, that task is invoked before loading the file. This -allows dependency files to be generated and used in a single rake -command invocation. - -Example: - - require 'rake/loaders/makefile' - - file ".depends.mf" => [SRC_LIST] do |t| - sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" - end - - import ".depends.mf" - -If ".depends" does not exist, or is out of date w.r.t. the source -files, a new ".depends" file is generated using +makedepend+ before -loading. - -== Comments - -Standard Ruby comments (beginning with "#") can be used anywhere it is -legal in Ruby source code, including comments for tasks and rules. -However, if you wish a task to be described using the "-T" switch, -then you need to use the +desc+ command to describe the task. - -Example: - - desc "Create a distribution package" - task package: %w[ ... ] do ... end - -The "-T" switch (or "--tasks" if you like to spell things out) will -display a list of tasks that have a description. If you use +desc+ to -describe your major tasks, you have a semi-automatic way of generating -a summary of your Rake file. - - $ rake -T - (in /home/.../rake) - rake clean # Remove any temporary products. - rake clobber # Remove any generated file. - rake clobber_rdoc # Remove rdoc products - rake contrib_test # Run tests for contrib_test - rake default # Default Task - rake install # Install the application - rake lines # Count lines in the main rake file - rake rdoc # Build the rdoc HTML Files - rake rerdoc # Force a rebuild of the RDOC files - rake test # Run tests - rake testall # Run all test targets - -Only tasks with descriptions will be displayed with the "-T" switch. -Use "-P" (or "--prereqs") to get a list of all tasks and their -prerequisites. - -== Namespaces - -As projects grow (and along with it, the number of tasks), it is -common for task names to begin to clash. For example, if you might -have a main program and a set of sample programs built by a single -Rakefile. By placing the tasks related to the main program in one -namespace, and the tasks for building the sample programs in a -different namespace, the task names will not interfere with each other. - -For example: - - namespace "main" do - task :build do - # Build the main program - end - end - - namespace "samples" do - task :build do - # Build the sample programs - end - end - - task build: %w[main:build samples:build] - -Referencing a task in a separate namespace can be achieved by -prefixing the task name with the namespace and a colon -(e.g. "main:build" refers to the :build task in the +main+ namespace). -Nested namespaces are supported. - -Note that the name given in the +task+ command is always the unadorned -task name without any namespace prefixes. The +task+ command always -defines a task in the current namespace. - -=== FileTasks - -File task names are not scoped by the namespace command. Since the -name of a file task is the name of an actual file in the file system, -it makes little sense to include file task names in name space. -Directory tasks (created by the +directory+ command) are a type of -file task and are also not affected by namespaces. - -=== Name Resolution - -When looking up a task name, rake will start with the current -namespace and attempt to find the name there. If it fails to find a -name in the current namespace, it will search the parent namespaces -until a match is found (or an error occurs if there is no match). - -The "rake" namespace is a special implicit namespace that refers to -the toplevel names. - -If a task name begins with a "^" character, the name resolution will -start in the parent namespace. Multiple "^" characters are allowed. - -Here is an example file with multiple :run tasks and how various names -resolve in different locations. - - task :run - - namespace "one" do - task :run - - namespace "two" do - task :run - - # :run => "one:two:run" - # "two:run" => "one:two:run" - # "one:two:run" => "one:two:run" - # "one:run" => "one:run" - # "^run" => "one:run" - # "^^run" => "rake:run" (the top level task) - # "rake:run" => "rake:run" (the top level task) - end - - # :run => "one:run" - # "two:run" => "one:two:run" - # "^run" => "rake:run" - end - - # :run => "rake:run" - # "one:run" => "one:run" - # "one:two:run" => "one:two:run" - -== FileLists - -FileLists are the way Rake manages lists of files. You can treat a -FileList as an array of strings for the most part, but FileLists -support some additional operations. - -=== Creating a FileList - -Creating a file list is easy. Just give it the list of file names: - - fl = FileList['file1.rb', file2.rb'] - -Or give it a glob pattern: - - fl = FileList['*.rb'] - -== Odds and Ends - -=== do/end versus { } - -Blocks may be specified with either a +do+/+end+ pair, or with curly -braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the -actions for tasks and rules. Because the rakefile idiom tends to -leave off parentheses on the task/file/rule methods, unusual -ambiguities can arise when using curly braces. - -For example, suppose that the method +object_files+ returns a list of -object files in a project. Now we use +object_files+ as the -prerequisites in a rule specified with actions in curly braces. - - # DON'T DO THIS! - file "prog" => object_files { - # Actions are expected here (but it doesn't work)! - } - -Because curly braces have a higher precedence than +do+/+end+, the -block is associated with the +object_files+ method rather than the -+file+ method. - -This is the proper way to specify the task ... - - # THIS IS FINE - file "prog" => object_files do - # Actions go here - end - -== Rakefile Path - -When issuing the +rake+ command in a terminal, Rake will look -for a Rakefile in the current directory. If a Rakefile is not found, -it will search parent directories until one is found. - -For example, if a Rakefile resides in the +project/+ directory, -moving deeper into the project's directory tree will not have an adverse -effect on rake tasks: - - $ pwd - /home/user/project - - $ cd lib/foo/bar - $ pwd - /home/user/project/lib/foo/bar - - $ rake run_pwd - /home/user/project - -As far as rake is concerned, all tasks are run from the directory in -which the Rakefile resides. - -=== Multiple Rake Files - -Not all tasks need to be included in a single Rakefile. Additional -rake files (with the file extension "+.rake+") may be placed in -+rakelib+ directory located at the top level of a project (i.e. -the same directory that contains the main +Rakefile+). - -Also, rails projects may include additional rake files in the -+lib/tasks+ directory. - -=== Clean and Clobber Tasks - -Through require 'rake/clean' Rake provides +clean+ and +clobber+ -tasks: - -+clean+ :: - Clean up the project by deleting scratch files and backup files. Add files - to the +CLEAN+ FileList to have the +clean+ target handle them. - -+clobber+ :: - Clobber all generated and non-source files in a project. The task depends - on +clean+, so all the +CLEAN+ files will be deleted as well as files in the - +CLOBBER+ FileList. The intent of this task is to return a project to its - pristine, just unpacked state. - -You can add file names or glob patterns to both the +CLEAN+ and +CLOBBER+ -lists. - -=== Phony Task - -The phony task can be used as a dependency to allow file-based tasks to use -non-file-based-tasks as prerequisites without forcing them to rebuild. You -can require 'rake/phony' to add the +phony+ task. - ----- - -== See - -* README.rdoc -- Main documentation for Rake. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc deleted file mode 100644 index 0e1c338..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/doc/rational.rdoc +++ /dev/null @@ -1,151 +0,0 @@ -= Why rake? - -Ok, let me state from the beginning that I never intended to write this -code. I'm not convinced it is useful, and I'm not convinced anyone -would even be interested in it. All I can say is that Why's onion truck -must by been passing through the Ohio valley. - -What am I talking about? ... A Ruby version of Make. - -See, I can sense you cringing already, and I agree. The world certainly -doesn't need yet another reworking of the "make" program. I mean, we -already have "ant". Isn't that enough? - -It started yesterday. I was helping a coworker fix a problem in one of -the Makefiles we use in our project. Not a particularly tough problem, -but during the course of the conversation I began lamenting some of the -shortcomings of make. In particular, in one of my makefiles I wanted to -determine the name of a file dynamically and had to resort to some -simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you -could just use Ruby inside a Makefile" I said. - -My coworker (a recent convert to Ruby) agreed, but wondered what it -would look like. So I sketched the following on the whiteboard... - - "What if you could specify the make tasks in Ruby, like this ..." - - task "build" do - java_compile(...args, etc ...) - end - - "The task function would register "build" as a target to be made, - and the block would be the action executed whenever the build - system determined that it was time to do the build target." - -We agreed that would be cool, but writing make from scratch would be WAY -too much work. And that was the end of that! - -... Except I couldn't get the thought out of my head. What exactly -would be needed to make the about syntax work as a make file? Hmmm, you -would need to register the tasks, you need some way of specifying -dependencies between tasks, and some way of kicking off the process. -Hey! What if we did ... and fifteen minutes later I had a working -prototype of Ruby make, complete with dependencies and actions. - -I showed the code to my coworker and we had a good laugh. It was just -about a page worth of code that reproduced an amazing amount of the -functionality of make. We were both truly stunned with the power of -Ruby. - -But it didn't do everything make did. In particular, it didn't have -timestamp based file dependencies (where a file is rebuilt if any of its -prerequisite files have a later timestamp). Obviously THAT would be a -pain to add and so Ruby Make would remain an interesting experiment. - -... Except as I walked back to my desk, I started thinking about what -file based dependencies would really need. Rats! I was hooked again, -and by adding a new class and two new methods, file/timestamp -dependencies were implemented. - -Ok, now I was really hooked. Last night (during CSI!) I massaged the -code and cleaned it up a bit. The result is a bare-bones replacement -for make in exactly 100 lines of code. - -For the curious, you can see it at ... -* doc/proto_rake.rdoc - -Oh, about the name. When I wrote the example Ruby Make task on my -whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ... -Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves -and Rake would clean them up ... or something like that. Anyways, the -name stuck. - -Some quick examples ... - -A simple task to delete backup files ... - - task :clean do - Dir['*~'].each {|fn| rm fn rescue nil} - end - -Note that task names are symbols (they are slightly easier to type -than quoted strings ... but you may use quoted string if you would -rather). Rake makes the methods of the FileUtils module directly -available, so we take advantage of the rm command. Also note -the use of "rescue nil" to trap and ignore errors in the rm -command. - -To run it, just type "rake clean". Rake will automatically find a -Rakefile in the current directory (or above!) and will invoke the -targets named on the command line. If there are no targets explicitly -named, rake will invoke the task "default". - -Here's another task with dependencies ... - - task :clobber => [:clean] do - rm_r "tempdir" - end - -Task :clobber depends upon task :clean, so :clean will be run before -:clobber is executed. - -Files are specified by using the "file" command. It is similar to the -task command, except that the task name represents a file, and the task -will be run only if the file doesn't exist, or if its modification time -is earlier than any of its prerequisites. - -Here is a file based dependency that will compile "hello.cc" to -"hello.o". - - file "hello.cc" - file "hello.o" => ["hello.cc"] do |t| - srcfile = t.name.sub(/\.o$/, ".cc") - sh %{g++ #{srcfile} -c -o #{t.name}} - end - -I normally specify file tasks with string (rather than symbols). Some -file names can't be represented by symbols. Plus it makes the -distinction between them more clear to the casual reader. - -Currently writing a task for each and every file in the project would be -tedious at best. I envision a set of libraries to make this job -easier. For instance, perhaps something like this ... - - require 'rake/ctools' - Dir['*.c'].each do |fn| - c_source_file(fn) - end - -where "c_source_file" will create all the tasks need to compile all the -C source files in a directory. Any number of useful libraries could be -created for rake. - -That's it. There's no documentation (other than whats in this -message). Does this sound interesting to anyone? If so, I'll continue -to clean it up and write it up and publish it on RAA. Otherwise, I'll -leave it as an interesting exercise and a tribute to the power of Ruby. - -Why /might/ rake be interesting to Ruby programmers. I don't know, -perhaps ... - -* No weird make syntax (only weird Ruby syntax :-) -* No need to edit or read XML (a la ant) -* Platform independent build scripts. -* Will run anywhere Ruby exists, so no need to have "make" installed. - If you stay away from the "sys" command and use things like - 'ftools', you can have a perfectly platform independent - build script. Also rake is only 100 lines of code, so it can - easily be packaged along with the rest of your code. - -So ... Sorry for the long rambling message. Like I said, I never -intended to write this code at all. diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake deleted file mode 100755 index a00975f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/exe/rake +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby - -#-- -# Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -#++ - -require "rake" - -Rake.application.run diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb deleted file mode 100644 index 2006fba..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true -#-- -# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -#++ - -module Rake; end - -require_relative "rake/version" - -require "rbconfig" -require "fileutils" -require "singleton" -require "monitor" -require "optparse" - -require_relative "rake/ext/string" - -require_relative "rake/win32" - -require_relative "rake/linked_list" -require_relative "rake/cpu_counter" -require_relative "rake/scope" -require_relative "rake/task_argument_error" -require_relative "rake/rule_recursion_overflow_error" -require_relative "rake/rake_module" -require_relative "rake/trace_output" -require_relative "rake/pseudo_status" -require_relative "rake/task_arguments" -require_relative "rake/invocation_chain" -require_relative "rake/task" -require_relative "rake/file_task" -require_relative "rake/file_creation_task" -require_relative "rake/multi_task" -require_relative "rake/dsl_definition" -require_relative "rake/file_utils_ext" -require_relative "rake/file_list" -require_relative "rake/default_loader" -require_relative "rake/early_time" -require_relative "rake/late_time" -require_relative "rake/name_space" -require_relative "rake/task_manager" -require_relative "rake/application" -require_relative "rake/backtrace" - -# :stopdoc: -# -# Some top level Constants. - -FileList = Rake::FileList -RakeFileUtils = Rake::FileUtilsExt diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb deleted file mode 100644 index 87ae47b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/application.rb +++ /dev/null @@ -1,854 +0,0 @@ -# frozen_string_literal: true -require "optparse" - -require_relative "task_manager" -require_relative "file_list" -require_relative "thread_pool" -require_relative "thread_history_display" -require_relative "trace_output" -require_relative "win32" - -module Rake - - CommandLineOptionError = Class.new(StandardError) - - ## - # Rake main application object. When invoking +rake+ from the - # command line, a Rake::Application object is created and run. - - class Application - include TaskManager - include TraceOutput - - # The name of the application (typically 'rake') - attr_reader :name - - # The original directory where rake was invoked. - attr_reader :original_dir - - # Name of the actual rakefile used. - attr_reader :rakefile - - # Number of columns on the terminal - attr_accessor :terminal_columns - - # List of the top level task names (task names from the command line). - attr_reader :top_level_tasks - - # Override the detected TTY output state (mostly for testing) - attr_writer :tty_output - - DEFAULT_RAKEFILES = [ - "rakefile", - "Rakefile", - "rakefile.rb", - "Rakefile.rb" - ].freeze - - # Initialize a Rake::Application object. - def initialize - super - @name = "rake" - @rakefiles = DEFAULT_RAKEFILES.dup - @rakefile = nil - @pending_imports = [] - @imported = [] - @loaders = {} - @default_loader = Rake::DefaultLoader.new - @original_dir = Dir.pwd - @top_level_tasks = [] - add_loader("rb", DefaultLoader.new) - add_loader("rf", DefaultLoader.new) - add_loader("rake", DefaultLoader.new) - @tty_output = STDOUT.tty? - @terminal_columns = ENV["RAKE_COLUMNS"].to_i - - set_default_options - end - - # Run the Rake application. The run method performs the following - # three steps: - # - # * Initialize the command line options (+init+). - # * Define the tasks (+load_rakefile+). - # * Run the top level tasks (+top_level+). - # - # If you wish to build a custom rake command, you should call - # +init+ on your application. Then define any tasks. Finally, - # call +top_level+ to run your top level tasks. - def run(argv = ARGV) - standard_exception_handling do - init "rake", argv - load_rakefile - top_level - end - end - - # Initialize the command line parameters and app name. - def init(app_name="rake", argv = ARGV) - standard_exception_handling do - @name = app_name - begin - args = handle_options argv - rescue ArgumentError - # Backward compatibility for capistrano - args = handle_options - end - load_debug_at_stop_feature - collect_command_line_tasks(args) - end - end - - def load_debug_at_stop_feature - return unless ENV["RAKE_DEBUG"] - require "debug/session" - DEBUGGER__::start no_sigint_hook: true, nonstop: true - Rake::Task.prepend Module.new { - def execute(*) - exception = DEBUGGER__::SESSION.capture_exception_frames(/(exe|bin|lib)\/rake/) do - super - end - - if exception - STDERR.puts exception.message - DEBUGGER__::SESSION.enter_postmortem_session exception - raise exception - end - end - } - rescue LoadError - end - private :load_debug_at_stop_feature - - # Find the rakefile and then load it and any pending imports. - def load_rakefile - standard_exception_handling do - raw_load_rakefile - end - end - - # Run the top level tasks of a Rake application. - def top_level - run_with_threads do - if options.show_tasks - display_tasks_and_comments - elsif options.show_prereqs - display_prerequisites - else - top_level_tasks.each { |task_name| invoke_task(task_name) } - end - end - end - - # Run the given block with the thread startup and shutdown. - def run_with_threads - thread_pool.gather_history if options.job_stats == :history - - yield - - thread_pool.join if defined?(@thread_pool) - if options.job_stats - stats = thread_pool.statistics - puts "Maximum active threads: #{stats[:max_active_threads]} + main" - puts "Total threads in play: #{stats[:total_threads_in_play]} + main" - end - ThreadHistoryDisplay.new(thread_pool.history).show if - options.job_stats == :history - end - - # Add a loader to handle imported files ending in the extension - # +ext+. - def add_loader(ext, loader) - ext = ".#{ext}" unless ext =~ /^\./ - @loaders[ext] = loader - end - - # Application options from the command line - def options - @options ||= Struct.new( - :always_multitask, :backtrace, :build_all, :dryrun, - :ignore_deprecate, :ignore_system, :job_stats, :load_system, - :nosearch, :rakelib, :show_all_tasks, :show_prereqs, - :show_task_pattern, :show_tasks, :silent, :suppress_backtrace_pattern, - :thread_pool_size, :trace, :trace_output, :trace_rules - ).new - end - - # Return the thread pool used for multithreaded processing. - def thread_pool # :nodoc: - @thread_pool ||= ThreadPool.new(options.thread_pool_size || Rake.suggested_thread_count-1) - end - - # internal ---------------------------------------------------------------- - - # Invokes a task with arguments that are extracted from +task_string+ - def invoke_task(task_string) # :nodoc: - name, args = parse_task_string(task_string) - t = self[name] - t.invoke(*args) - end - - def parse_task_string(string) # :nodoc: - /^([^\[]+)(?:\[(.*)\])$/ =~ string.to_s - - name = $1 - remaining_args = $2 - - return string, [] unless name - return name, [] if remaining_args.empty? - - args = [] - - begin - /\s*((?:[^\\,]|\\.)*?)\s*(?:,\s*(.*))?$/ =~ remaining_args - - remaining_args = $2 - args << $1.gsub(/\\(.)/, '\1') - end while remaining_args - - return name, args - end - - # Provide standard exception handling for the given block. - def standard_exception_handling # :nodoc: - yield - rescue SystemExit - # Exit silently with current status - raise - rescue OptionParser::InvalidOption => ex - $stderr.puts ex.message - exit(false) - rescue Exception => ex - # Exit with error message - display_error_message(ex) - exit_because_of_exception(ex) - end - - # Exit the program because of an unhandled exception. - # (may be overridden by subclasses) - def exit_because_of_exception(ex) # :nodoc: - exit(false) - end - - # Display the error message that caused the exception. - def display_error_message(ex) # :nodoc: - trace "#{name} aborted!" - display_exception_details(ex) - trace "Tasks: #{ex.chain}" if has_chain?(ex) - trace "(See full trace by running task with --trace)" unless - options.backtrace - end - - def display_exception_details(ex) # :nodoc: - display_exception_details_seen << ex - - display_exception_message_details(ex) - display_exception_backtrace(ex) if ex.backtrace - display_cause_details(ex.cause) if has_cause?(ex) - end - - def display_cause_details(ex) # :nodoc: - return if display_exception_details_seen.include? ex - - trace "\nCaused by:" - display_exception_details(ex) - end - - def display_exception_details_seen # :nodoc: - Thread.current[:rake_display_exception_details_seen] ||= [] - end - - def has_cause?(ex) # :nodoc: - ex.respond_to?(:cause) && ex.cause - end - - def display_exception_message_details(ex) # :nodoc: - if ex.instance_of?(RuntimeError) - trace ex.message - elsif ex.respond_to?(:detailed_message) - trace "#{ex.class.name}: #{ex.detailed_message(highlight: false)}" - else - trace "#{ex.class.name}: #{ex.message}" - end - end - - def display_exception_backtrace(ex) # :nodoc: - if options.backtrace - trace ex.backtrace.join("\n") - else - trace Backtrace.collapse(ex.backtrace).join("\n") - end - end - - # Warn about deprecated usage. - # - # Example: - # Rake.application.deprecate("import", "Rake.import", caller.first) - # - def deprecate(old_usage, new_usage, call_site) # :nodoc: - unless options.ignore_deprecate - $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + - "Please use '#{new_usage}' instead.\n" + - " at #{call_site}" - end - end - - # Does the exception have a task invocation chain? - def has_chain?(exception) # :nodoc: - exception.respond_to?(:chain) && exception.chain - end - private :has_chain? - - # True if one of the files in RAKEFILES is in the current directory. - # If a match is found, it is copied into @rakefile. - def have_rakefile # :nodoc: - @rakefiles.each do |fn| - if File.exist?(fn) - others = FileList.glob(fn, File::FNM_CASEFOLD) - return others.size == 1 ? others.first : fn - elsif fn == "" - return fn - end - end - return nil - end - - # True if we are outputting to TTY, false otherwise - def tty_output? # :nodoc: - @tty_output - end - - # We will truncate output if we are outputting to a TTY or if we've been - # given an explicit column width to honor - def truncate_output? # :nodoc: - tty_output? || @terminal_columns.nonzero? - end - - # Display the tasks and comments. - def display_tasks_and_comments # :nodoc: - displayable_tasks = tasks.select { |t| - (options.show_all_tasks || t.comment) && - t.name =~ options.show_task_pattern - } - case options.show_tasks - when :tasks - width = displayable_tasks.map { |t| t.name_with_args.length }.max || 10 - if truncate_output? - max_column = terminal_width - name.size - width - 7 - else - max_column = nil - end - - displayable_tasks.each do |t| - printf("#{name} %-#{width}s # %s\n", - t.name_with_args, - max_column ? truncate(t.comment, max_column) : t.comment) - end - when :describe - displayable_tasks.each do |t| - puts "#{name} #{t.name_with_args}" - comment = t.full_comment || "" - comment.split("\n").each do |line| - puts " #{line}" - end - puts - end - when :lines - displayable_tasks.each do |t| - t.locations.each do |loc| - printf "#{name} %-30s %s\n", t.name_with_args, loc - end - end - else - fail "Unknown show task mode: '#{options.show_tasks}'" - end - end - - def terminal_width # :nodoc: - if @terminal_columns.nonzero? - result = @terminal_columns - else - result = unix? ? dynamic_width : 80 - end - (result < 10) ? 80 : result - rescue - 80 - end - - # Calculate the dynamic width of the - def dynamic_width # :nodoc: - @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) - end - - def dynamic_width_stty # :nodoc: - %x{stty size 2>/dev/null}.split[1].to_i - end - - def dynamic_width_tput # :nodoc: - %x{tput cols 2>/dev/null}.to_i - end - - def unix? # :nodoc: - RbConfig::CONFIG["host_os"] =~ - /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i - end - - def windows? # :nodoc: - Win32.windows? - end - - def truncate(string, width) # :nodoc: - if string.nil? - "" - elsif string.length <= width - string - else - (string[0, width - 3] || "") + "..." - end - end - - # Display the tasks and prerequisites - def display_prerequisites # :nodoc: - tasks.each do |t| - puts "#{name} #{t.name}" - t.prerequisites.each { |pre| puts " #{pre}" } - end - end - - def trace(*strings) # :nodoc: - options.trace_output ||= $stderr - trace_on(options.trace_output, *strings) - end - - def sort_options(options) # :nodoc: - options.sort_by { |opt| - opt.select { |o| o.is_a?(String) && o =~ /^-/ }.map(&:downcase).sort.reverse - } - end - private :sort_options - - # A list of all the standard options used in rake, suitable for - # passing to OptionParser. - def standard_rake_options # :nodoc: - sort_options( - [ - ["--all", "-A", - "Show all tasks, even uncommented ones (in combination with -T or -D)", - lambda { |value| - options.show_all_tasks = value - } - ], - ["--backtrace=[OUT]", - "Enable full backtrace. OUT can be stderr (default) or stdout.", - lambda { |value| - options.backtrace = true - select_trace_output(options, "backtrace", value) - } - ], - ["--build-all", "-B", - "Build all prerequisites, including those which are up-to-date.", - lambda { |value| - options.build_all = true - } - ], - ["--comments", - "Show commented tasks only", - lambda { |value| - options.show_all_tasks = !value - } - ], - ["--describe", "-D [PATTERN]", - "Describe the tasks (matching optional PATTERN), then exit.", - lambda { |value| - select_tasks_to_show(options, :describe, value) - } - ], - ["--directory", "-C [DIRECTORY]", - "Change to DIRECTORY before doing anything.", - lambda { |value| - Dir.chdir value - @original_dir = Dir.pwd - } - ], - ["--dry-run", "-n", - "Do a dry run without executing actions.", - lambda { |value| - Rake.verbose(true) - Rake.nowrite(true) - options.dryrun = true - options.trace = true - } - ], - ["--execute", "-e CODE", - "Execute some Ruby code and exit.", - lambda { |value| - eval(value) - exit - } - ], - ["--execute-print", "-p CODE", - "Execute some Ruby code, print the result, then exit.", - lambda { |value| - puts eval(value) - exit - } - ], - ["--execute-continue", "-E CODE", - "Execute some Ruby code, " + - "then continue with normal task processing.", - lambda { |value| eval(value) } - ], - ["--jobs", "-j [NUMBER]", - "Specifies the maximum number of tasks to execute in parallel. " + - "(default is number of CPU cores + 4)", - lambda { |value| - if value.nil? || value == "" - value = Float::INFINITY - elsif value =~ /^\d+$/ - value = value.to_i - else - value = Rake.suggested_thread_count - end - value = 1 if value < 1 - options.thread_pool_size = value - 1 - } - ], - ["--job-stats [LEVEL]", - "Display job statistics. " + - "LEVEL=history displays a complete job list", - lambda { |value| - if value =~ /^history/i - options.job_stats = :history - else - options.job_stats = true - end - } - ], - ["--libdir", "-I LIBDIR", - "Include LIBDIR in the search path for required modules.", - lambda { |value| $:.push(value) } - ], - ["--multitask", "-m", - "Treat all tasks as multitasks.", - lambda { |value| options.always_multitask = true } - ], - ["--no-search", "--nosearch", - "-N", "Do not search parent directories for the Rakefile.", - lambda { |value| options.nosearch = true } - ], - ["--prereqs", "-P", - "Display the tasks and dependencies, then exit.", - lambda { |value| options.show_prereqs = true } - ], - ["--quiet", "-q", - "Do not log messages to standard output.", - lambda { |value| Rake.verbose(false) } - ], - ["--rakefile", "-f [FILENAME]", - "Use FILENAME as the rakefile to search for.", - lambda { |value| - value ||= "" - @rakefiles.clear - @rakefiles << value - } - ], - ["--rakelibdir", "--rakelib", "-R RAKELIBDIR", - "Auto-import any .rake files in RAKELIBDIR. " + - "(default is 'rakelib')", - lambda { |value| - options.rakelib = value.split(File::PATH_SEPARATOR) - } - ], - ["--require", "-r MODULE", - "Require MODULE before executing rakefile.", - lambda { |value| - begin - require value - rescue LoadError => ex - begin - rake_require value - rescue LoadError - raise ex - end - end - } - ], - ["--rules", - "Trace the rules resolution.", - lambda { |value| options.trace_rules = true } - ], - ["--silent", "-s", - "Like --quiet, but also suppresses the " + - "'in directory' announcement.", - lambda { |value| - Rake.verbose(false) - options.silent = true - } - ], - ["--suppress-backtrace PATTERN", - "Suppress backtrace lines matching regexp PATTERN. " + - "Ignored if --trace is on.", - lambda { |value| - options.suppress_backtrace_pattern = Regexp.new(value) - } - ], - ["--system", "-g", - "Using system wide (global) rakefiles " + - "(usually '~/.rake/*.rake').", - lambda { |value| options.load_system = true } - ], - ["--no-system", "--nosystem", "-G", - "Use standard project Rakefile search paths, " + - "ignore system wide rakefiles.", - lambda { |value| options.ignore_system = true } - ], - ["--tasks", "-T [PATTERN]", - "Display the tasks (matching optional PATTERN) " + - "with descriptions, then exit. " + - "-AT combination displays all the tasks, including those without descriptions.", - lambda { |value| - select_tasks_to_show(options, :tasks, value) - } - ], - ["--trace=[OUT]", "-t", - "Turn on invoke/execute tracing, enable full backtrace. " + - "OUT can be stderr (default) or stdout.", - lambda { |value| - options.trace = true - options.backtrace = true - select_trace_output(options, "trace", value) - Rake.verbose(true) - } - ], - ["--verbose", "-v", - "Log message to standard output.", - lambda { |value| Rake.verbose(true) } - ], - ["--version", "-V", - "Display the program version.", - lambda { |value| - puts "rake, version #{Rake::VERSION}" - exit - } - ], - ["--where", "-W [PATTERN]", - "Describe the tasks (matching optional PATTERN), then exit.", - lambda { |value| - select_tasks_to_show(options, :lines, value) - options.show_all_tasks = true - } - ], - ["--no-deprecation-warnings", "-X", - "Disable the deprecation warnings.", - lambda { |value| - options.ignore_deprecate = true - } - ], - ]) - end - - def select_tasks_to_show(options, show_tasks, value) # :nodoc: - options.show_tasks = show_tasks - options.show_task_pattern = Regexp.new(value || "") - Rake::TaskManager.record_task_metadata = true - end - private :select_tasks_to_show - - def select_trace_output(options, trace_option, value) # :nodoc: - value = value.strip unless value.nil? - case value - when "stdout" - options.trace_output = $stdout - when "stderr", nil - options.trace_output = $stderr - else - fail CommandLineOptionError, - "Unrecognized --#{trace_option} option '#{value}'" - end - end - private :select_trace_output - - # Read and handle the command line options. Returns the command line - # arguments that we didn't understand, which should (in theory) be just - # task names and env vars. - def handle_options(argv) # :nodoc: - set_default_options - - OptionParser.new do |opts| - opts.banner = "#{Rake.application.name} [-f rakefile] {options} targets..." - opts.separator "" - opts.separator "Options are ..." - - opts.on_tail("-h", "--help", "-H", "Display this help message.") do - puts opts - exit - end - - standard_rake_options.each { |args| opts.on(*args) } - opts.environment("RAKEOPT") - end.parse(argv) - end - - # Similar to the regular Ruby +require+ command, but will check - # for *.rake files in addition to *.rb files. - def rake_require(file_name, paths=$LOAD_PATH, loaded=$LOADED_FEATURES) # :nodoc: - fn = file_name + ".rake" - return false if loaded.include?(fn) - paths.each do |path| - full_path = File.join(path, fn) - if File.exist?(full_path) - Rake.load_rakefile(full_path) - loaded << fn - return true - end - end - fail LoadError, "Can't find #{file_name}" - end - - def find_rakefile_location # :nodoc: - here = Dir.pwd - until (fn = have_rakefile) - Dir.chdir("..") - return nil if Dir.pwd == here || options.nosearch - here = Dir.pwd - end - [fn, here] - ensure - Dir.chdir(Rake.original_dir) - end - - def print_rakefile_directory(location) # :nodoc: - $stderr.puts "(in #{Dir.pwd})" unless - options.silent or original_dir == location - end - - def raw_load_rakefile # :nodoc: - rakefile, location = find_rakefile_location - if (!options.ignore_system) && - (options.load_system || rakefile.nil?) && - system_dir && File.directory?(system_dir) - print_rakefile_directory(location) - glob("#{system_dir}/*.rake") do |name| - add_import name - end - else - fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if - rakefile.nil? - @rakefile = rakefile - Dir.chdir(location) - print_rakefile_directory(location) - Rake.load_rakefile(File.expand_path(@rakefile)) if - @rakefile && @rakefile != "" - options.rakelib.each do |rlib| - glob("#{rlib}/*.rake") do |name| - add_import name - end - end - end - load_imports - end - - def glob(path, &block) # :nodoc: - FileList.glob(path.tr("\\", "/")).each(&block) - end - private :glob - - # The directory path containing the system wide rakefiles. - def system_dir # :nodoc: - @system_dir ||= ENV["RAKE_SYSTEM"] || standard_system_dir - end - - # The standard directory containing system wide rake files. - if Win32.windows? - def standard_system_dir #:nodoc: - Win32.win32_system_dir - end - else - def standard_system_dir #:nodoc: - File.join(Dir.home, ".rake") - end - end - private :standard_system_dir - - # Collect the list of tasks on the command line. If no tasks are - # given, return a list containing only the default task. - # Environmental assignments are processed at this time as well. - # - # `args` is the list of arguments to peruse to get the list of tasks. - # It should be the command line that was given to rake, less any - # recognised command-line options, which OptionParser.parse will - # have taken care of already. - def collect_command_line_tasks(args) # :nodoc: - @top_level_tasks = [] - args.each do |arg| - if arg =~ /^(\w+)=(.*)$/m - ENV[$1] = $2 - else - @top_level_tasks << arg unless arg =~ /^-/ - end - end - @top_level_tasks.push(default_task_name) if @top_level_tasks.empty? - end - - # Default task name ("default"). - # (May be overridden by subclasses) - def default_task_name # :nodoc: - "default" - end - - # Add a file to the list of files to be imported. - def add_import(fn) # :nodoc: - @pending_imports << fn - end - - # Load the pending list of imported files. - def load_imports # :nodoc: - while fn = @pending_imports.shift - next if @imported.member?(fn) - fn_task = lookup(fn) and fn_task.invoke - ext = File.extname(fn) - loader = @loaders[ext] || @default_loader - loader.load(fn) - if fn_task = lookup(fn) and fn_task.needed? - fn_task.reenable - fn_task.invoke - loader.load(fn) - end - @imported << fn - end - end - - def rakefile_location(backtrace=caller) # :nodoc: - backtrace.map { |t| t[/([^:]+):/, 1] } - - re = /^#{@rakefile}$/ - re = /#{re.source}/i if windows? - - backtrace.find { |str| str =~ re } || "" - end - - def set_default_options # :nodoc: - options.always_multitask = false - options.backtrace = false - options.build_all = false - options.dryrun = false - options.ignore_deprecate = false - options.ignore_system = false - options.job_stats = false - options.load_system = false - options.nosearch = false - options.rakelib = %w[rakelib] - options.show_all_tasks = false - options.show_prereqs = false - options.show_task_pattern = nil - options.show_tasks = nil - options.silent = false - options.suppress_backtrace_pattern = nil - options.thread_pool_size = Rake.suggested_thread_count - options.trace = false - options.trace_output = $stderr - options.trace_rules = false - end - - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb deleted file mode 100644 index c87f2f9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/backtrace.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -module Rake - module Backtrace # :nodoc: all - SYS_KEYS = RbConfig::CONFIG.keys.grep(/(?:[a-z]prefix|libdir)\z/) - SYS_PATHS = RbConfig::CONFIG.values_at(*SYS_KEYS).uniq + - [ File.join(File.dirname(__FILE__), "..") ] - - SUPPRESSED_PATHS = SYS_PATHS. - map { |s| s.tr("\\", "/") }. - map { |f| File.expand_path(f) }. - reject { |s| s.nil? || s =~ /^ *$/ } - SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|") - SUPPRESSED_PATHS_RE << "|^" - SUPPRESSED_PATHS_RE << "|^org\\/jruby\\/\\w+\\.java" if - Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == "jruby" - - SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i - - def self.collapse(backtrace) - pattern = Rake.application.options.suppress_backtrace_pattern || - SUPPRESS_PATTERN - backtrace.reject { |elem| elem =~ pattern } - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb deleted file mode 100644 index c49adf9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/clean.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true -# The 'rake/clean' file defines two file lists (CLEAN and CLOBBER) and -# two rake tasks (:clean and :clobber). -# -# [:clean] Clean up the project by deleting scratch files and backup -# files. Add files to the CLEAN file list to have the :clean -# target handle them. -# -# [:clobber] Clobber all generated and non-source files in a project. -# The task depends on :clean, so all the clean files will -# be deleted as well as files in the CLOBBER file list. -# The intent of this task is to return a project to its -# pristine, just unpacked state. - -require_relative "../rake" - -# :stopdoc: - -module Rake - module Cleaner - extend FileUtils - - module_function - - def cleanup_files(file_names) - file_names.each do |file_name| - cleanup(file_name) - end - end - - def cleanup(file_name, **opts) - begin - opts = { verbose: Rake.application.options.trace }.merge(opts) - rm_r file_name, **opts - rescue StandardError => ex - puts "Failed to remove #{file_name}: #{ex}" unless file_already_gone?(file_name) - end - end - - def file_already_gone?(file_name) - return false if File.exist?(file_name) - - path = file_name - prev = nil - - while path = File.dirname(path) - return false if cant_be_deleted?(path) - break if [prev, "."].include?(path) - prev = path - end - true - end - private_class_method :file_already_gone? - - def cant_be_deleted?(path_name) - File.exist?(path_name) && - (!File.readable?(path_name) || !File.executable?(path_name)) - end - private_class_method :cant_be_deleted? - end -end - -CLEAN = ::Rake::FileList["**/*~", "**/*.bak", "**/core"] -CLEAN.clear_exclude.exclude { |fn| - fn.pathmap("%f").downcase == "core" && File.directory?(fn) -} - -desc "Remove any temporary products." -task :clean do - Rake::Cleaner.cleanup_files(CLEAN) -end - -CLOBBER = ::Rake::FileList.new - -desc "Remove any generated files." -task clobber: [:clean] do - Rake::Cleaner.cleanup_files(CLOBBER) -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb deleted file mode 100644 index eddb77e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cloneable.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -module Rake - ## - # Mixin for creating easily cloned objects. - - module Cloneable # :nodoc: - # The hook that is invoked by 'clone' and 'dup' methods. - def initialize_copy(source) - super - source.instance_variables.each do |var| - src_value = source.instance_variable_get(var) - value = src_value.clone rescue src_value - instance_variable_set(var, value) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb deleted file mode 100644 index 75cc0d0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/cpu_counter.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Based on a script at: - # http://stackoverflow.com/questions/891537/ruby-detect-number-of-cpus-installed - class CpuCounter # :nodoc: all - def self.count - new.count_with_default - end - - def count_with_default(default=4) - count || default - rescue StandardError - default - end - - begin - require "etc" - rescue LoadError - else - if Etc.respond_to?(:nprocessors) - def count - return Etc.nprocessors - end - end - end - end -end - -unless Rake::CpuCounter.method_defined?(:count) - Rake::CpuCounter.class_eval <<-'end;', __FILE__, __LINE__+1 - require 'rbconfig' - - def count - if RUBY_PLATFORM == 'java' - count_via_java_runtime - else - case RbConfig::CONFIG['host_os'] - when /linux/ - count_via_cpuinfo - when /darwin|bsd/ - count_via_sysctl - when /mswin|mingw/ - count_via_win32 - else - # Try everything - count_via_win32 || - count_via_sysctl || - count_via_cpuinfo - end - end - end - - def count_via_java_runtime - Java::Java.lang.Runtime.getRuntime.availableProcessors - rescue StandardError - nil - end - - def count_via_win32 - # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0 - result = run_win32( - 'powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores ' \ - '| Select-Object -Property NumberOfCores"' - ) - if !result || $?.exitstatus != 0 - # fallback to deprecated wmic for older systems - result = run_win32("wmic cpu get NumberOfCores") - end - - # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n" - # wmic: "NumberOfCores \n\n4 \n\n\n\n" - result.scan(/\d+/).map(&:to_i).reduce(:+) if result - rescue StandardError - nil - end - - def count_via_cpuinfo - open('/proc/cpuinfo') { |f| f.readlines }.grep(/processor/).size - rescue StandardError - nil - end - - def count_via_sysctl - run 'sysctl', '-n', 'hw.ncpu' - end - - def run(command, *args) - cmd = resolve_command(command) - if cmd - IO.popen [cmd, *args] do |io| - io.read.to_i - end - else - nil - end - end - - def run_win32(command, *args) - IO.popen(command, &:read) - rescue Errno::ENOENT - nil - end - - def resolve_command(command) - look_for_command("/usr/sbin", command) || - look_for_command("/sbin", command) || - in_path_command(command) - end - - def look_for_command(dir, command) - path = File.join(dir, command) - File.exist?(path) ? path : nil - end - - def in_path_command(command) - IO.popen ['which', command] do |io| - io.eof? ? nil : command - end - end - end; -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb deleted file mode 100644 index d3b4650..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/default_loader.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Default Rakefile loader used by +import+. - class DefaultLoader - - ## - # Loads a rakefile into the current application from +fn+ - - def load(fn) - Rake.load_rakefile(File.expand_path(fn)) - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb deleted file mode 100644 index 3799068..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/dsl_definition.rb +++ /dev/null @@ -1,196 +0,0 @@ -# frozen_string_literal: true -# Rake DSL functions. -require_relative "file_utils_ext" - -module Rake - - ## - # DSL is a module that provides #task, #desc, #namespace, etc. Use this - # when you'd like to use rake outside the top level scope. - # - # For a Rakefile you run from the command line this module is automatically - # included. - - module DSL - - #-- - # Include the FileUtils file manipulation functions in the top - # level module, but mark them private so that they don't - # unintentionally define methods on other objects. - #++ - - include FileUtilsExt - private(*FileUtils.instance_methods(false)) - private(*FileUtilsExt.instance_methods(false)) - - private - - # :call-seq: - # task(task_name) - # task(task_name: dependencies) - # task(task_name, arguments => dependencies) - # - # Declare a basic task. The +task_name+ is always the first argument. If - # the task name contains a ":" it is defined in that namespace. - # - # The +dependencies+ may be a single task name or an Array of task names. - # The +argument+ (a single name) or +arguments+ (an Array of names) define - # the arguments provided to the task. - # - # The task, argument and dependency names may be either symbols or - # strings. - # - # A task with a single dependency: - # - # task clobber: %w[clean] do - # rm_rf "html" - # end - # - # A task with an argument and a dependency: - # - # task :package, [:version] => :test do |t, args| - # # ... - # end - # - # To invoke this task from the command line: - # - # $ rake package[1.2.3] - # - def task(*args, &block) # :doc: - Rake::Task.define_task(*args, &block) - end - - # Declare a file task. - # - # Example: - # file "config.cfg" => ["config.template"] do - # open("config.cfg", "w") do |outfile| - # open("config.template") do |infile| - # while line = infile.gets - # outfile.puts line - # end - # end - # end - # end - # - def file(*args, &block) # :doc: - Rake::FileTask.define_task(*args, &block) - end - - # Declare a file creation task. - # (Mainly used for the directory command). - def file_create(*args, &block) - Rake::FileCreationTask.define_task(*args, &block) - end - - # Declare a set of files tasks to create the given directories on - # demand. - # - # Example: - # directory "testdata/doc" - # - def directory(*args, &block) # :doc: - args = args.flat_map { |arg| arg.is_a?(FileList) ? arg.to_a.flatten : arg } - result = file_create(*args, &block) - dir, _ = *Rake.application.resolve_args(args) - dir = Rake.from_pathname(dir) - Rake.each_dir_parent(dir) do |d| - file_create d do |t| - mkdir_p t.name unless File.exist?(t.name) - end - end - result - end - - # Declare a task that performs its prerequisites in - # parallel. Multitasks does *not* guarantee that its prerequisites - # will execute in any given order (which is obvious when you think - # about it) - # - # Example: - # multitask deploy: %w[deploy_gem deploy_rdoc] - # - def multitask(*args, &block) # :doc: - Rake::MultiTask.define_task(*args, &block) - end - - # Create a new rake namespace and use it for evaluating the given - # block. Returns a NameSpace object that can be used to lookup - # tasks defined in the namespace. - # - # Example: - # - # ns = namespace "nested" do - # # the "nested:run" task - # task :run - # end - # task_run = ns[:run] # find :run in the given namespace. - # - # Tasks can also be defined in a namespace by using a ":" in the task - # name: - # - # task "nested:test" do - # # ... - # end - # - def namespace(name=nil, &block) # :doc: - name = name.to_s if name.kind_of?(Symbol) - name = name.to_str if name.respond_to?(:to_str) - unless name.kind_of?(String) || name.nil? - raise ArgumentError, "Expected a String or Symbol for a namespace name" - end - Rake.application.in_namespace(name, &block) - end - - # Declare a rule for auto-tasks. - # - # Example: - # rule '.o' => '.c' do |t| - # sh 'cc', '-c', '-o', t.name, t.source - # end - # - def rule(*args, &block) # :doc: - Rake::Task.create_rule(*args, &block) - end - - # Describes the next rake task. Duplicate descriptions are discarded. - # Descriptions are shown with rake -T (up to the first - # sentence) and rake -D (the entire description). - # - # Example: - # desc "Run the Unit Tests" - # task test: [:build] do - # # ... run tests - # end - # - def desc(description) # :doc: - Rake.application.last_description = description - end - - # Import the partial Rakefiles +fn+. Imported files are loaded - # _after_ the current file is completely loaded. This allows the - # import statement to appear anywhere in the importing file, and yet - # allowing the imported files to depend on objects defined in the - # importing file. - # - # A common use of the import statement is to include files - # containing dependency declarations. - # - # See also the --rakelibdir command line option. - # - # Example: - # import ".depend", "my_rules" - # - def import(*fns) # :doc: - fns.each do |fn| - Rake.application.add_import(fn) - end - end - end - extend FileUtilsExt -end - -# Extend the main object with the DSL commands. This allows top-level -# calls to task, etc. to work from a Rakefile without polluting the -# object inheritance tree. -self.extend Rake::DSL diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb deleted file mode 100644 index 80cc6bf..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/early_time.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true -module Rake - - # EarlyTime is a fake timestamp that occurs _before_ any other time value. - class EarlyTime - include Comparable - include Singleton - - ## - # The EarlyTime always comes before +other+! - - def <=>(other) - -1 - end - - def to_s # :nodoc: - "" - end - end - - EARLY = EarlyTime.instance -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb deleted file mode 100644 index 226f212..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/core.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true -class Module - # Check for an existing method in the current class before extending. If - # the method already exists, then a warning is printed and the extension is - # not added. Otherwise the block is yielded and any definitions in the - # block will take effect. - # - # Usage: - # - # class String - # rake_extension("xyz") do - # def xyz - # ... - # end - # end - # end - # - def rake_extension(method) # :nodoc: - if method_defined?(method) - $stderr.puts "WARNING: Possible conflict with Rake extension: " + - "#{self}##{method} already exists" - else - yield - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb deleted file mode 100644 index c82f532..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/ext/string.rb +++ /dev/null @@ -1,176 +0,0 @@ -# frozen_string_literal: true -require_relative "core" - -class String - - rake_extension("ext") do - # Replace the file extension with +newext+. If there is no extension on - # the string, append the new extension to the end. If the new extension - # is not given, or is the empty string, remove any existing extension. - # - # +ext+ is a user added method for the String class. - # - # This String extension comes from Rake - def ext(newext="") - return self.dup if [".", ".."].include? self - if newext != "" - newext = "." + newext unless newext =~ /^\./ - end - self.chomp(File.extname(self)) << newext - end - end - - rake_extension("pathmap") do - # Explode a path into individual components. Used by +pathmap+. - # - # This String extension comes from Rake - def pathmap_explode - head, tail = File.split(self) - return [self] if head == self - return [tail] if head == "." || tail == "/" - return [head, tail] if head == "/" - return head.pathmap_explode + [tail] - end - protected :pathmap_explode - - # Extract a partial path from the path. Include +n+ directories from the - # front end (left hand side) if +n+ is positive. Include |+n+| - # directories from the back end (right hand side) if +n+ is negative. - # - # This String extension comes from Rake - def pathmap_partial(n) - dirs = File.dirname(self).pathmap_explode - partial_dirs = - if n > 0 - dirs[0...n] - elsif n < 0 - dirs.reverse[0...-n].reverse - else - "." - end - File.join(partial_dirs) - end - protected :pathmap_partial - - # Perform the pathmap replacement operations on the given path. The - # patterns take the form 'pat1,rep1;pat2,rep2...'. - # - # This String extension comes from Rake - def pathmap_replace(patterns, &block) - result = self - patterns.split(";").each do |pair| - pattern, replacement = pair.split(",") - pattern = Regexp.new(pattern) - if replacement == "*" && block_given? - result = result.sub(pattern, &block) - elsif replacement - result = result.sub(pattern, replacement) - else - result = result.sub(pattern, "") - end - end - result - end - protected :pathmap_replace - - # Map the path according to the given specification. The specification - # controls the details of the mapping. The following special patterns are - # recognized: - # - # %p :: The complete path. - # %f :: The base file name of the path, with its file extension, - # but without any directories. - # %n :: The file name of the path without its file extension. - # %d :: The directory list of the path. - # %x :: The file extension of the path. An empty string if there - # is no extension. - # %X :: Everything *but* the file extension. - # %s :: The alternate file separator if defined, otherwise use # - # the standard file separator. - # %% :: A percent sign. - # - # The %d specifier can also have a numeric prefix (e.g. '%2d'). - # If the number is positive, only return (up to) +n+ directories in the - # path, starting from the left hand side. If +n+ is negative, return (up - # to) +n+ directories from the right hand side of the path. - # - # Examples: - # - # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b' - # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d' - # - # Also the %d, %p, %f, %n, - # %x, and %X operators can take a pattern/replacement - # argument to perform simple string substitutions on a particular part of - # the path. The pattern and replacement are separated by a comma and are - # enclosed by curly braces. The replacement spec comes after the % - # character but before the operator letter. (e.g. "%{old,new}d"). - # Multiple replacement specs should be separated by semi-colons (e.g. - # "%{old,new;src,bin}d"). - # - # Regular expressions may be used for the pattern, and back refs may be - # used in the replacement text. Curly braces, commas and semi-colons are - # excluded from both the pattern and replacement text (let's keep parsing - # reasonable). - # - # For example: - # - # "src/org/onestepback/proj/A.java".pathmap("%{^src,class}X.class") - # - # returns: - # - # "class/org/onestepback/proj/A.class" - # - # If the replacement text is '*', then a block may be provided to perform - # some arbitrary calculation for the replacement. - # - # For example: - # - # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext| - # ext.downcase - # } - # - # Returns: - # - # "/path/to/file.txt" - # - # This String extension comes from Rake - def pathmap(spec=nil, &block) - return self if spec.nil? - result = "".dup - spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| - case frag - when "%f" - result << File.basename(self) - when "%n" - result << File.basename(self).ext - when "%d" - result << File.dirname(self) - when "%x" - result << File.extname(self) - when "%X" - result << self.ext - when "%p" - result << self - when "%s" - result << (File::ALT_SEPARATOR || File::SEPARATOR) - when "%-" - # do nothing - when "%%" - result << "%" - when /%(-?\d+)d/ - result << pathmap_partial($1.to_i) - when /^%\{([^}]*)\}(\d*[dpfnxX])/ - patterns, operator = $1, $2 - result << pathmap("%" + operator).pathmap_replace(patterns, &block) - when /^%/ - fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" - else - result << frag - end - end - result - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb deleted file mode 100644 index 3df254c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_creation_task.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -require_relative "file_task" -require_relative "early_time" - -module Rake - - # A FileCreationTask is a file task that when used as a dependency will be - # needed if and only if the file has not been created. Once created, it is - # not re-triggered if any of its dependencies are newer, nor does trigger - # any rebuilds of tasks that depend on it whenever it is updated. - # - class FileCreationTask < FileTask - # Is this file task needed? Yes if it doesn't exist. - def needed? - !File.exist?(name) - end - - # Time stamp for file creation task. This time stamp is earlier - # than any other time stamp. - def timestamp - Rake::EARLY - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb deleted file mode 100644 index 76078d2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_list.rb +++ /dev/null @@ -1,435 +0,0 @@ -# frozen_string_literal: true -require_relative "cloneable" -require_relative "file_utils_ext" -require_relative "ext/string" - -module Rake - - ## - # A FileList is essentially an array with a few helper methods defined to - # make file manipulation a bit easier. - # - # FileLists are lazy. When given a list of glob patterns for possible files - # to be included in the file list, instead of searching the file structures - # to find the files, a FileList holds the pattern for latter use. - # - # This allows us to define a number of FileList to match any number of - # files, but only search out the actual files when then FileList itself is - # actually used. The key is that the first time an element of the - # FileList/Array is requested, the pending patterns are resolved into a real - # list of file names. - # - class FileList - - include Cloneable - - # == Method Delegation - # - # The lazy evaluation magic of FileLists happens by implementing all the - # array specific methods to call +resolve+ before delegating the heavy - # lifting to an embedded array object (@items). - # - # In addition, there are two kinds of delegation calls. The regular kind - # delegates to the @items array and returns the result directly. Well, - # almost directly. It checks if the returned value is the @items object - # itself, and if so will return the FileList object instead. - # - # The second kind of delegation call is used in methods that normally - # return a new Array object. We want to capture the return value of these - # methods and wrap them in a new FileList object. We enumerate these - # methods in the +SPECIAL_RETURN+ list below. - - # List of array methods (that are not in +Object+) that need to be - # delegated. - ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map(&:to_s) - - # List of additional methods that must be delegated. - MUST_DEFINE = %w[inspect <=>] - - # List of methods that should not be delegated here (we define special - # versions of them explicitly below). - MUST_NOT_DEFINE = %w[to_a to_ary partition * <<] - - # List of delegated methods that return new array values which need - # wrapping. - SPECIAL_RETURN = %w[ - map collect sort sort_by select find_all reject grep - compact flatten uniq values_at - + - & | - ] - - DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).map(&:to_s).sort.uniq - - # Now do the delegation. - DELEGATING_METHODS.each do |sym| - if SPECIAL_RETURN.include?(sym) - ln = __LINE__ + 1 - class_eval %{ - def #{sym}(*args, &block) - resolve - result = @items.send(:#{sym}, *args, &block) - self.class.new.import(result) - end - }, __FILE__, ln - else - ln = __LINE__ + 1 - class_eval %{ - def #{sym}(*args, &block) - resolve - result = @items.send(:#{sym}, *args, &block) - result.object_id == @items.object_id ? self : result - end - }, __FILE__, ln - end - end - - GLOB_PATTERN = %r{[*?\[\{]} - - # Create a file list from the globbable patterns given. If you wish to - # perform multiple includes or excludes at object build time, use the - # "yield self" pattern. - # - # Example: - # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb') - # - # pkg_files = FileList.new('lib/**/*') do |fl| - # fl.exclude(/\bCVS\b/) - # end - # - def initialize(*patterns) - @pending_add = [] - @pending = false - @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup - @exclude_procs = DEFAULT_IGNORE_PROCS.dup - @items = [] - patterns.each { |pattern| include(pattern) } - yield self if block_given? - end - - # Add file names defined by glob patterns to the file list. If an array - # is given, add each element of the array. - # - # Example: - # file_list.include("*.java", "*.cfg") - # file_list.include %w( math.c lib.h *.o ) - # - def include(*filenames) - # TODO: check for pending - filenames.each do |fn| - if fn.respond_to? :to_ary - include(*fn.to_ary) - else - @pending_add << Rake.from_pathname(fn) - end - end - @pending = true - self - end - alias :add :include - - # Register a list of file name patterns that should be excluded from the - # list. Patterns may be regular expressions, glob patterns or regular - # strings. In addition, a block given to exclude will remove entries that - # return true when given to the block. - # - # Note that glob patterns are expanded against the file system. If a file - # is explicitly added to a file list, but does not exist in the file - # system, then an glob pattern in the exclude list will not exclude the - # file. - # - # Examples: - # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c'] - # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c'] - # - # If "a.c" is a file, then ... - # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c'] - # - # If "a.c" is not a file, then ... - # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c'] - # - def exclude(*patterns, &block) - patterns.each do |pat| - if pat.respond_to? :to_ary - exclude(*pat.to_ary) - else - @exclude_patterns << Rake.from_pathname(pat) - end - end - @exclude_procs << block if block_given? - resolve_exclude unless @pending - self - end - - # Clear all the exclude patterns so that we exclude nothing. - def clear_exclude - @exclude_patterns = [] - @exclude_procs = [] - self - end - - # A FileList is equal through array equality. - def ==(array) - to_ary == array - end - - # Return the internal array object. - def to_a - resolve - @items - end - - # Return the internal array object. - def to_ary - to_a - end - - # Lie about our class. - def is_a?(klass) - klass == Array || super(klass) - end - alias kind_of? is_a? - - # Redefine * to return either a string or a new file list. - def *(other) - result = @items * other - case result - when Array - self.class.new.import(result) - else - result - end - end - - def <<(obj) - resolve - @items << Rake.from_pathname(obj) - self - end - - # Resolve all the pending adds now. - def resolve - if @pending - @pending = false - @pending_add.each do |fn| resolve_add(fn) end - @pending_add = [] - resolve_exclude - end - self - end - - def resolve_add(fn) # :nodoc: - case fn - when GLOB_PATTERN - add_matching(fn) - else - self << fn - end - end - private :resolve_add - - def resolve_exclude # :nodoc: - reject! { |fn| excluded_from_list?(fn) } - self - end - private :resolve_exclude - - # Return a new FileList with the results of running +sub+ against each - # element of the original list. - # - # Example: - # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o'] - # - def sub(pat, rep) - inject(self.class.new) { |res, fn| res << fn.sub(pat, rep) } - end - - # Return a new FileList with the results of running +gsub+ against each - # element of the original list. - # - # Example: - # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\") - # => ['lib\\test\\file', 'x\\y'] - # - def gsub(pat, rep) - inject(self.class.new) { |res, fn| res << fn.gsub(pat, rep) } - end - - # Same as +sub+ except that the original file list is modified. - def sub!(pat, rep) - each_with_index { |fn, i| self[i] = fn.sub(pat, rep) } - self - end - - # Same as +gsub+ except that the original file list is modified. - def gsub!(pat, rep) - each_with_index { |fn, i| self[i] = fn.gsub(pat, rep) } - self - end - - # Apply the pathmap spec to each of the included file names, returning a - # new file list with the modified paths. (See String#pathmap for - # details.) - def pathmap(spec=nil, &block) - collect { |fn| fn.pathmap(spec, &block) } - end - - # Return a new FileList with String#ext method applied to - # each member of the array. - # - # This method is a shortcut for: - # - # array.collect { |item| item.ext(newext) } - # - # +ext+ is a user added method for the Array class. - def ext(newext="") - collect { |fn| fn.ext(newext) } - end - - # Grep each of the files in the filelist using the given pattern. If a - # block is given, call the block on each matching line, passing the file - # name, line number, and the matching line of text. If no block is given, - # a standard emacs style file:linenumber:line message will be printed to - # standard out. Returns the number of matched items. - def egrep(pattern, *options) - matched = 0 - each do |fn| - begin - File.open(fn, "r", *options) do |inf| - count = 0 - inf.each do |line| - count += 1 - if pattern.match(line) - matched += 1 - if block_given? - yield fn, count, line - else - puts "#{fn}:#{count}:#{line}" - end - end - end - end - rescue StandardError => ex - $stderr.puts "Error while processing '#{fn}': #{ex}" - end - end - matched - end - - # Return a new file list that only contains file names from the current - # file list that exist on the file system. - def existing - select { |fn| File.exist?(fn) }.uniq - end - - # Modify the current file list so that it contains only file name that - # exist on the file system. - def existing! - resolve - @items = @items.select { |fn| File.exist?(fn) }.uniq - self - end - - # FileList version of partition. Needed because the nested arrays should - # be FileLists in this version. - def partition(&block) # :nodoc: - resolve - result = @items.partition(&block) - [ - self.class.new.import(result[0]), - self.class.new.import(result[1]), - ] - end - - # Convert a FileList to a string by joining all elements with a space. - def to_s - resolve - self.join(" ") - end - - # Add matching glob patterns. - def add_matching(pattern) - self.class.glob(pattern).each do |fn| - self << fn unless excluded_from_list?(fn) - end - end - private :add_matching - - # Should the given file name be excluded from the list? - # - # NOTE: This method was formerly named "exclude?", but Rails - # introduced an exclude? method as an array method and setup a - # conflict with file list. We renamed the method to avoid - # confusion. If you were using "FileList#exclude?" in your user - # code, you will need to update. - def excluded_from_list?(fn) - return true if @exclude_patterns.any? do |pat| - case pat - when Regexp - fn =~ pat - when GLOB_PATTERN - flags = File::FNM_PATHNAME - # Ruby <= 1.9.3 does not support File::FNM_EXTGLOB - flags |= File::FNM_EXTGLOB if defined? File::FNM_EXTGLOB - File.fnmatch?(pat, fn, flags) - else - fn == pat - end - end - @exclude_procs.any? { |p| p.call(fn) } - end - - DEFAULT_IGNORE_PATTERNS = [ - /(^|[\/\\])CVS([\/\\]|$)/, - /(^|[\/\\])\.svn([\/\\]|$)/, - /\.bak$/, - /~$/ - ] - DEFAULT_IGNORE_PROCS = [ - proc { |fn| fn =~ /(^|[\/\\])core$/ && !File.directory?(fn) } - ] - - def import(array) # :nodoc: - @items = array - self - end - - class << self - # Create a new file list including the files listed. Similar to: - # - # FileList.new(*args) - def [](*args) - new(*args) - end - - # Get a sorted list of files matching the pattern. This method - # should be preferred to Dir[pattern] and Dir.glob(pattern) because - # the files returned are guaranteed to be sorted. - def glob(pattern, *args) - Dir.glob(pattern, *args).sort - end - end - end -end - -module Rake - class << self - - # Yield each file or directory component. - def each_dir_parent(dir) # :nodoc: - old_length = nil - while dir != "." && dir.length != old_length - yield(dir) - old_length = dir.length - dir = File.dirname(dir) - end - end - - # Convert Pathname and Pathname-like objects to strings; - # leave everything else alone - def from_pathname(path) # :nodoc: - path = path.to_path if path.respond_to?(:to_path) - path = path.to_str if path.respond_to?(:to_str) - path - end - end -end # module Rake diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb deleted file mode 100644 index 8c398bc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_task.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true -require_relative "task" -require_relative "early_time" - -module Rake - - # A FileTask is a task that includes time based dependencies. If any of a - # FileTask's prerequisites have a timestamp that is later than the file - # represented by this task, then the file must be rebuilt (using the - # supplied actions). - # - class FileTask < Task - - # Is this file task needed? Yes if it doesn't exist, or if its time stamp - # is out of date. - def needed? - begin - out_of_date?(File.mtime(name)) || @application.options.build_all - rescue Errno::ENOENT - true - end - end - - # Time stamp for file task. - def timestamp - begin - File.mtime(name) - rescue Errno::ENOENT - Rake::LATE - end - end - - private - - # Are there any prerequisites with a later time than the given time stamp? - def out_of_date?(stamp) - all_prerequisite_tasks.any? { |prereq| - prereq_task = application[prereq, @scope] - if prereq_task.instance_of?(Rake::FileTask) - prereq_task.timestamp > stamp || @application.options.build_all - else - prereq_task.timestamp > stamp - end - } - end - - # ---------------------------------------------------------------- - # Task class methods. - # - class << self - # Apply the scope to the task name according to the rules for this kind - # of task. File based tasks ignore the scope when creating the name. - def scope_name(scope, task_name) - Rake.from_pathname(task_name) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb deleted file mode 100644 index 1510d95..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils.rb +++ /dev/null @@ -1,132 +0,0 @@ -# frozen_string_literal: true -require "rbconfig" -require "fileutils" - -#-- -# This a FileUtils extension that defines several additional commands to be -# added to the FileUtils utility functions. -module FileUtils - # Path to the currently running Ruby program - RUBY = ENV["RUBY"] || File.join( - RbConfig::CONFIG["bindir"], - RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]). - sub(/.*\s.*/m, '"\&"') - - # Run the system command +cmd+. If multiple arguments are given the command - # is run directly (without the shell, same semantics as Kernel::exec and - # Kernel::system). - # - # It is recommended you use the multiple argument form over interpolating - # user input for both usability and security reasons. With the multiple - # argument form you can easily process files with spaces or other shell - # reserved characters in them. With the multiple argument form your rake - # tasks are not vulnerable to users providing an argument like - # ; rm # -rf /. - # - # If a block is given, upon command completion the block is called with an - # OK flag (true on a zero exit status) and a Process::Status object. - # Without a block a RuntimeError is raised when the command exits non-zero. - # - # Examples: - # - # sh 'ls -ltr' - # - # sh 'ls', 'file with spaces' - # - # # check exit status after command runs - # sh %{grep pattern file} do |ok, res| - # if !ok - # puts "pattern not found (status = #{res.exitstatus})" - # end - # end - # - def sh(*cmd, &block) - options = (Hash === cmd.last) ? cmd.pop : {} - shell_runner = block_given? ? block : create_shell_runner(cmd) - - set_verbose_option(options) - verbose = options.delete :verbose - noop = options.delete(:noop) || Rake::FileUtilsExt.nowrite_flag - - Rake.rake_output_message sh_show_command cmd if verbose - - unless noop - res = (Hash === cmd.last) ? system(*cmd) : system(*cmd, options) - status = $? - status = Rake::PseudoStatus.new(1) if !res && status.nil? - shell_runner.call(res, status) - end - end - - def create_shell_runner(cmd) # :nodoc: - show_command = sh_show_command cmd - lambda do |ok, status| - ok or - fail "Command failed with status (#{status.exitstatus}): " + - "[#{show_command}]" - end - end - private :create_shell_runner - - def sh_show_command(cmd) # :nodoc: - cmd = cmd.dup - - if Hash === cmd.first - env = cmd.first - env = env.map { |name, value| "#{name}=#{value}" }.join " " - cmd[0] = env - end - - cmd.join " " - end - private :sh_show_command - - def set_verbose_option(options) # :nodoc: - unless options.key? :verbose - options[:verbose] = - (Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT) || - Rake::FileUtilsExt.verbose_flag - end - end - private :set_verbose_option - - # Run a Ruby interpreter with the given arguments. - # - # Example: - # ruby %{-pe '$_.upcase!' 1 - sh(RUBY, *args, **options, &block) - else - sh("#{RUBY} #{args.first}", **options, &block) - end - end - - LN_SUPPORTED = [true] - - # Attempt to do a normal file link, but fall back to a copy if the link - # fails. - def safe_ln(*args, **options) - if LN_SUPPORTED[0] - begin - return options.empty? ? ln(*args) : ln(*args, **options) - rescue StandardError, NotImplementedError - LN_SUPPORTED[0] = false - end - end - options.empty? ? cp(*args) : cp(*args, **options) - end - - # Split a file path into individual directory names. - # - # Example: - # split_all("a/b/c") => ['a', 'b', 'c'] - # - def split_all(path) - head, tail = File.split(path) - return [tail] if head == "." || tail == "/" - return [head, tail] if head == "/" - return split_all(head) + [tail] - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb deleted file mode 100644 index 687d805..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/file_utils_ext.rb +++ /dev/null @@ -1,134 +0,0 @@ -# frozen_string_literal: true -require_relative "file_utils" - -module Rake - # - # FileUtilsExt provides a custom version of the FileUtils methods - # that respond to the verbose and nowrite - # commands. - # - module FileUtilsExt - include FileUtils - - class << self - attr_accessor :verbose_flag, :nowrite_flag - end - - DEFAULT = Object.new - - FileUtilsExt.verbose_flag = DEFAULT - FileUtilsExt.nowrite_flag = false - - FileUtils.commands.each do |name| - opts = FileUtils.options_of name - default_options = [] - if opts.include?("verbose") - default_options << "verbose: FileUtilsExt.verbose_flag" - end - if opts.include?("noop") - default_options << "noop: FileUtilsExt.nowrite_flag" - end - - next if default_options.empty? - module_eval(<<-EOS, __FILE__, __LINE__ + 1) - def #{name}(*args, **options, &block) - super(*args, - #{default_options.join(', ')}, - **options, &block) - end - EOS - end - - # Get/set the verbose flag controlling output from the FileUtils - # utilities. If verbose is true, then the utility method is - # echoed to standard output. - # - # Examples: - # verbose # return the current value of the - # # verbose flag - # verbose(v) # set the verbose flag to _v_. - # verbose(v) { code } # Execute code with the verbose flag set - # # temporarily to _v_. Return to the - # # original value when code is done. - def verbose(value=nil) - oldvalue = FileUtilsExt.verbose_flag - FileUtilsExt.verbose_flag = value unless value.nil? - if block_given? - begin - yield - ensure - FileUtilsExt.verbose_flag = oldvalue - end - end - FileUtilsExt.verbose_flag - end - - # Get/set the nowrite flag controlling output from the FileUtils - # utilities. If verbose is true, then the utility method is - # echoed to standard output. - # - # Examples: - # nowrite # return the current value of the - # # nowrite flag - # nowrite(v) # set the nowrite flag to _v_. - # nowrite(v) { code } # Execute code with the nowrite flag set - # # temporarily to _v_. Return to the - # # original value when code is done. - def nowrite(value=nil) - oldvalue = FileUtilsExt.nowrite_flag - FileUtilsExt.nowrite_flag = value unless value.nil? - if block_given? - begin - yield - ensure - FileUtilsExt.nowrite_flag = oldvalue - end - end - oldvalue - end - - # Use this function to prevent potentially destructive ruby code - # from running when the :nowrite flag is set. - # - # Example: - # - # when_writing("Building Project") do - # project.build - # end - # - # The following code will build the project under normal - # conditions. If the nowrite(true) flag is set, then the example - # will print: - # - # DRYRUN: Building Project - # - # instead of actually building the project. - # - def when_writing(msg=nil) - if FileUtilsExt.nowrite_flag - $stderr.puts "DRYRUN: #{msg}" if msg - else - yield - end - end - - # Send the message to the default rake output (which is $stderr). - def rake_output_message(message) - $stderr.puts(message) - end - - # Check that the options do not contain options not listed in - # +optdecl+. An ArgumentError exception is thrown if non-declared - # options are found. - def rake_check_options(options, *optdecl) - h = options.dup - optdecl.each do |name| - h.delete name - end - raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless - h.empty? - end - - extend self - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb deleted file mode 100644 index 44a9954..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_chain.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true -module Rake - - # InvocationChain tracks the chain of task invocations to detect - # circular dependencies. - class InvocationChain < LinkedList - - # Is the invocation already in the chain? - def member?(invocation) - head == invocation || tail.member?(invocation) - end - - # Append an invocation to the chain of invocations. It is an error - # if the invocation already listed. - def append(invocation) - if member?(invocation) - fail RuntimeError, "Circular dependency detected: #{to_s} => #{invocation}" - end - conj(invocation) - end - - # Convert to string, ie: TOP => invocation => invocation - def to_s - "#{prefix}#{head}" - end - - # Class level append. - def self.append(invocation, chain) - chain.append(invocation) - end - - private - - def prefix - "#{tail} => " - end - - # Null object for an empty chain. - class EmptyInvocationChain < LinkedList::EmptyLinkedList - @parent = InvocationChain - - def member?(obj) - false - end - - def append(invocation) - conj(invocation) - end - - def to_s - "TOP" - end - end - - EMPTY = EmptyInvocationChain.new - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb deleted file mode 100644 index b0d307a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/invocation_exception_mixin.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -module Rake - module InvocationExceptionMixin - # Return the invocation chain (list of Rake tasks) that were in - # effect when this exception was detected by rake. May be null if - # no tasks were active. - def chain - @rake_invocation_chain ||= nil - end - - # Set the invocation chain in effect when this exception was - # detected. - def chain=(value) - @rake_invocation_chain = value - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb deleted file mode 100644 index 8fe0249..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/late_time.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -module Rake - # LateTime is a fake timestamp that occurs _after_ any other time value. - class LateTime - include Comparable - include Singleton - - def <=>(other) - 1 - end - - def to_s - "" - end - end - - LATE = LateTime.instance -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb deleted file mode 100644 index 11fa46f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/linked_list.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Polylithic linked list structure used to implement several data - # structures in Rake. - class LinkedList - include Enumerable - attr_reader :head, :tail - - # Polymorphically add a new element to the head of a list. The - # type of head node will be the same list type as the tail. - def conj(item) - self.class.cons(item, self) - end - - # Is the list empty? - # .make guards against a list being empty making any instantiated LinkedList - # object not empty by default - # You should consider overriding this method if you implement your own .make method - def empty? - false - end - - # Lists are structurally equivalent. - def ==(other) - current = self - while !current.empty? && !other.empty? - return false if current.head != other.head - current = current.tail - other = other.tail - end - current.empty? && other.empty? - end - - # Convert to string: LL(item, item...) - def to_s - items = map(&:to_s).join(", ") - "LL(#{items})" - end - - # Same as +to_s+, but with inspected items. - def inspect - items = map(&:inspect).join(", ") - "LL(#{items})" - end - - # For each item in the list. - def each - current = self - while !current.empty? - yield(current.head) - current = current.tail - end - self - end - - # Make a list out of the given arguments. This method is - # polymorphic - def self.make(*args) - # return an EmptyLinkedList if there are no arguments - return empty if !args || args.empty? - - # build a LinkedList by starting at the tail and iterating - # through each argument - # inject takes an EmptyLinkedList to start - args.reverse.inject(empty) do |list, item| - list = cons(item, list) - list # return the newly created list for each item in the block - end - end - - # Cons a new head onto the tail list. - def self.cons(head, tail) - new(head, tail) - end - - # The standard empty list class for the given LinkedList class. - def self.empty - self::EMPTY - end - - protected - - def initialize(head, tail=EMPTY) - @head = head - @tail = tail - end - - # Represent an empty list, using the Null Object Pattern. - # - # When inheriting from the LinkedList class, you should implement - # a type specific Empty class as well. Make sure you set the class - # instance variable @parent to the associated list class (this - # allows conj, cons and make to work polymorphically). - class EmptyLinkedList < LinkedList - @parent = LinkedList - - def initialize - end - - def empty? - true - end - - def self.cons(head, tail) - @parent.cons(head, tail) - end - end - - EMPTY = EmptyLinkedList.new - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb deleted file mode 100644 index 46f4bea..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/loaders/makefile.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Makefile loader to be used with the import file loader. Use this to - # import dependencies from make dependency tools: - # - # require 'rake/loaders/makefile' - # - # file ".depends.mf" => [SRC_LIST] do |t| - # sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" - # end - # - # import ".depends.mf" - # - # See {Importing Dependencies}[link:doc/rakefile_rdoc.html#label-Importing+Dependencies] - # for further details. - - class MakefileLoader - include Rake::DSL - - SPACE_MARK = "\0" # :nodoc: - - # Load the makefile dependencies in +fn+. - def load(fn) # :nodoc: - lines = File.read fn - lines.gsub!(/\\ /, SPACE_MARK) - lines.gsub!(/#[^\n]*\n/m, "") - lines.gsub!(/\\\n/, " ") - lines.each_line do |line| - process_line(line) - end - end - - private - - # Process one logical line of makefile data. - def process_line(line) # :nodoc: - file_tasks, args = line.split(":", 2) - return if args.nil? - dependents = args.split.map { |d| respace(d) } - file_tasks.scan(/\S+/) do |file_task| - file_task = respace(file_task) - file file_task => dependents - end - end - - def respace(str) # :nodoc: - str.tr SPACE_MARK, " " - end - end - - # Install the handler - Rake.application.add_loader("mf", MakefileLoader.new) -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb deleted file mode 100644 index 3ae363c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/multi_task.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Same as a regular task, but the immediate prerequisites are done in - # parallel using Ruby threads. - # - class MultiTask < Task - private - - def invoke_prerequisites(task_args, invocation_chain) # :nodoc: - invoke_prerequisites_concurrently(task_args, invocation_chain) - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb deleted file mode 100644 index 32f8139..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/name_space.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true -## -# The NameSpace class will lookup task names in the scope defined by a -# +namespace+ command. - -class Rake::NameSpace - - ## - # Create a namespace lookup object using the given task manager - # and the list of scopes. - - def initialize(task_manager, scope_list) - @task_manager = task_manager - @scope = scope_list.dup - end - - ## - # Lookup a task named +name+ in the namespace. - - def [](name) - @task_manager.lookup(name, @scope) - end - - ## - # The scope of the namespace (a LinkedList) - - def scope - @scope.dup - end - - ## - # Return the list of tasks defined in this and nested namespaces. - - def tasks - @task_manager.tasks_in_scope(@scope) - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb deleted file mode 100644 index 80a4acf..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/packagetask.rb +++ /dev/null @@ -1,222 +0,0 @@ -# frozen_string_literal: true -# Define a package task library to aid in the definition of -# redistributable package files. - -require_relative "../rake" -require_relative "tasklib" - -module Rake - - # Create a packaging task that will package the project into - # distributable files (e.g zip archive or tar files). - # - # The PackageTask will create the following targets: - # - # +:package+ :: - # Create all the requested package files. - # - # +:clobber_package+ :: - # Delete all the package files. This target is automatically - # added to the main clobber target. - # - # +:repackage+ :: - # Rebuild the package files from scratch, even if they are not out - # of date. - # - # "package_dir/name-version.tgz" :: - # Create a gzipped tar package (if need_tar is true). - # - # "package_dir/name-version.tar.gz" :: - # Create a gzipped tar package (if need_tar_gz is true). - # - # "package_dir/name-version.tar.bz2" :: - # Create a bzip2'd tar package (if need_tar_bz2 is true). - # - # "package_dir/name-version.zip" :: - # Create a zip package archive (if need_zip is true). - # - # Example: - # - # Rake::PackageTask.new("rake", "1.2.3") do |p| - # p.need_tar = true - # p.package_files.include("lib/**/*.rb") - # end - # - class PackageTask < TaskLib - # Name of the package (from the GEM Spec). - attr_accessor :name - - # Version of the package (e.g. '1.3.2'). - attr_accessor :version - - # Directory used to store the package files (default is 'pkg'). - attr_accessor :package_dir - - # True if a gzipped tar file (tgz) should be produced (default is - # false). - attr_accessor :need_tar - - # True if a gzipped tar file (tar.gz) should be produced (default - # is false). - attr_accessor :need_tar_gz - - # True if a bzip2'd tar file (tar.bz2) should be produced (default - # is false). - attr_accessor :need_tar_bz2 - - # True if a xz'd tar file (tar.xz) should be produced (default is false) - attr_accessor :need_tar_xz - - # True if a zip file should be produced (default is false) - attr_accessor :need_zip - - # List of files to be included in the package. - attr_accessor :package_files - - # Tar command for gzipped or bzip2ed archives. The default is 'tar'. - attr_accessor :tar_command - - # Zip command for zipped archives. The default is 'zip'. - attr_accessor :zip_command - - # True if parent directory should be omitted (default is false) - attr_accessor :without_parent_dir - - # Create a Package Task with the given name and version. Use +:noversion+ - # as the version to build a package without a version or to provide a - # fully-versioned package name. - - def initialize(name=nil, version=nil) - init(name, version) - yield self if block_given? - define unless name.nil? - end - - # Initialization that bypasses the "yield self" and "define" step. - def init(name, version) - @name = name - @version = version - @package_files = Rake::FileList.new - @package_dir = "pkg" - @need_tar = false - @need_tar_gz = false - @need_tar_bz2 = false - @need_tar_xz = false - @need_zip = false - @tar_command = "tar" - @zip_command = "zip" - @without_parent_dir = false - end - - # Create the tasks defined by this task library. - def define - fail "Version required (or :noversion)" if @version.nil? - @version = nil if :noversion == @version - - desc "Build all the packages" - task :package - - desc "Force a rebuild of the package files" - task repackage: [:clobber_package, :package] - - desc "Remove package products" - task :clobber_package do - rm_r package_dir rescue nil - end - - task clobber: [:clobber_package] - - [ - [need_tar, tgz_file, "z"], - [need_tar_gz, tar_gz_file, "z"], - [need_tar_bz2, tar_bz2_file, "j"], - [need_tar_xz, tar_xz_file, "J"] - ].each do |need, file, flag| - if need - task package: ["#{package_dir}/#{file}"] - file "#{package_dir}/#{file}" => - [package_dir_path] + package_files do - chdir(working_dir) { sh @tar_command, "#{flag}cvf", file, target_dir } - mv "#{package_dir_path}/#{target_dir}", package_dir if without_parent_dir - end - end - end - - if need_zip - task package: ["#{package_dir}/#{zip_file}"] - file "#{package_dir}/#{zip_file}" => - [package_dir_path] + package_files do - chdir(working_dir) { sh @zip_command, "-r", zip_file, target_dir } - mv "#{package_dir_path}/#{zip_file}", package_dir if without_parent_dir - end - end - - directory package_dir_path => @package_files do - @package_files.each do |fn| - f = File.join(package_dir_path, fn) - fdir = File.dirname(f) - mkdir_p(fdir) unless File.exist?(fdir) - if File.directory?(fn) - mkdir_p(f) - else - rm_f f - safe_ln(fn, f) - end - end - end - self - end - - # The name of this package - - def package_name - @version ? "#{@name}-#{@version}" : @name - end - - # The directory this package will be built in - - def package_dir_path - "#{package_dir}/#{package_name}" - end - - # The package name with .tgz added - - def tgz_file - "#{package_name}.tgz" - end - - # The package name with .tar.gz added - - def tar_gz_file - "#{package_name}.tar.gz" - end - - # The package name with .tar.bz2 added - - def tar_bz2_file - "#{package_name}.tar.bz2" - end - - # The package name with .tar.xz added - - def tar_xz_file - "#{package_name}.tar.xz" - end - - # The package name with .zip added - - def zip_file - "#{package_name}.zip" - end - - def working_dir - without_parent_dir ? package_dir_path : package_dir - end - - # target directory relative to working_dir - def target_dir - without_parent_dir ? "." : package_name - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb deleted file mode 100644 index 8f62b7c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/phony.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Defines a :phony task that you can use as a dependency. This allows -# file-based tasks to use non-file-based tasks as prerequisites -# without forcing them to rebuild. -# -# See FileTask#out_of_date? and Task#timestamp for more info. - -require_relative "../rake" - -task :phony - -Rake::Task[:phony].tap do |task| - def task.timestamp # :nodoc: - Time.at 0 - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb deleted file mode 100644 index 2815ce6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/private_reader.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Include PrivateReader to use +private_reader+. - module PrivateReader # :nodoc: all - - def self.included(base) - base.extend(ClassMethods) - end - - module ClassMethods - - # Declare a list of private accessors - def private_reader(*names) - attr_reader(*names) - private(*names) - end - end - - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb deleted file mode 100644 index f45af4f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/promise.rb +++ /dev/null @@ -1,100 +0,0 @@ -# frozen_string_literal: true -module Rake - - # A Promise object represents a promise to do work (a chore) in the - # future. The promise is created with a block and a list of - # arguments for the block. Calling value will return the value of - # the promised chore. - # - # Used by ThreadPool. - # - class Promise # :nodoc: all - NOT_SET = Object.new.freeze # :nodoc: - - attr_accessor :recorder - - # Create a promise to do the chore specified by the block. - def initialize(args, &block) - @mutex = Mutex.new - @result = NOT_SET - @error = NOT_SET - @args = args - @block = block - end - - # Return the value of this promise. - # - # If the promised chore is not yet complete, then do the work - # synchronously. We will wait. - def value - unless complete? - stat :sleeping_on, item_id: object_id - @mutex.synchronize do - stat :has_lock_on, item_id: object_id - chore - stat :releasing_lock_on, item_id: object_id - end - end - error? ? raise(@error) : @result - end - - # If no one else is working this promise, go ahead and do the chore. - def work - stat :attempting_lock_on, item_id: object_id - if @mutex.try_lock - stat :has_lock_on, item_id: object_id - chore - stat :releasing_lock_on, item_id: object_id - @mutex.unlock - else - stat :bailed_on, item_id: object_id - end - end - - private - - # Perform the chore promised - def chore - if complete? - stat :found_completed, item_id: object_id - return - end - stat :will_execute, item_id: object_id - begin - @result = @block.call(*@args) - rescue Exception => e - @error = e - end - stat :did_execute, item_id: object_id - discard - end - - # Do we have a result for the promise - def result? - !@result.equal?(NOT_SET) - end - - # Did the promise throw an error - def error? - !@error.equal?(NOT_SET) - end - - # Are we done with the promise - def complete? - result? || error? - end - - # free up these items for the GC - def discard - @args = nil - @block = nil - end - - # Record execution statistics if there is a recorder - def stat(*args) - @recorder.call(*args) if @recorder - end - - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb deleted file mode 100644 index 8b3c989..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/pseudo_status.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -module Rake - - ## - # Exit status class for times the system just gives us a nil. - class PseudoStatus # :nodoc: all - attr_reader :exitstatus - - def initialize(code=0) - @exitstatus = code - end - - def to_i - @exitstatus << 8 - end - - def >>(n) - to_i >> n - end - - def stopped? - false - end - - def exited? - true - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb deleted file mode 100644 index 03c2956..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_module.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true -require "rake/application" - -module Rake - - class << self - # Current Rake Application - def application - @application ||= Rake::Application.new - end - - # Set the current Rake application object. - def application=(app) - @application = app - end - - def suggested_thread_count # :nodoc: - @cpu_count ||= Rake::CpuCounter.count - @cpu_count + 4 - end - - # Return the original directory where the Rake application was started. - def original_dir - application.original_dir - end - - # Load a rakefile. - def load_rakefile(path) - load(path) - end - - # Add files to the rakelib list - def add_rakelib(*files) - application.options.rakelib ||= [] - application.options.rakelib.concat(files) - end - - # Make +block_application+ the default rake application inside a block so - # you can load rakefiles into a different application. - # - # This is useful when you want to run rake tasks inside a library without - # running rake in a sub-shell. - # - # Example: - # - # Dir.chdir 'other/directory' - # - # other_rake = Rake.with_application do |rake| - # rake.load_rakefile - # end - # - # puts other_rake.tasks - - def with_application(block_application = Rake::Application.new) - orig_application = Rake.application - - Rake.application = block_application - - yield block_application - - block_application - ensure - Rake.application = orig_application - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb deleted file mode 100644 index 05d89fc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rake_test_loader.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require_relative "file_list" - -# Load the test files from the command line. -argv = ARGV.select do |argument| - case argument - when /^-/ then - argument - when /\*/ then - Rake::FileList[argument].to_a.each do |file| - require File.expand_path file - end - - false - else - path = File.expand_path argument - - abort "\nFile does not exist: #{path}\n\n" unless File.exist?(path) - - require path - - false - end -end - -ARGV.replace argv diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb deleted file mode 100644 index a51e774..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/rule_recursion_overflow_error.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Error indicating a recursion overflow error in task selection. - class RuleRecursionOverflowError < StandardError - def initialize(*args) - super - @targets = [] - end - - def add_target(target) - @targets << target - end - - def message - super + ": [" + @targets.reverse.join(" => ") + "]" - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb deleted file mode 100644 index fc1eb6c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/scope.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true -module Rake - class Scope < LinkedList # :nodoc: all - - # Path for the scope. - def path - map(&:to_s).reverse.join(":") - end - - # Path for the scope + the named path. - def path_with_task_name(task_name) - "#{path}:#{task_name}" - end - - # Trim +n+ innermost scope levels from the scope. In no case will - # this trim beyond the toplevel scope. - def trim(n) - result = self - while n > 0 && !result.empty? - result = result.tail - n -= 1 - end - result - end - - # Scope lists always end with an EmptyScope object. See Null - # Object Pattern) - class EmptyScope < EmptyLinkedList - @parent = Scope - - def path - "" - end - - def path_with_task_name(task_name) - task_name - end - end - - # Singleton null object for an empty scope. - EMPTY = EmptyScope.new - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb deleted file mode 100644 index e61ccb6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task.rb +++ /dev/null @@ -1,434 +0,0 @@ -# frozen_string_literal: true -require_relative "invocation_exception_mixin" - -module Rake - - ## - # A Task is the basic unit of work in a Rakefile. Tasks have associated - # actions (possibly more than one) and a list of prerequisites. When - # invoked, a task will first ensure that all of its prerequisites have an - # opportunity to run and then it will execute its own actions. - # - # Tasks are not usually created directly using the new method, but rather - # use the +file+ and +task+ convenience methods. - # - class Task - # List of prerequisites for a task. - attr_reader :prerequisites - alias prereqs prerequisites - - # List of order only prerequisites for a task. - attr_reader :order_only_prerequisites - - # List of actions attached to a task. - attr_reader :actions - - # Application owning this task. - attr_accessor :application - - # Array of nested namespaces names used for task lookup by this task. - attr_reader :scope - - # File/Line locations of each of the task definitions for this - # task (only valid if the task was defined with the detect - # location option set). - attr_reader :locations - - # Has this task already been invoked? Already invoked tasks - # will be skipped unless you reenable them. - attr_reader :already_invoked - - # Return task name - def to_s - name - end - - def inspect # :nodoc: - "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>" - end - - # List of sources for task. - attr_writer :sources - def sources - if defined?(@sources) - @sources - else - prerequisites - end - end - - # List of prerequisite tasks - def prerequisite_tasks - (prerequisites + order_only_prerequisites).map { |pre| lookup_prerequisite(pre) } - end - - def lookup_prerequisite(prerequisite_name) # :nodoc: - scoped_prerequisite_task = application[prerequisite_name, @scope] - if scoped_prerequisite_task == self - unscoped_prerequisite_task = application[prerequisite_name] - end - unscoped_prerequisite_task || scoped_prerequisite_task - end - private :lookup_prerequisite - - # List of all unique prerequisite tasks including prerequisite tasks' - # prerequisites. - # Includes self when cyclic dependencies are found. - def all_prerequisite_tasks - seen = {} - collect_prerequisites(seen) - seen.values - end - - def collect_prerequisites(seen) # :nodoc: - prerequisite_tasks.each do |pre| - next if seen[pre.name] - seen[pre.name] = pre - pre.collect_prerequisites(seen) - end - end - protected :collect_prerequisites - - # First source from a rule (nil if no sources) - def source - sources.first - end - - # Create a task named +task_name+ with no actions or prerequisites. Use - # +enhance+ to add actions and prerequisites. - def initialize(task_name, app) - @name = task_name.to_s - @prerequisites = [] - @actions = [] - @already_invoked = false - @comments = [] - @lock = Monitor.new - @application = app - @scope = app.current_scope - @arg_names = nil - @locations = [] - @invocation_exception = nil - @order_only_prerequisites = [] - end - - # Enhance a task with prerequisites or actions. Returns self. - def enhance(deps=nil, &block) - @prerequisites |= deps if deps - @actions << block if block_given? - self - end - - # Name of the task, including any namespace qualifiers. - def name - @name.to_s - end - - # Name of task with argument list description. - def name_with_args # :nodoc: - if arg_description - "#{name}#{arg_description}" - else - name - end - end - - # Argument description (nil if none). - def arg_description # :nodoc: - @arg_names ? "[#{arg_names.join(',')}]" : nil - end - - # Name of arguments for this task. - def arg_names - @arg_names || [] - end - - # Reenable the task, allowing its tasks to be executed if the task - # is invoked again. - def reenable - @already_invoked = false - @invocation_exception = nil - end - - # Clear the existing prerequisites, actions, comments, and arguments of a rake task. - def clear - clear_prerequisites - clear_actions - clear_comments - clear_args - self - end - - # Clear the existing prerequisites of a rake task. - def clear_prerequisites - prerequisites.clear - self - end - - # Clear the existing actions on a rake task. - def clear_actions - actions.clear - self - end - - # Clear the existing comments on a rake task. - def clear_comments - @comments = [] - self - end - - # Clear the existing arguments on a rake task. - def clear_args - @arg_names = nil - self - end - - # Invoke the task if it is needed. Prerequisites are invoked first. - def invoke(*args) - task_args = TaskArguments.new(arg_names, args) - invoke_with_call_chain(task_args, InvocationChain::EMPTY) - end - - # Same as invoke, but explicitly pass a call chain to detect - # circular dependencies. - # - # If multiple tasks depend on this - # one in parallel, they will all fail if the first execution of - # this task fails. - def invoke_with_call_chain(task_args, invocation_chain) - new_chain = Rake::InvocationChain.append(self, invocation_chain) - @lock.synchronize do - begin - if application.options.trace - application.trace "** Invoke #{name} #{format_trace_flags}" - end - - if @already_invoked - if @invocation_exception - if application.options.trace - application.trace "** Previous invocation of #{name} failed #{format_trace_flags}" - end - raise @invocation_exception - else - return - end - end - - @already_invoked = true - - invoke_prerequisites(task_args, new_chain) - execute(task_args) if needed? - rescue Exception => ex - add_chain_to(ex, new_chain) - @invocation_exception = ex - raise ex - end - end - end - protected :invoke_with_call_chain - - def add_chain_to(exception, new_chain) # :nodoc: - exception.extend(InvocationExceptionMixin) unless - exception.respond_to?(:chain) - exception.chain = new_chain if exception.chain.nil? - end - private :add_chain_to - - # Invoke all the prerequisites of a task. - def invoke_prerequisites(task_args, invocation_chain) # :nodoc: - if application.options.always_multitask - invoke_prerequisites_concurrently(task_args, invocation_chain) - else - prerequisite_tasks.each { |p| - prereq_args = task_args.new_scope(p.arg_names) - p.invoke_with_call_chain(prereq_args, invocation_chain) - } - end - end - - # Invoke all the prerequisites of a task in parallel. - def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc: - futures = prerequisite_tasks.map do |p| - prereq_args = task_args.new_scope(p.arg_names) - application.thread_pool.future(p) do |r| - r.invoke_with_call_chain(prereq_args, invocation_chain) - end - end - # Iterate in reverse to improve performance related to thread waiting and switching - futures.reverse_each(&:value) - end - - # Format the trace flags for display. - def format_trace_flags - flags = [] - flags << "first_time" unless @already_invoked - flags << "not_needed" unless needed? - flags.empty? ? "" : "(" + flags.join(", ") + ")" - end - private :format_trace_flags - - # Execute the actions associated with this task. - def execute(args=nil) - args ||= EMPTY_TASK_ARGS - if application.options.dryrun - application.trace "** Execute (dry run) #{name}" - return - end - application.trace "** Execute #{name}" if application.options.trace - application.enhance_with_matching_rule(name) if @actions.empty? - if opts = Hash.try_convert(args) and !opts.empty? - @actions.each { |act| act.call(self, args, **opts) } - else - @actions.each { |act| act.call(self, args) } - end - end - - # Is this task needed? - def needed? - true - end - - # Timestamp for this task. Basic tasks return the current time for their - # time stamp. Other tasks can be more sophisticated. - def timestamp - Time.now - end - - # Add a description to the task. The description can consist of an option - # argument list (enclosed brackets) and an optional comment. - def add_description(description) - return unless description - comment = description.strip - add_comment(comment) if comment && !comment.empty? - end - - def comment=(comment) # :nodoc: - add_comment(comment) - end - - def add_comment(comment) # :nodoc: - return if comment.nil? - @comments << comment unless @comments.include?(comment) - end - private :add_comment - - # Full collection of comments. Multiple comments are separated by - # newlines. - def full_comment - transform_comments("\n") - end - - # First line (or sentence) of all comments. Multiple comments are - # separated by a "/". - def comment - transform_comments(" / ") { |c| first_sentence(c) } - end - - # Transform the list of comments as specified by the block and - # join with the separator. - def transform_comments(separator, &block) - if @comments.empty? - nil - else - block ||= lambda { |c| c } - @comments.map(&block).join(separator) - end - end - private :transform_comments - - # Get the first sentence in a string. The sentence is terminated - # by the first period, exclamation mark, or the end of the line. - # Decimal points do not count as periods. - def first_sentence(string) - string.split(/(?<=\w)(\.|!)[ \t]|(\.$|!)|\n/).first - end - private :first_sentence - - # Set the names of the arguments for this task. +args+ should be - # an array of symbols, one for each argument name. - def set_arg_names(args) - @arg_names = args.map(&:to_sym) - end - - # Return a string describing the internal state of a task. Useful for - # debugging. - def investigation - result = "------------------------------\n".dup - result << "Investigating #{name}\n" - result << "class: #{self.class}\n" - result << "task needed: #{needed?}\n" - result << "timestamp: #{timestamp}\n" - result << "pre-requisites: \n" - prereqs = prerequisite_tasks - prereqs.sort! { |a, b| a.timestamp <=> b.timestamp } - prereqs.each do |p| - result << "--#{p.name} (#{p.timestamp})\n" - end - latest_prereq = prerequisite_tasks.map(&:timestamp).max - result << "latest-prerequisite time: #{latest_prereq}\n" - result << "................................\n\n" - return result - end - - # Format dependencies parameter to pass to task. - def self.format_deps(deps) - deps = [deps] unless deps.respond_to?(:to_ary) - deps.map { |d| Rake.from_pathname(d).to_s } - end - - # Add order only dependencies. - def |(deps) - @order_only_prerequisites |= Task.format_deps(deps) - @prerequisites - self - end - - # ---------------------------------------------------------------- - # Rake Module Methods - # - class << self - - # Clear the task list. This cause rake to immediately forget all the - # tasks that have been assigned. (Normally used in the unit tests.) - def clear - Rake.application.clear - end - - # List of all defined tasks. - def tasks - Rake.application.tasks - end - - # Return a task with the given name. If the task is not currently - # known, try to synthesize one from the defined rules. If no rules are - # found, but an existing file matches the task name, assume it is a file - # task with no dependencies or actions. - def [](task_name) - Rake.application[task_name] - end - - # TRUE if the task name is already defined. - def task_defined?(task_name) - Rake.application.lookup(task_name) != nil - end - - # Define a task given +args+ and an option block. If a rule with the - # given name already exists, the prerequisites and actions are added to - # the existing task. Returns the defined task. - def define_task(*args, &block) - Rake.application.define_task(self, *args, &block) - end - - # Define a rule for synthesizing tasks. - def create_rule(*args, &block) - Rake.application.create_rule(*args, &block) - end - - # Apply the scope to the task name according to the rules for - # this kind of task. Generic tasks will accept the scope as - # part of the name. - def scope_name(scope, task_name) - scope.path_with_task_name(task_name) - end - - end # class << Rake::Task - end # class Rake::Task -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb deleted file mode 100644 index ef20076..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_argument_error.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Error indicating an ill-formed task declaration. - class TaskArgumentError < ArgumentError - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb deleted file mode 100644 index 24abebc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_arguments.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true -module Rake - - ## - # TaskArguments manage the arguments passed to a task. - # - class TaskArguments - include Enumerable - - # Argument names - attr_reader :names - - # Create a TaskArgument object with a list of argument +names+ and a set - # of associated +values+. +parent+ is the parent argument object. - def initialize(names, values, parent=nil) - @names = names - @parent = parent - @hash = {} - @values = values - names.each_with_index { |name, i| - next if values[i].nil? || values[i] == "" - @hash[name.to_sym] = values[i] - } - end - - # Retrieve the complete array of sequential values - def to_a - @values.dup - end - - # Retrieve the list of values not associated with named arguments - def extras - @values[@names.length..-1] || [] - end - - # Create a new argument scope using the prerequisite argument - # names. - def new_scope(names) - values = names.map { |n| self[n] } - self.class.new(names, values + extras, self) - end - - # Find an argument value by name or index. - def [](index) - lookup(index.to_sym) - end - - # Specify a hash of default values for task arguments. Use the - # defaults only if there is no specific value for the given - # argument. - def with_defaults(defaults) - @hash = defaults.merge(@hash) - end - - # Enumerates the arguments and their values - def each(&block) - @hash.each(&block) - end - - # Extracts the argument values at +keys+ - def values_at(*keys) - keys.map { |k| lookup(k) } - end - - # Returns the value of the given argument via method_missing - def method_missing(sym, *args) - lookup(sym.to_sym) - end - - # Returns a Hash of arguments and their values - def to_hash - @hash.dup - end - - def to_s # :nodoc: - inspect - end - - def inspect # :nodoc: - inspection = @hash.map do |k,v| - "#{k.to_s}: #{v.to_s}" - end.join(", ") - - "#<#{self.class} #{inspection}>" - end - - # Returns true if +key+ is one of the arguments - def has_key?(key) - @hash.has_key?(key) - end - alias key? has_key? - - def fetch(*args, &block) - @hash.fetch(*args, &block) - end - - def deconstruct_keys(keys) - keys ? @hash.slice(*keys) : to_hash - end - - protected - - def lookup(name) # :nodoc: - if @hash.has_key?(name) - @hash[name] - elsif @parent - @parent.lookup(name) - end - end - end - - EMPTY_TASK_ARGS = TaskArguments.new([], []) # :nodoc: -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb deleted file mode 100644 index 838779c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/task_manager.rb +++ /dev/null @@ -1,331 +0,0 @@ -# frozen_string_literal: true -module Rake - - # The TaskManager module is a mixin for managing tasks. - module TaskManager - # Track the last comment made in the Rakefile. - attr_accessor :last_description - - def initialize # :nodoc: - super - @tasks = Hash.new - @rules = Array.new - @scope = Scope.make - @last_description = nil - end - - def create_rule(*args, &block) # :nodoc: - pattern, args, deps, order_only = resolve_args(args) - pattern = Regexp.new(Regexp.quote(pattern) + "$") if String === pattern - @rules << [pattern, args, deps, order_only, block] - end - - def define_task(task_class, *args, &block) # :nodoc: - task_name, arg_names, deps, order_only = resolve_args(args) - - original_scope = @scope - if String === task_name and - not task_class.ancestors.include? Rake::FileTask - task_name, *definition_scope = *(task_name.split(":").reverse) - @scope = Scope.make(*(definition_scope + @scope.to_a)) - end - - task_name = task_class.scope_name(@scope, task_name) - task = intern(task_class, task_name) - task.set_arg_names(arg_names) unless arg_names.empty? - if Rake::TaskManager.record_task_metadata - add_location(task) - task.add_description(get_description) - end - task.enhance(Task.format_deps(deps), &block) - task | order_only unless order_only.nil? - task - ensure - @scope = original_scope - end - - # Lookup a task. Return an existing task if found, otherwise - # create a task of the current type. - def intern(task_class, task_name) - @tasks[task_name.to_s] ||= task_class.new(task_name, self) - end - - # Find a matching task for +task_name+. - def [](task_name, scopes=nil) - task_name = task_name.to_s - self.lookup(task_name, scopes) or - enhance_with_matching_rule(task_name) or - synthesize_file_task(task_name) or - fail generate_message_for_undefined_task(task_name) - end - - def generate_message_for_undefined_task(task_name) - message = "Don't know how to build task '#{task_name}' "\ - "(See the list of available tasks with `#{Rake.application.name} --tasks`)" - message + generate_did_you_mean_suggestions(task_name) - end - - def generate_did_you_mean_suggestions(task_name) - return "" unless defined?(::DidYouMean::SpellChecker) - - suggestions = ::DidYouMean::SpellChecker.new(dictionary: @tasks.keys).correct(task_name.to_s) - if ::DidYouMean.respond_to?(:formatter)# did_you_mean v1.2.0 or later - ::DidYouMean.formatter.message_for(suggestions) - elsif defined?(::DidYouMean::Formatter) # before did_you_mean v1.2.0 - ::DidYouMean::Formatter.new(suggestions).to_s - else - "" - end - end - - def synthesize_file_task(task_name) # :nodoc: - return nil unless File.exist?(task_name) - define_task(Rake::FileTask, task_name) - end - - # Resolve the arguments for a task/rule. Returns a tuple of - # [task_name, arg_name_list, prerequisites, order_only_prerequisites]. - def resolve_args(args) - if args.last.is_a?(Hash) - deps = args.pop - resolve_args_with_dependencies(args, deps) - else - resolve_args_without_dependencies(args) - end - end - - # Resolve task arguments for a task or rule when there are no - # dependencies declared. - # - # The patterns recognized by this argument resolving function are: - # - # task :t - # task :t, [:a] - # - def resolve_args_without_dependencies(args) - task_name = args.shift - if args.size == 1 && args.first.respond_to?(:to_ary) - arg_names = args.first.to_ary - else - arg_names = args - end - [task_name, arg_names, [], nil] - end - private :resolve_args_without_dependencies - - # Resolve task arguments for a task or rule when there are - # dependencies declared. - # - # The patterns recognized by this argument resolving function are: - # - # task :t, order_only: [:e] - # task :t => [:d] - # task :t => [:d], order_only: [:e] - # task :t, [a] => [:d] - # task :t, [a] => [:d], order_only: [:e] - # - def resolve_args_with_dependencies(args, hash) # :nodoc: - fail "Task Argument Error" if - hash.size != 1 && - (hash.size != 2 || !hash.key?(:order_only)) - order_only = hash.delete(:order_only) - key, value = hash.map { |k, v| [k, v] }.first - if args.empty? - task_name = key - arg_names = [] - deps = value || [] - else - task_name = args.shift - arg_names = key || args.shift|| [] - deps = value || [] - end - deps = [deps] unless deps.respond_to?(:to_ary) - [task_name, arg_names, deps, order_only] - end - private :resolve_args_with_dependencies - - # If a rule can be found that matches the task name, enhance the - # task with the prerequisites and actions from the rule. Set the - # source attribute of the task appropriately for the rule. Return - # the enhanced task or nil of no rule was found. - def enhance_with_matching_rule(task_name, level=0) - fail Rake::RuleRecursionOverflowError, - "Rule Recursion Too Deep" if level >= 16 - @rules.each do |pattern, args, extensions, order_only, block| - if pattern && pattern.match(task_name) - task = attempt_rule(task_name, pattern, args, extensions, block, level) - task | order_only unless order_only.nil? - return task if task - end - end - nil - rescue Rake::RuleRecursionOverflowError => ex - ex.add_target(task_name) - fail ex - end - - # List of all defined tasks in this application. - def tasks - @tasks.values.sort_by { |t| t.name } - end - - # List of all the tasks defined in the given scope (and its - # sub-scopes). - def tasks_in_scope(scope) - prefix = scope.path - tasks.select { |t| - /^#{prefix}:/ =~ t.name - } - end - - # Clear all tasks in this application. - def clear - @tasks.clear - @rules.clear - end - - # Lookup a task, using scope and the scope hints in the task name. - # This method performs straight lookups without trying to - # synthesize file tasks or rules. Special scope names (e.g. '^') - # are recognized. If no scope argument is supplied, use the - # current scope. Return nil if the task cannot be found. - def lookup(task_name, initial_scope=nil) - initial_scope ||= @scope - task_name = task_name.to_s - if task_name =~ /^rake:/ - scopes = Scope.make - task_name = task_name.sub(/^rake:/, "") - elsif task_name =~ /^(\^+)/ - scopes = initial_scope.trim($1.size) - task_name = task_name.sub(/^(\^+)/, "") - else - scopes = initial_scope - end - lookup_in_scope(task_name, scopes) - end - - # Lookup the task name - def lookup_in_scope(name, scope) - loop do - tn = scope.path_with_task_name(name) - task = @tasks[tn] - return task if task - break if scope.empty? - scope = scope.tail - end - nil - end - private :lookup_in_scope - - # Return the list of scope names currently active in the task - # manager. - def current_scope - @scope - end - - # Evaluate the block in a nested namespace named +name+. Create - # an anonymous namespace if +name+ is nil. - def in_namespace(name) - name ||= generate_name - @scope = Scope.new(name, @scope) - ns = NameSpace.new(self, @scope) - yield(ns) - ns - ensure - @scope = @scope.tail - end - - private - - # Add a location to the locations field of the given task. - def add_location(task) - loc = find_location - task.locations << loc if loc - task - end - - # Find the location that called into the dsl layer. - def find_location - locations = caller - i = 0 - while locations[i] - return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/ - i += 1 - end - nil - end - - # Generate an anonymous namespace name. - def generate_name - @seed ||= 0 - @seed += 1 - "_anon_#{@seed}" - end - - def trace_rule(level, message) # :nodoc: - options.trace_output.puts "#{" " * level}#{message}" if - Rake.application.options.trace_rules - end - - # Attempt to create a rule given the list of prerequisites. - def attempt_rule(task_name, task_pattern, args, extensions, block, level) - sources = make_sources(task_name, task_pattern, extensions) - prereqs = sources.map { |source| - trace_rule level, "Attempting Rule #{task_name} => #{source}" - if File.exist?(source) || Rake::Task.task_defined?(source) - trace_rule level, "(#{task_name} => #{source} ... EXIST)" - source - elsif parent = enhance_with_matching_rule(source, level + 1) - trace_rule level, "(#{task_name} => #{source} ... ENHANCE)" - parent.name - else - trace_rule level, "(#{task_name} => #{source} ... FAIL)" - return nil - end - } - task = FileTask.define_task(task_name, { args => prereqs }, &block) - task.sources = prereqs - task - end - - # Make a list of sources from the list of file name extensions / - # translation procs. - def make_sources(task_name, task_pattern, extensions) - result = extensions.map { |ext| - case ext - when /%/ - task_name.pathmap(ext) - when %r{/} - ext - when /^\./ - source = task_name.sub(task_pattern, ext) - source == ext ? task_name.ext(ext) : source - when String, Symbol - ext.to_s - when Proc, Method - if ext.arity == 1 - ext.call(task_name) - else - ext.call - end - else - fail "Don't know how to handle rule dependent: #{ext.inspect}" - end - } - result.flatten - end - - # Return the current description, clearing it in the process. - def get_description - desc = @last_description - @last_description = nil - desc - end - - class << self - attr_accessor :record_task_metadata # :nodoc: - TaskManager.record_task_metadata = false - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb deleted file mode 100644 index 597a2d6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/tasklib.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -require_relative "../rake" - -module Rake - - # Base class for Task Libraries. - class TaskLib - include Cloneable - include Rake::DSL - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb deleted file mode 100644 index 7cf1ece..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/testtask.rb +++ /dev/null @@ -1,189 +0,0 @@ -# frozen_string_literal: true -require_relative "../rake" -require_relative "tasklib" - -module Rake - - # Create a task that runs a set of tests. - # - # Example: - # require "rake/testtask" - # - # Rake::TestTask.new do |t| - # t.libs << "test" - # t.test_files = FileList['test/test*.rb'] - # t.verbose = true - # end - # - # If rake is invoked with a "TEST=filename" command line option, - # then the list of test files will be overridden to include only the - # filename specified on the command line. This provides an easy way - # to run just one test. - # - # If rake is invoked with a "TESTOPTS=options" command line option, - # then the given options are passed to the test process after a - # '--'. This allows Test::Unit options to be passed to the test - # suite. - # - # Examples: - # - # rake test # run tests normally - # rake test TEST=just_one_file.rb # run just one test file. - # rake test TESTOPTS="-v" # run in verbose mode - # rake test TESTOPTS="--runner=fox" # use the fox test runner - # - class TestTask < TaskLib - - # Name of test task. (default is :test) - attr_accessor :name - - # List of directories added to $LOAD_PATH before running the - # tests. (default is 'lib') - attr_accessor :libs - - # True if verbose test output desired. (default is false) - attr_accessor :verbose - - # Test options passed to the test suite. An explicit - # TESTOPTS=opts on the command line will override this. (default - # is NONE) - attr_accessor :options - - # Request that the tests be run with the warning flag set. - # E.g. warning=true implies "ruby -w" used to run the tests. - # (default is true) - attr_accessor :warning - - # Glob pattern to match test files. (default is 'test/test*.rb') - attr_accessor :pattern - - # Style of test loader to use. Options are: - # - # * :rake -- Rake provided test loading script (default). - # * :testrb -- Ruby provided test loading script. - # * :direct -- Load tests using command line loader. - # - attr_accessor :loader - - # Array of command line options to pass to ruby when running test loader. - attr_accessor :ruby_opts - - # Description of the test task. (default is 'Run tests') - attr_accessor :description - - # Task prerequisites. - attr_accessor :deps - - # Explicitly define the list of test files to be included in a - # test. +list+ is expected to be an array of file names (a - # FileList is acceptable). If both +pattern+ and +test_files+ are - # used, then the list of test files is the union of the two. - def test_files=(list) - @test_files = list - end - - # Create a testing task. - def initialize(name=:test) - @name = name - @libs = ["lib"] - @pattern = nil - @options = nil - @test_files = nil - @verbose = false - @warning = true - @loader = :rake - @ruby_opts = [] - @description = "Run tests" + (@name == :test ? "" : " for #{@name}") - @deps = [] - if @name.is_a?(Hash) - @deps = @name.values.first - @name = @name.keys.first - end - yield self if block_given? - @pattern = "test/test*.rb" if @pattern.nil? && @test_files.nil? - define - end - - # Create the tasks defined by this task lib. - def define - desc @description - task @name => Array(deps) do - FileUtilsExt.verbose(@verbose) do - puts "Use TESTOPTS=\"--verbose\" to pass --verbose" \ - ", etc. to runners." if ARGV.include? "--verbose" - args = - "#{ruby_opts_string} #{run_code} " + - "#{file_list_string} #{option_list}" - ruby args do |ok, status| - if !ok && status.respond_to?(:signaled?) && status.signaled? - raise SignalException.new(status.termsig) - elsif !ok - status = "Command failed with status (#{status.exitstatus})" - details = ": [ruby #{args}]" - message = - if Rake.application.options.trace or @verbose - status + details - else - status - end - - fail message - end - end - end - end - self - end - - def option_list # :nodoc: - (ENV["TESTOPTS"] || - ENV["TESTOPT"] || - ENV["TEST_OPTS"] || - ENV["TEST_OPT"] || - @options || - "") - end - - def ruby_opts_string # :nodoc: - opts = @ruby_opts.dup - opts.unshift("-I\"#{lib_path}\"") unless @libs.empty? - opts.unshift("-w") if @warning - opts.join(" ") - end - - def lib_path # :nodoc: - @libs.join(File::PATH_SEPARATOR) - end - - def file_list_string # :nodoc: - file_list.map { |fn| "\"#{fn}\"" }.join(" ") - end - - def file_list # :nodoc: - if ENV["TEST"] - FileList[ENV["TEST"]] - else - result = [] - result += @test_files.to_a if @test_files - result += FileList[@pattern].to_a if @pattern - result - end - end - - def ruby_version # :nodoc: - RUBY_VERSION - end - - def run_code # :nodoc: - case @loader - when :direct - "-e \"ARGV.each{|f| require f}\"" - when :testrb - "-S testrb" - when :rake - "#{__dir__}/rake_test_loader.rb" - end - end - - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb deleted file mode 100644 index 50e2bc8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_history_display.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true -require_relative "private_reader" - -module Rake - - class ThreadHistoryDisplay # :nodoc: all - include Rake::PrivateReader - - private_reader :stats, :items, :threads - - def initialize(stats) - @stats = stats - @items = { _seq_: 1 } - @threads = { _seq_: "A" } - end - - def show - puts "Job History:" - stats.each do |stat| - stat[:data] ||= {} - rename(stat, :thread, threads) - rename(stat[:data], :item_id, items) - rename(stat[:data], :new_thread, threads) - rename(stat[:data], :deleted_thread, threads) - printf("%8d %2s %-20s %s\n", - (stat[:time] * 1_000_000).round, - stat[:thread], - stat[:event], - stat[:data].map do |k, v| "#{k}:#{v}" end.join(" ")) - end - end - - private - - def rename(hash, key, renames) - if hash && hash[key] - original = hash[key] - value = renames[original] - unless value - value = renames[:_seq_] - renames[:_seq_] = renames[:_seq_].succ - renames[original] = value - end - hash[key] = value - end - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb deleted file mode 100644 index ea9c0ae..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/thread_pool.rb +++ /dev/null @@ -1,157 +0,0 @@ -# frozen_string_literal: true - -require_relative "promise" -require "set" - -module Rake - - class ThreadPool # :nodoc: all - - # Creates a ThreadPool object. The +thread_count+ parameter is the size - # of the pool. - def initialize(thread_count) - @max_active_threads = [thread_count, 0].max - @threads = Set.new - @threads_mon = Monitor.new - @queue = Queue.new - @join_cond = @threads_mon.new_cond - - @history_start_time = nil - @history = [] - @history_mon = Monitor.new - @total_threads_in_play = 0 - end - - # Creates a future executed by the +ThreadPool+. - # - # The args are passed to the block when executing (similarly to - # Thread#new) The return value is an object representing - # a future which has been created and added to the queue in the - # pool. Sending #value to the object will sleep the - # current thread until the future is finished and will return the - # result (or raise an exception thrown from the future) - def future(*args, &block) - promise = Promise.new(args, &block) - promise.recorder = lambda { |*stats| stat(*stats) } - - @queue.enq promise - stat :queued, item_id: promise.object_id - start_thread - promise - end - - # Waits until the queue of futures is empty and all threads have exited. - def join - @threads_mon.synchronize do - begin - stat :joining - @join_cond.wait unless @threads.empty? - stat :joined - rescue Exception => e - stat :joined - $stderr.puts e - $stderr.print "Queue contains #{@queue.size} items. " + - "Thread pool contains #{@threads.count} threads\n" - $stderr.print "Current Thread #{Thread.current} status = " + - "#{Thread.current.status}\n" - $stderr.puts e.backtrace.join("\n") - @threads.each do |t| - $stderr.print "Thread #{t} status = #{t.status}\n" - $stderr.puts t.backtrace.join("\n") - end - raise e - end - end - end - - # Enable the gathering of history events. - def gather_history #:nodoc: - @history_start_time = Time.now if @history_start_time.nil? - end - - # Return a array of history events for the thread pool. - # - # History gathering must be enabled to be able to see the events - # (see #gather_history). Best to call this when the job is - # complete (i.e. after ThreadPool#join is called). - def history # :nodoc: - @history_mon.synchronize { @history.dup }. - sort_by { |i| i[:time] }. - each { |i| i[:time] -= @history_start_time } - end - - # Return a hash of always collected statistics for the thread pool. - def statistics # :nodoc: - { - total_threads_in_play: @total_threads_in_play, - max_active_threads: @max_active_threads, - } - end - - private - - # processes one item on the queue. Returns true if there was an - # item to process, false if there was no item - def process_queue_item #:nodoc: - return false if @queue.empty? - - # Even though we just asked if the queue was empty, it - # still could have had an item which by this statement - # is now gone. For this reason we pass true to Queue#deq - # because we will sleep indefinitely if it is empty. - promise = @queue.deq(true) - stat :dequeued, item_id: promise.object_id - promise.work - return true - - rescue ThreadError # this means the queue is empty - false - end - - def start_thread # :nodoc: - @threads_mon.synchronize do - next unless @threads.count < @max_active_threads - - t = Thread.new do - begin - loop do - break unless process_queue_item - end - ensure - @threads_mon.synchronize do - @threads.delete Thread.current - stat :ended, thread_count: @threads.count - @join_cond.broadcast if @threads.empty? - end - end - end - - @threads << t - stat( - :spawned, - new_thread: t.object_id, - thread_count: @threads.count) - @total_threads_in_play = @threads.count if - @threads.count > @total_threads_in_play - end - end - - def stat(event, data=nil) # :nodoc: - return if @history_start_time.nil? - info = { - event: event, - data: data, - time: Time.now, - thread: Thread.current.object_id, - } - @history_mon.synchronize { @history << info } - end - - # for testing only - - def __queue__ # :nodoc: - @queue - end - end - -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb deleted file mode 100644 index d713a09..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/trace_output.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -module Rake - module TraceOutput # :nodoc: all - - # Write trace output to output stream +out+. - # - # The write is done as a single IO call (to print) to lessen the - # chance that the trace output is interrupted by other tasks also - # producing output. - def trace_on(out, *strings) - sep = $\ || "\n" - if strings.empty? - output = sep - else - output = strings.map { |s| - next if s.nil? - s.end_with?(sep) ? s : s + sep - }.join - end - out.print(output) - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb deleted file mode 100644 index 01df37d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/version.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -module Rake - VERSION = "13.3.1" - - module Version # :nodoc: all - MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split "." - - NUMBERS = [MAJOR, MINOR, BUILD, *OTHER] - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb deleted file mode 100644 index 6e62031..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/lib/rake/win32.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true -require "rbconfig" - -module Rake - # Win 32 interface methods for Rake. Windows specific functionality - # will be placed here to collect that knowledge in one spot. - module Win32 # :nodoc: all - - # Error indicating a problem in locating the home directory on a - # Win32 system. - class Win32HomeError < RuntimeError - end - - class << self - # True if running on a windows system. - def windows? - RbConfig::CONFIG["host_os"] =~ %r!(msdos|mswin|djgpp|mingw|[Ww]indows)! - end - - # The standard directory containing system wide rake files on - # Win 32 systems. Try the following environment variables (in - # order): - # - # * HOME - # * HOMEDRIVE + HOMEPATH - # * APPDATA - # * USERPROFILE - # - # If the above are not defined, the return nil. - def win32_system_dir #:nodoc: - win32_shared_path = ENV["HOME"] - if win32_shared_path.nil? && ENV["HOMEDRIVE"] && ENV["HOMEPATH"] - win32_shared_path = ENV["HOMEDRIVE"] + ENV["HOMEPATH"] - end - - win32_shared_path ||= ENV["APPDATA"] - win32_shared_path ||= ENV["USERPROFILE"] - raise Win32HomeError, - "Unable to determine home path environment variable." if - win32_shared_path.nil? or win32_shared_path.empty? - normalize(File.join(win32_shared_path, "Rake")) - end - - # Normalize a win32 path so that the slashes are all forward slashes. - def normalize(path) - path.gsub(/\\/, "/") - end - - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec b/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec deleted file mode 100644 index 5899790..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rake-13.3.1/rake.gemspec +++ /dev/null @@ -1,101 +0,0 @@ -# frozen_string_literal: true - -require_relative "lib/rake/version" - -Gem::Specification.new do |s| - s.name = "rake" - s.version = Rake::VERSION - s.authors = ["Hiroshi SHIBATA", "Eric Hodel", "Jim Weirich"] - s.email = ["hsbt@ruby-lang.org", "drbrain@segment7.net", ""] - - s.summary = "Rake is a Make-like program implemented in Ruby" - s.description = <<~DESCRIPTION - Rake is a Make-like program implemented in Ruby. Tasks and dependencies are - specified in standard Ruby syntax. - Rake has the following features: - * Rakefiles (rake's version of Makefiles) are completely defined in standard Ruby syntax. - No XML files to edit. No quirky Makefile syntax to worry about (is that a tab or a space?) - * Users can specify tasks with prerequisites. - * Rake supports rule patterns to synthesize implicit tasks. - * Flexible FileLists that act like arrays but know about manipulating file names and paths. - * Supports parallel execution of tasks. - DESCRIPTION - s.homepage = "https://github.com/ruby/rake" - s.licenses = ["MIT"] - - s.metadata = { - "bug_tracker_uri" => "https://github.com/ruby/rake/issues", - "changelog_uri" => "https://github.com/ruby/rake/releases", - "documentation_uri" => "https://ruby.github.io/rake", - "source_code_uri" => s.homepage - } - - s.files = [ - "History.rdoc", - "MIT-LICENSE", - "README.rdoc", - "doc/command_line_usage.rdoc", - "doc/example/Rakefile1", - "doc/example/Rakefile2", - "doc/example/a.c", - "doc/example/b.c", - "doc/example/main.c", - "doc/glossary.rdoc", - "doc/jamis.rb", - "doc/proto_rake.rdoc", - "doc/rake.1", - "doc/rakefile.rdoc", - "doc/rational.rdoc", - "exe/rake", - "lib/rake.rb", - "lib/rake/application.rb", - "lib/rake/backtrace.rb", - "lib/rake/clean.rb", - "lib/rake/cloneable.rb", - "lib/rake/cpu_counter.rb", - "lib/rake/default_loader.rb", - "lib/rake/dsl_definition.rb", - "lib/rake/early_time.rb", - "lib/rake/ext/core.rb", - "lib/rake/ext/string.rb", - "lib/rake/file_creation_task.rb", - "lib/rake/file_list.rb", - "lib/rake/file_task.rb", - "lib/rake/file_utils.rb", - "lib/rake/file_utils_ext.rb", - "lib/rake/invocation_chain.rb", - "lib/rake/invocation_exception_mixin.rb", - "lib/rake/late_time.rb", - "lib/rake/linked_list.rb", - "lib/rake/loaders/makefile.rb", - "lib/rake/multi_task.rb", - "lib/rake/name_space.rb", - "lib/rake/packagetask.rb", - "lib/rake/phony.rb", - "lib/rake/private_reader.rb", - "lib/rake/promise.rb", - "lib/rake/pseudo_status.rb", - "lib/rake/rake_module.rb", - "lib/rake/rake_test_loader.rb", - "lib/rake/rule_recursion_overflow_error.rb", - "lib/rake/scope.rb", - "lib/rake/task.rb", - "lib/rake/task_argument_error.rb", - "lib/rake/task_arguments.rb", - "lib/rake/task_manager.rb", - "lib/rake/tasklib.rb", - "lib/rake/testtask.rb", - "lib/rake/thread_history_display.rb", - "lib/rake/thread_pool.rb", - "lib/rake/trace_output.rb", - "lib/rake/version.rb", - "lib/rake/win32.rb", - "rake.gemspec" - ] - s.bindir = "exe" - s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) } - s.require_paths = ["lib"] - - s.required_ruby_version = Gem::Requirement.new(">= 2.3") - s.rdoc_options = ["--main", "README.rdoc"] -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md deleted file mode 100644 index 722b21e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/LICENSE.md +++ /dev/null @@ -1,27 +0,0 @@ -The MIT License (MIT) -===================== - -Copyright © 2009 Chad Humphries, David Chelimsky -Copyright © 2006 David Chelimsky, The RSpec Development Team -Copyright © 2005 Steven Baker - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the “Software”), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md deleted file mode 100644 index 4af390d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# RSpec - -Behaviour Driven Development for Ruby - -**The rspec metagem repository has been renamed to rspec-metagem, please update -any rspec/rspec Github references to rspec/rspec-metagem, this is in preparation -for a new mono-repo approach to RSpec dev to unify issue tracking and PR management** - -## Description - -rspec is a meta-gem, which depends on the -[rspec-core](https://github.com/rspec/rspec-core), -[rspec-expectations](https://github.com/rspec/rspec-expectations) -and [rspec-mocks](https://github.com/rspec/rspec-mocks) gems. Each of these -can be installed separately and loaded in isolation using `require`. Among -other benefits, this allows you to use rspec-expectations, for example, in -Test::Unit::TestCase if you happen to prefer that style. - -Conversely, if you like RSpec's approach to declaring example groups and -examples (`describe` and `it`) but prefer Test::Unit assertions and -[mocha](https://github.com/freerange/mocha), [rr](https://github.com/rr/rr) -or [flexmock](https://github.com/jimweirich/flexmock) for mocking, you'll be -able to do that without having to install or load the components of RSpec that -you're not using. - -## Documentation - -See http://rspec.info/documentation/ for links to documentation for all gems. - -## Install - - gem install rspec - -## Setup - - rspec --init - -## Contribute - -* [http://github.com/rspec/rspec-dev](http://github.com/rspec/rspec-dev) - -## Also see - -* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) -* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations) -* [https://github.com/rspec/rspec-mocks](https://github.com/rspec/rspec-mocks) -* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb deleted file mode 100644 index 36149e0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'rspec/core' -require 'rspec/version' - diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb deleted file mode 100644 index 0db236d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-3.13.2/lib/rspec/version.rb +++ /dev/null @@ -1,5 +0,0 @@ -module RSpec # :nodoc: - module Version # :nodoc: - STRING = '3.13.2' - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document deleted file mode 100644 index 52a564f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.document +++ /dev/null @@ -1,5 +0,0 @@ -lib/**/*.rb -- -README.md -LICENSE.md -Changelog.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts deleted file mode 100644 index 0e44326..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/.yardopts +++ /dev/null @@ -1,8 +0,0 @@ ---exclude features ---no-private ---markup markdown ---default-return void -- -Filtering.md -Changelog.md -LICENSE.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md deleted file mode 100644 index fb1eaff..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/Changelog.md +++ /dev/null @@ -1,2447 +0,0 @@ -### Development -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-core-v3.13.6...3-13-maintenance) - -### 3.13.6 / 2025-10-19 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.4...rspec-core-v3.13.5) - -Bug Fixes: - -* Add explicit block parameter to `RSpec::World::Null.traverse_example_group_trees_until` to - prevent warning. (@viralpraxis, rspec/rspec#240) - -### 3.13.5 / 2025-06-25 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.4...rspec-core-v3.13.5) - -Bug Fixes: - -* Fix finding failed lines from frozen backtrace arrays. (Jon Rowe, #225) - -### 3.13.4 / 2025-05-27 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.3...rspec-core-v3.13.4) - -Bug Fixes: - -* Fix links in gemspec to point to the monorepo / homepage. - -### 3.13.3 / 2025-02-06 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-core-v3.13.4...rspec-core-v3.13.3) - -Bug fixes: - -* Fix reporter memorisation of `ExamplesNotification` used in `RSpec::Core::Reporter#finish` - by reusing an instance across notifcations. (Maxime Lapointe, rspec/rspec#172) -* Fix memorisation of `RSpec::Core::Example#location_rerun_argument`. - (Maxime Lapointe, rspec/rspec#173) - -### 3.13.2 / 2024-10-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.13.1...v3.13.2) - -Bug fixes: - -* `RSpec::Configuration#requires` will reflect files already required, whilst requiring - them. (Jon Rowe, rspec/rspec-core#3117) - -### 3.13.1 / 2024-09-02 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.13.0...v3.13.1) - -Bug fixes: - -* Sort ids to run as the original order to fix `--bisect`. (Maki Kawahara, rspec/rspec-core#3093) - -### 3.13.0 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.3...v3.13.0) - -Enhancements: - -* Support the `--backtrace` flag when using the JSON formatter. (Matt Larraz, rspec/rspec-core#2980) -* Ignore commented out lines in CLI config files (e.g. `.rspec`). (Junichi Ito, rspec/rspec-core#2984) -* Add `pending_failure_output` config option to allow skipping backtraces or - muting pending specs output. (Phil Pirozhkov, rspec/rspec-core#2957) -* Process `--dry-run` before configuration flags that read files so that introspecting - it returns the correct value. (Xenor Chang, rspec/rspec-core#3008) -* Allow specifying custom ordering strategies via `--order`. (Jon Rowe, rspec/rspec-core#3025) -* Use the improved `syntax_suggest` output for `SyntaxError` when available. - (Richard Schneeman, rspec/rspec-core#3015, rspec/rspec-core#3026) -* Add config option (`RSpec::Core::Configuration#full_cause_backtrace`) to print the - entire backtrace of an exception cause. (David Taylor, rspec/rspec-core#3046) - -### 3.12.3 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.2...v3.12.3) - -Bug fixes: - -* Use `__send__` in output wrapper to avoid issues with IO objects that implement `send` - like `Socket`. (Richard Platel, rspec/rspec-core#3045) - -### 3.12.2 / 2023-04-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.1...v3.12.2) - -Bug fixes: - -* Remove link to outdated documentation in generated output. (Jon Rowe, rspec/rspec-core#3035) - -### 3.12.1 / 2023-02-03 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.0...v3.12.1) - -Bug fixes: - -* Prevent multiple calls to `extra_failure_lines` from adding additional whitespace - around them when the lines already contain whitespace. (Jon Rowe, rspec/rspec-core#3006) - -### 3.12.0 / 2022-10-26 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.11.0...v3.12.0) - -* No changes, released to support other gems. - -### 3.11.0 / 2022-02-09 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.2...v3.11.0) - -Enhancements: - -* Improve pluralisation of words ending with `s` (like process). (Joshua Pinter, rspec/rspec-core#2779) -* Add ordering by file modification time (most recent first). (Matheus Richard, rspec/rspec-core#2778) -* Add `to_s` to reserved names for #let and #subject. (Nick Flückiger, rspec/rspec-core#2886) -* Introduce `RSpec.current_scope` to expose the current scope in which - RSpec is executing. e.g. `:before_example_hook`, `:example` etc. (@odinhb, rspec/rspec-core#2895) -* Add named bold colours as options for custom colours. (rspec/rspec-core#2913, rspec/rspec-core#2914) -* Warn when (but not prevent) a `SystemExit` occurs. (Jared Beck, rspec/rspec-core#2926) - -### 3.10.2 / 2022-01-27 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.1...v3.10.2) - -Bug fixes: - -* Ensure bisect communication uses consistent encoding. (Mike Jarema, rspec/rspec-core#2852) -* Fix exception presenter when the root cause exception has nil backtrace. - (Zinovyev Ivan, rspec/rspec-core#2903) -* Fix `inspect` output of `RSpec::Core::Example::Procsy` to namespace correctly. - (Keiko Kaneko, rspec/rspec-core#2915) -* Ensure formatters not exposing `#output` will not crash duplicate check. - (@niceking, rspec/rspec-core#2916) - -### 3.10.1 / 2020-12-27 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.0...v3.10.1) - -Bug fixes: - -* RSpec warning output was missing deprecations from Ruby, these are now included. - (Jon Rowe, rspec/rspec-core#2811) - -### 3.10.0 / 2020-10-30 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.3...v3.10.0) - -Enhancements: - -* Memoize `RSpec::Core::Formatters::ExceptionPresenter#exception_lines` to improve performance - with slow exception messages. (Maxime Lapointe, rspec/rspec-core#2743) -* Add configuration for an error exit code (to disambiguate errored builds from failed builds - by exit status). (Dana Sherson, rspec/rspec-core#2749) - -### 3.9.3 / 2020-09-30 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.2...v3.9.3) - -Bug Fixes: - -* Declare `ruby2_keywords` on `method_missing` for other gems. (Jon Rowe, rspec/rspec-core#2731) -* Ensure custom error codes are returned from bisect runs. (Jon Rowe, rspec/rspec-core#2732) -* Ensure `RSpec::Core::Configuration` predicate config methods return booleans. - (Marc-André Lafortune, rspec/rspec-core#2736) -* Prevent `rspec --bisect` from generating zombie processes while executing - bisect runs. (Benoit Tigeot, Jon Rowe, rspec/rspec-core#2739) -* Predicates for pending examples, (in `RSpec::Core::Example`, `#pending?`, `#skipped?` and - `#pending_fixed?`) now return boolean values rather than truthy values. - (Marc-André Lafortune, rspec/rspec-core#2756, rspec/rspec-core#2758) -* Exceptions which have a message which cannot be cast to a string will no longer - cause a crash. (Jon Rowe, rspec/rspec-core#2761) - -### 3.9.2 / 2020-05-02 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.1...v3.9.2) - -Bug Fixes: - -* Emit a warning when `around` hook is used with `:context` scope - (Phil Pirozhkov, rspec/rspec-core#2687) -* Prevent invalid implementations of `Exception#cause` from being treated as a - valid cause (and causing strange errors) in `RSpec::Core::Formatters::ExceptionPresenter`. - (Jon Rowe, rspec/rspec-core#2703) -* Correctly detect patterns when `rspec_opts` is an array in `RSpec::Core::RakeTask`. - (Marc-André Lafortune, rspec/rspec-core#2704) -* Make `RSpec.clear_examples` reset example counts for example groups. This fixes - an issue with re-running specs not matching ids. (Agis Anastasopoulos, rspec/rspec-core#2723) - -### 3.9.1 / 2019-12-28 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.9.0...v3.9.1) - -Bug Fixes: - -* Prevent bisect command from blocking when number of specs exceeds file - descriptor limit on OSX or Linux. (Benoit Tigeot, rspec/rspec-core#2669) -* Prevent warnings being issued on Ruby 2.7.0. (Jon Rowe, rspec/rspec-core#2680) - -### 3.9.0 / 2019-10-07 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.2...v3.9.0) - -Enhancements: - -* Improve the handling of errors during loading support files, if a file - errors before loading specs, RSpec will now skip loading the specs. - (David Rodríguez, rspec/rspec-core#2568) -* Add support for --example-matches to run examples by regular expression. - (Sam Joseph, Matt Rider, @okothkongo1, rspec/rspec-core#2586) -* Add `did_you_mean` suggestions for file names encountering a `LoadError` - outside of examples. (@obromios, rspec/rspec-core#2601) -* Add a minimalist quick fix style formatter, only outputs failures as - `file:line:message`. (Romain Tartière, rspec/rspec-core#2614) -* Convert string number values to integer when used for `RSpec::Configuration#fail_fast` - (Viktor Fonic, rspec/rspec-core#2634) -* Issue warning when invalid values are used for `RSpec::Configuration#fail_fast` - (Viktor Fonic, rspec/rspec-core#2634) -* Add support for running the Rake task in a clean environment. - (Jon Rowe, rspec/rspec-core#2632) -* Indent messages by there example group / example in the documentation formatter. - (Samuel Williams, rspec/rspec-core#2649) - -### 3.8.2 / 2019-06-29 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.1...v3.8.2) - -Bug Fixes: - -* Fix `config.define_derived_metadata` so that cascades are not triggered - until metadata has been assigned to the example or example group - (Myron Marston, rspec/rspec-core#2635). - -### 3.8.1 / 2019-06-13 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.8.0...v3.8.1) - -Bug Fixes: - -* Handle RSpec description(s) with japanese chars in CP932 encoded files. - (Benoit Tigeot, rspec/rspec-core#2575) -* When defining `let` methods that overwrite an existing method, prevent - a warning being issued by removing the old definition. (Jon Rowe, rspec/rspec-core#2593) -* Prevent warning on Ruby 2.6.0-rc1 (Keiji Yoshimi, rspec/rspec-core#2582) -* Fix `config.define_derived_metadata` so that it supports cascades. - (Myron Marston, rspec/rspec-core#2630). - -### 3.8.0 / 2018-08-04 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.1...v3.8.0) - -Enhancements: - -* Improve shell escaping used by `RSpec::Core::RakeTask` and `--bisect` so - that it works on `Pathname` objects. (Andrew Vit, rspec/rspec-core#2479) -* Nicely format errors encountered while loading files specified - by `--require` option. (Myron Marston, rspec/rspec-core#2504) -* Significantly improve the performance of `--bisect` on platforms that - support forking by replacing the shell-based runner with one that uses - forking so that RSpec and the application environment can be booted only - once, instead of once per spec run. (Myron Marston, rspec/rspec-core#2511) -* Provide a configuration API to pick which bisect runner is used for - `--bisect`. Pick a runner via `config.bisect_runner = :shell` or - `config.bisect_runner = :fork` in a file loaded by a `--require` - option passed at the command line or set in `.rspec`. (Myron Marston, rspec/rspec-core#2511) -* Support the [XDG Base Directory - Specification](https://specifications.freedesktop.org/basedir-spec/latest/) - for the global options file. `~/.rspec` is still supported when no - options file is found in `$XDG_CONFIG_HOME/rspec/options` (Magnus Bergmark, rspec/rspec-core#2538) -* Extract `RSpec.world.prepare_example_filtering` that sets up the - example filtering for custom RSpec runners. (Oleg Pudeyev, rspec/rspec-core#2552) - -Bug Fixes: - -* Prevent an `ArgumentError` when truncating backtraces with two identical - backtraces. (Systho, rspec/rspec-core#2515, Benoit Tigeot, rspec/rspec-core#2539) - -### 3.7.1 / 2018-01-02 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.0...v3.7.1) - -Bug Fixes: - -* Work around duplicate config hook regression introduced - by Ruby 2.5's lazy proc allocation. (Myron Marston, rspec/rspec-core#2497) - -### 3.7.0 / 2017-10-17 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0...v3.7.0) - -Enhancements: - -* Add `-n` alias for `--next-failure`. (Ian Ker-Seymer, rspec/rspec-core#2434) -* Improve compatibility with `--enable-frozen-string-literal` option - on Ruby 2.3+. (Pat Allan, rspec/rspec-core#2425, rspec/rspec-core#2427, rspec/rspec-core#2437) -* Do not run `:context` hooks for example groups that have been skipped. - (Devon Estes, rspec/rspec-core#2442) -* Add `errors_outside_of_examples_count` to the JSON formatter. - (Takeshi Arabiki, rspec/rspec-core#2448) - -Bug Fixes: - -* Improve compatibility with frozen string literal flag. (rspec/rspec-core#2425, Pat Allan) - -### 3.6.0 / 2017-05-04 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta2...v3.6.0) - -Enhancements: - -* Add seed information to JSON formatter output. (rspec/rspec-core#2388, Mitsutaka Mimura) -* Include example id in the JSON formatter output. (rspec/rspec-core#2369, Xavier Shay) -* Respect changes to `config.output_stream` after formatters have been - setup. (rspec/rspec-core#2401, rspec/rspec-core#2419, Ilya Lavrov) - -Bug Fixes: - -* Delay formatter loading until the last minute to allow accessing the reporter - without triggering formatter setup. (Jon Rowe, rspec/rspec-core#2243) -* Ensure context hook failures running before an example can access the - reporter. (Jon Jensen, rspec/rspec-core#2387) -* Multiple fixes to allow using the runner multiple times within the same - process: `RSpec.clear_examples` resets the formatter and no longer clears - shared examples, and streams can be used across multiple runs rather than - being closed after the first. (rspec/rspec-core#2368, Xavier Shay) -* Prevent unexpected `example_group_finished` notifications causing an error. - (rspec/rspec-core#2396, VTJamie) -* Fix bugs where `config.when_first_matching_example_defined` hooks would fire - multiple times in some cases. (Yuji Nakayama, rspec/rspec-core#2400) -* Default `last_run_status` to "unknown" when the `status` field in the - persistence file contains an unrecognized value. (rspec/rspec-core#2360, matrinox) -* Prevent `let` from defining an `initialize` method. (rspec/rspec-core#2414, Jon Rowe) - -### 3.6.0.beta2 / 2016-12-12 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta1...v3.6.0.beta2) - -Enhancements: - -* Include count of errors occurring outside examples in default summaries. - (rspec/rspec-core#2351, Jon Rowe) -* Warn when including shared example groups recursively. (rspec/rspec-core#2356, Jon Rowe) -* Improve failure snippet syntax highlighting with CodeRay to highlight - RSpec "keywords" like `expect`. (rspec/rspec-core#2358, Myron Marston) - -### 3.6.0.beta1 / 2016-10-09 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.4...v3.6.0.beta1) - -Enhancements: - -* Warn when duplicate shared examples definitions are loaded due to being - defined in files matching the spec pattern (e.g. `_spec.rb`) (rspec/rspec-core#2278, Devon Estes) -* Improve metadata filtering so that it can match against any object - that implements `===` instead of treating regular expressions as - special. (Myron Marston, rspec/rspec-core#2294) -* Improve `rspec -v` so that it prints out the versions of each part of - RSpec to prevent confusion. (Myron Marston, rspec/rspec-core#2304) -* Add `config.fail_if_no_examples` option which causes RSpec to fail if - no examples are found. (Ewa Czechowska, rspec/rspec-core#2302) -* Nicely format errors encountered while loading spec files. - (Myron Marston, rspec/rspec-core#2323) -* Improve the API for enabling and disabling color output (Josh - Justice, rspec/rspec-core#2321): - * Automatically enable color if the output is a TTY, since color is - nearly always desirable if the output can handle it. - * Introduce new CLI flag to force color on (`--force-color`), even - if the output is not a TTY. `--no-color` continues to work as well. - * Introduce `config.color_mode` for configuring the color from Ruby. - `:automatic` is the default and will produce color if the output is - a TTY. `:on` forces it on and `:off` forces it off. - -### 3.5.4 / 2016-09-30 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.3...v3.5.4) - -Bug Fixes: - -* Remove accumulated `ExampleGroup` constants when reseting RSpec, - preventing a memory leak. (TravisSpangle, rspec/rspec-core#2328) - -### 3.5.3 / 2016-09-02 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.2...v3.5.3) - -Bug Fixes: - -* When applying shared group metadata to a host group, overwrite - conflicting keys if the value in the host group was inherited from - a parent group instead of being specified at that level. - (Myron Marston, rspec/rspec-core#2307) -* Handle errors in `:suite` hooks and provide the same nicely formatted - output as errors that happen in examples. (Myron Marston, rspec/rspec-core#2316) -* Set the exit status to non-zero when an error occurs in an - `after(:context)` hook. (Myron Marston, rspec/rspec-core#2320) - -### 3.5.2 / 2016-07-28 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.1...v3.5.2) - -Bug Fixes: - -* Wait to report `example_finished` until the example's `execution_result` - has been completely filled in. (Myron Marston, rspec/rspec-core#2291) -* Make sure example block is still available when using `duplicate_with` - to clone examples. (bootstraponline, rspec/rspec-core#2298) -* Don't include the default `--pattern` in the Rake task when - `rspec_opts` specifies its own. (Jon Rowe, rspec/rspec-core#2305) - -### 3.5.1 / 2016-07-06 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0...v3.5.1) - -Bug Fixes: - -* Ensure that config hooks that are added to existing example groups are - added only once. (Eugene Kenny, rspec/rspec-core#2280) - -### 3.5.0 / 2016-07-01 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta4...v3.5.0) - -Enhancements: - -* Include any `SPEC_OPTS` in reproduction command printed at the end of - a bisect run. (Simon Coffey, rspec/rspec-core#2274) - -Bug Fixes: - -* Handle `--bisect` in `SPEC_OPTS` environment variable correctly so as - to avoid infinite recursion. (Simon Coffey, rspec/rspec-core#2271) - -### 3.5.0.beta4 / 2016-06-05 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta3...v3.5.0.beta4) - -Enhancements: - -* Filter out bundler stackframes from backtraces by default, since - Bundler 1.12 now includes its own frames in stack traces produced - by using `bundle exec`. (Myron Marston, rspec/rspec-core#2240) -* HTML Formatter uses exception presenter to get failure message - for consistency with other formatters. (@mrageh, rspec/rspec-core#2222) -* Load spec files in the order of the directories or files passed - at the command line, making it easy to make some specs run before - others in a one-off manner. For example, `rspec spec/unit - spec/acceptance --order defined` will run unit specs before acceptance - specs. (Myron Marston, rspec/rspec-core#2253) -* Add new `config.include_context` API for configuring global or - filtered inclusion of shared contexts in example groups. - (Myron Marston, rspec/rspec-core#2256) -* Add new `config.shared_context_metadata_behavior = :apply_to_host_groups` - option, which causes shared context metadata to be inherited by the - metadata hash of all host groups and examples instead of configuring - implicit auto-inclusion based on the passed metadata. (Myron Marston, rspec/rspec-core#2256) - -Bug Fixes: - -* Fix `--bisect` so it works on large spec suites that were previously triggering - "Argument list too long errors" due to all the spec locations being passed as - CLI args. (Matt Jones, rspec/rspec-core#2223). -* Fix deprecated `:example_group`-based filtering so that it properly - applies to matching example groups. (Myron Marston, rspec/rspec-core#2234) -* Fix `NoMethodError` caused by Java backtraces on JRuby. (Michele Piccirillo, rspec/rspec-core#2244) - -### 3.5.0.beta3 / 2016-04-02 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta2...v3.5.0.beta3) - -Enhancements: - -* Add new `config.filter_run_when_matching` API, intended to replace - the combination of `config.filter_run` and - `config.run_all_when_everything_filtered` (Myron Marston, rspec/rspec-core#2206) - -Bug Fixes: - -* Use the encoded string logic for source extraction. (Jon Rowe, rspec/rspec-core#2183) -* Fix rounding issue in duration formatting helper. (Fabersky, Jon Rowe, rspec/rspec-core#2208) -* Fix failure snippet extraction so that `def-end` snippets - ending with `end`-only line can be extracted properly. - (Yuji Nakayama, rspec/rspec-core#2215) - -### 3.5.0.beta2 / 2016-03-10 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta1...v3.5.0.beta2) - -Enhancements: - -* Remove unneeded `:execution_result` example group metadata, saving a - bit of memory. (Myron Marston, rspec/rspec-core#2172) -* Apply hooks registered with `config` to previously defined groups. - (Myron Marston, rspec/rspec-core#2189) -* `RSpec::Core::Configuration#reporter` is now public API under SemVer. - (Jon Rowe, rspec/rspec-core#2193) -* Add new `config.when_first_matching_example_defined` hook. (Myron - Marston, rspec/rspec-core#2175) - -### 3.5.0.beta1 / 2016-02-06 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.4...v3.5.0.beta1) - -Enhancements: - -* Add `RSpec::Core::ExampleGroup.currently_executing_a_context_hook?`, - primarily for use by rspec-rails. (Sam Phippen, rspec/rspec-core#2131) - -Bug Fixes: - -* Ensure `MultipleExceptionError` does not contain a recursive reference - to itself. (Sam Phippen, rspec/rspec-core#2133) - -### 3.4.4 / 2016-03-09 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.3...v3.4.4) - -Bug Fixes: - -* Fix `RSpec::Core::RakeTask` so that it works with Rake 11. - (Travis Grathwell, rspec/rspec-core#2197) - -### 3.4.3 / 2016-02-19 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.2...v3.4.3) - -Bug Fixes: - -* Prevent a `TypeError` from occurring when running via the rake task when - Ruby crashes. (Patrik Wenger, rspec/rspec-core#2161) -* Only consider example and group declaration lines from a specific file - when applying line number filtering, instead of considering all - declaration lines from all spec files. (Myron Marston, rspec/rspec-core#2170) -* Fix failure snippet extraction so that snippets that contain `do-end` style - block and end with `end`-only line can be extracted properly. - (Yuji Nakayama, rspec/rspec-core#2173) -* Prevent infinite recursion when an exception is caused by itself. - (Jon Rowe, rspec/rspec-core#2128) - -### 3.4.2 / 2016-01-26 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.1...v3.4.2) - -Bug Fixes: - -* Fix `rspec --profile` when an example calls `abort` or `exit`. - (Bradley Schaefer, rspec/rspec-core#2144) -* Fix `--drb` so that when no DRb server is running, it prevents - the DRb connection error from being listed as the cause of all - expectation failures. (Myron Marston, rspec/rspec-core#2156) -* Fix syntax highlighter so that it works when the `coderay` gem is - installed as a rubygem but not already available on your load path - (as happens when you use bundler). (Myron Marston, rspec/rspec-core#2159) - -### 3.4.1 / 2015-11-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.0...v3.4.1) - -Bug Fixes: - -* Fix backtrace formatter to handle backtraces that are `nil`. - (Myron Marston, rspec/rspec-core#2118) - -### 3.4.0 / 2015-11-11 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.3.2...v3.4.0) - -Enhancements: - -* Combine multiple `--pattern` arguments making them equivalent to - `--pattern=1,2,...,n`. (Jon Rowe, rspec/rspec-core#2002) -* Improve `inspect` and `to_s` output for `RSpec::Core::Example` - objects, replacing Ruby's excessively verbose output. (Gavin Miller, rspec/rspec-core#1922) -* Add `silence_filter_announcements` configuration option. - (David Raffensperger, rspec/rspec-core#2007) -* Add optional `example_finished` notification to the reporter protocol for - when you don't care about the example outcome. (Jon Rowe, rspec/rspec-core#2013) -* Switch `--bisect` to a recursion-based bisection algorithm rather than - a permutation-based one. This better handles cases where an example - depends upon multiple other examples instead of just one and minimizes - the number of runs necessary to determine that an example set cannot be - minimized further. (Simon Coffey, rspec/rspec-core#1997) -* Allow simple filters (e.g. `:symbol` key only) to be triggered by truthey - values. (Tim Mertens, rspec/rspec-core#2035) -* Remove unneeded warning about need for `ansicon` on Windows when using - RSpec's `--color` option. (Ashley Engelund, rspec/rspec-core#2038) -* Add option to configure RSpec to raise errors when issuing warnings. - (Jon Rowe, rspec/rspec-core#2052) -* Append the root `cause` of a failure or error to the printed failure - output when a `cause` is available. (Adam Magan) -* Stop rescuing `NoMemoryError`, `SignalExcepetion`, `Interrupt` and - `SystemExit`. It is dangerous to interfere with these. (Myron Marston, rspec/rspec-core#2063) -* Add `config.project_source_dirs` setting which RSpec uses to determine - if a backtrace line comes from your project source or from some - external library. It defaults to `spec`, `lib` and `app` but can be - configured differently. (Myron Marston, rspec/rspec-core#2088) -* Improve failure line detection so that it looks for the failure line - in any project source directory instead of just in the spec file. - In addition, if no backtrace lines can be found from a project source - file, we fall back to displaying the source of the first backtrace - line. This should virtually eliminate the "Unable to find matching - line from backtrace" messages. (Myron Marston, rspec/rspec-core#2088) -* Add support for `:extra_failure_lines` example metadata that will - be appended to the failure output. (bootstraponline, rspec/rspec-core#2092). -* Add `RSpec::Core::Example#duplicate_with` to produce new examples - with cloned metadata. (bootstraponline, rspec/rspec-core#2098) -* Add `RSpec::Core::Configuration#on_example_group_definition` to register - hooks to be invoked when example groups are created. (bootstraponline, rspec/rspec-core#2094) -* Add `add_example` and `remove_example` to `RSpec::Core::ExampleGroup` to - allow manipulating an example groups examples. (bootstraponline, rspec/rspec-core#2095) -* Display multiline failure source lines in failure output when Ripper is - available (MRI >= 1.9.2, and JRuby >= 1.7.5 && < 9.0.0.0.rc1). - (Yuji Nakayama, rspec/rspec-core#2083) -* Add `max_displayed_failure_line_count` configuration option - (defaults to 10). (Yuji Nakayama, rspec/rspec-core#2083) -* Enhance `fail_fast` option so it can take a number (e.g. `--fail-fast=3`) - to force the run to abort after the specified number of failures. - (Jack Scotti, rspec/rspec-core#2065) -* Syntax highlight the failure snippets in text formatters when `color` - is enabled and the `coderay` gem is installed on a POSIX system. - (Myron Marston, rspec/rspec-core#2109) - -Bug Fixes: - -* Lock `example_status_persistence_file` when reading from and writing - to it to prevent race conditions when multiple processes try to use - it. (Ben Woosley, rspec/rspec-core#2029) -* Fix regression in 3.3 that caused spec file names with square brackets in - them (such as `1[]_spec.rb`) to not be loaded properly. (Myron Marston, rspec/rspec-core#2041) -* Fix output encoding issue caused by ASCII literal on 1.9.3 (Jon Rowe, rspec/rspec-core#2072) -* Fix requires in `rspec/core/rake_task.rb` to avoid double requires - seen by some users. (Myron Marston, rspec/rspec-core#2101) - -### 3.3.2 / 2015-07-15 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.3.1...v3.3.2) - -Bug Fixes: - -* Fix formatters to handle exceptions for which `backtrace` returns `nil`. - (Myron Marston, rspec/rspec-core#2023) -* Fix duplicate formatter detection so that it allows subclasses of formatters - to be added. (Sebastián Tello, rspec/rspec-core#2019) - -### 3.3.1 / 2015-06-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.3.0...v3.3.1) - -Bug Fixes: - -* Correctly run `before(:suite)` (and friends) in the context of an example - group instance, thus making the expected RSpec environment available. - (Jon Rowe, rspec/rspec-core#1986) - -### 3.3.0 / 2015-06-12 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.3...v3.3.0) - -Enhancements: - -* Expose the reporter used to run examples via `RSpec::Core::Example#reporter`. - (Jon Rowe, rspec/rspec-core#1866) -* Make `RSpec::Core::Reporter#message` a public supported API. (Jon Rowe, rspec/rspec-core#1866) -* Allow custom formatter events to be published via - `RSpec::Core::Reporter#publish(event_name, hash_of_attributes)`. (Jon Rowe, rspec/rspec-core#1869) -* Remove dependency on the standard library `Set` and replace with `RSpec::Core::Set`. - (Jon Rowe, rspec/rspec-core#1870) -* Assign a unique id to each example and group so that they can be - uniquely identified, even for shared examples (and similar situations) - where the location isn't unique. (Myron Marston, rspec/rspec-core#1884) -* Use the example id in the rerun command printed for failed examples - when the location is not unique. (Myron Marston, rspec/rspec-core#1884) -* Add `config.example_status_persistence_file_path` option, which is - used to persist the last run status of each example. (Myron Marston, rspec/rspec-core#1888) -* Add `:last_run_status` metadata to each example, which indicates what - happened the last time an example ran. (Myron Marston, rspec/rspec-core#1888) -* Add `--only-failures` CLI option which filters to only the examples - that failed the last time they ran. (Myron Marston, rspec/rspec-core#1888) -* Add `--next-failure` CLI option which allows you to repeatedly focus - on just one of the currently failing examples, then move on to the - next failure, etc. (Myron Marston, rspec/rspec-core#1888) -* Make `--order random` ordering stable, so that when you rerun a - subset with a given seed, the examples will be order consistently - relative to each other. (Myron Marston, rspec/rspec-core#1908) -* Set example group constant earlier so errors when evaluating the context - include the example group name (Myron Marson, rspec/rspec-core#1911) -* Make `let` and `subject` threadsafe. (Josh Cheek, rspec/rspec-core#1858) -* Add version information into the JSON formatter. (Mark Swinson, rspec/rspec-core#1883) -* Add `--bisect` CLI option, which will repeatedly run your suite in - order to isolate the failures to the smallest reproducible case. - (Myron Marston, rspec/rspec-core#1917) -* For `config.include`, `config.extend` and `config.prepend`, apply the - module to previously defined matching example groups. (Eugene Kenny, rspec/rspec-core#1935) -* When invalid options are parsed, notify users where they came from - (e.g. `.rspec` or `~/.rspec` or `ENV['SPEC_OPTS']`) so they can - easily find the source of the problem. (Myron Marston, rspec/rspec-core#1940) -* Add pending message contents to the json formatter output. (Jon Rowe, rspec/rspec-core#1949) -* Add shared group backtrace to the output displayed by the built-in - formatters for pending examples that have been fixed. (Myron Marston, rspec/rspec-core#1946) -* Add support for `:aggregate_failures` metadata. Tag an example or - group with this metadata and it'll use rspec-expectations' - `aggregate_failures` feature to allow multiple failures in an example - and list them all, rather than aborting on the first failure. (Myron - Marston, rspec/rspec-core#1946) -* When no formatter implements #message add a fallback to prevent those - messages being lost. (Jon Rowe, rspec/rspec-core#1980) -* Profiling examples now takes into account time spent in `before(:context)` - hooks. (Denis Laliberté, Jon Rowe, rspec/rspec-core#1971) -* Improve failure output when an example has multiple exceptions, such - as one from an `it` block and one from an `after` block. (Myron Marston, rspec/rspec-core#1985) - -Bug Fixes: - -* Handle invalid UTF-8 strings within exception methods. (Benjamin Fleischer, rspec/rspec-core#1760) -* Fix Rake Task quoting of file names with quotes to work properly on - Windows. (Myron Marston, rspec/rspec-core#1887) -* Fix `RSpec::Core::RakeTask#failure_message` so that it gets printed - when the task failed. (Myron Marston, rspec/rspec-core#1905) -* Make `let` work properly when defined in a shared context that is applied - to an individual example via metadata. (Myron Marston, rspec/rspec-core#1912) -* Ensure `rspec/autorun` respects configuration defaults. (Jon Rowe, rspec/rspec-core#1933) -* Prevent modules overriding example group defined methods when included, - prepended or extended by config defined after an example group. (Eugene Kenny, rspec/rspec-core#1935) -* Fix regression which caused shared examples to be mistakenly run when specs - where filtered to a particular location. (Ben Axnick, rspec/rspec-core#1963) -* Fix time formatting logic so that it displays 70 seconds as "1 minute, - 10 seconds" rather than "1 minute, 1 second". (Paul Brennan, rspec/rspec-core#1984) -* Fix regression where the formatter loader would allow duplicate formatters. - (Jon Rowe, rspec/rspec-core#1990) - -### 3.2.3 / 2015-04-06 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.2...v3.2.3) - -Bug Fixes: - -* Fix how the DSL methods are defined so that RSpec is compatible with - gems that define methods of the same name on `Kernel` (such as - the `its-it` gem). (Alex Kwiatkowski, Ryan Ong, rspec/rspec-core#1907) -* Fix `before(:context) { skip }` so that it does not wrongly cause the - spec suite to exit with a non-zero status when no examples failed. - (Myron Marston, rspec/rspec-core#1926) - -### 3.2.2 / 2015-03-11 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.1...v3.2.2) - -Bug Fixes: - -* Fix regression in 3.2.0 that allowed tag-filtered examples to - run even if there was a location filter applied to the spec - file that was intended to limit the file to other examples. - (rspec/rspec-core#1894, Myron Marston) - -### 3.2.1 / 2015-02-23 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.0...v3.2.1) - -Bug Fixes: - -* Notify start-of-run seed _before_ `start` notification rather than - _after_ so that formatters like Fuubar work properly. (Samuel Esposito, rspec/rspec-core#1882) - -### 3.2.0 / 2015-02-03 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.7...v3.2.0) - -Enhancements: - -* Improve the `inspect` output of example groups. (Mike Dalton, rspec/rspec-core#1687) -* When rake task fails, only output the command if `verbose` flag is - set. (Ben Snape, rspec/rspec-core#1704) -* Add `RSpec.clear_examples` as a clear way to reset examples in between - spec runs, whilst retaining user configuration. (Alexey Fedorov, rspec/rspec-core#1706) -* Reduce string allocations when defining and running examples by 70% - and 50% respectively. (Myron Marston, rspec/rspec-core#1738) -* Removed dependency on pathname from stdlib. (Sam Phippen, rspec/rspec-core#1703) -* Improve the message presented when a user hits Ctrl-C. - (Alex Chaffee rspec/rspec-core#1717, rspec/rspec-core#1742) -* Improve shared example group inclusion backtrace displayed - in failed example output so that it works for all methods - of including shared example groups and shows all inclusion - locations. (Myron Marston, rspec/rspec-core#1763) -* Issue seed notification at start (as well as the end) of the reporter - run. (Arlandis Word, rspec/rspec-core#1761) -* Improve the documentation of around hooks. (Jim Kingdon, rspec/rspec-core#1772) -* Support prepending of modules into example groups from config and allow - filtering based on metadata. (Arlandis Word, rspec/rspec-core#1806) -* Emit warnings when `:suite` hooks are registered on an example group - (where it has always been ignored) or are registered with metadata - (which has always been ignored). (Myron Marston, rspec/rspec-core#1805) -* Provide a friendly error message when users call RSpec example group - APIs (e.g. `context`, `describe`, `it`, `let`, `before`, etc) from - within an example where those APIs are unavailable. (Myron Marston, rspec/rspec-core#1819) -* Provide a friendly error message when users call RSpec example - APIs (e.g. `expect`, `double`, `stub_const`, etc) from - within an example group where those APIs are unavailable. - (Myron Marston, rspec/rspec-core#1819) -* Add new `RSpec::Core::Sandbox.sandboxed { }` API that facilitates - testing RSpec with RSpec, allowing you to define example groups - and example from within an example without affecting the global - `RSpec.world` state. (Tyler Ball, 1808) -* Apply line-number filters only to the files they are scoped to, - allowing you to mix filtered and unfiltered files. (Myron Marston, rspec/rspec-core#1839) -* When dumping pending examples, include the failure details so that you - don't have to un-pend the example to see it. (Myron Marston, rspec/rspec-core#1844) -* Make `-I` option support multiple values when separated by - `File::PATH_SEPARATOR`, such as `rspec -I foo:bar`. This matches - the behavior of Ruby's `-I` option. (Fumiaki Matsushima, rspec/rspec-core#1855). -* Treat each example as having a singleton example group for the - purposes of applying metadata-based features that normally apply - to example groups to individually tagged examples. For example, - `RSpec.shared_context "Uses redis", :uses_redis` will now apply - to individual examples tagged with `:uses_redis`, as will - `config.include RedisHelpers, :uses_redis`, and - `config.before(:context, :uses_redis) { }`, etc. (Myron Marston, rspec/rspec-core#1749) - -Bug Fixes: - -* When assigning generated example descriptions, surface errors - raised by `matcher.description` in the example description. - (Myron Marston, rspec/rspec-core#1771) -* Don't consider expectations from `after` hooks when generating - example descriptions. (Myron Marston, rspec/rspec-core#1771) -* Don't apply metadata-filtered config hooks to examples in groups - with matching metadata when those examples override the parent - metadata value to not match. (Myron Marston, rspec/rspec-core#1796) -* Fix `config.expect_with :minitest` so that `skip` uses RSpec's - implementation rather than Minitest's. (Jonathan Rochkind, rspec/rspec-core#1822) -* Fix `NameError` caused when duplicate example group aliases are defined and - the DSL is not globally exposed. (Aaron Kromer, rspec/rspec-core#1825) -* When a shared example defined in an external file fails, use the host - example group (from a loaded spec file) for the re-run command to - ensure the command will actually work. (Myron Marston, rspec/rspec-core#1835) -* Fix location filtering to work properly for examples defined in - a nested example group within a shared example group defined in - an external file. (Bradley Schaefer, Xavier Shay, Myron Marston, rspec/rspec-core#1837) -* When a pending example fails (as expected) due to a mock expectation, - set `RSpec::Core::Example::ExecutionResult#pending_exception` -- - previously it was not being set but should have been. (Myron Marston, rspec/rspec-core#1844) -* Fix rake task to work when `rspec-core` is installed in a directory - containing a space. (Guido Günther, rspec/rspec-core#1845) -* Fix regression in 3.1 that caused `describe Regexp` to raise errors. - (Durran Jordan, rspec/rspec-core#1853) -* Fix regression in 3.x that caused the profile information to be printed - after the summary. (Max Lincoln, rspec/rspec-core#1857) -* Apply `--seed` before loading `--require` files so that required files - can access the provided seed. (Myron Marston, rspec/rspec-core#1745) -* Handle `RSpec::Core::Formatters::DeprecationFormatter::FileStream` being - reopened with an IO stream, which sometimes happens with spring. - (Kevin Mook, rspec/rspec-core#1757) - -### 3.1.7 / 2014-10-11 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.6...v3.1.7) - -Bug Fixes: - -* Fix `Metadata.relative_path` so that for a current directory of - `/foo/bar`, `/foo/bar_1` is not wrongly converted to `._1`. - (Akos Vandra, rspec/rspec-core#1730) -* Prevent constant lookup mistakenly finding `RSpec::ExampleGroups` generated - constants on 1.9.2 by appending a trailing `_` to the generated names. - (Jon Rowe, rspec/rspec-core#1737) -* Fix bug in `:pending` metadata. If it got set in any way besides passing - it as part of the metadata literal passed to `it` (such as by using - `define_derived_metadata`), it did not have the desired effect, - instead marking the example as `:passed`. (Myron Marston, rspec/rspec-core#1739) - -### 3.1.6 / 2014-10-08 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.5...v3.1.6) - -Bug Fixes: - -* Fix regression in rake task pattern handling, that prevented patterns - that were relative from the current directory rather than from `spec` - from working properly. (Myron Marston, rspec/rspec-core#1734) -* Prevent rake task from generating duplicate load path entries. - (Myron Marston, rspec/rspec-core#1735) - -### 3.1.5 / 2014-09-29 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.4...v3.1.5) - -Bug Fixes: - -* Fix issue with the rake task incorrectly escaping strings on Windows. - (Jon Rowe rspec/rspec-core#1718) -* Support absolute path patterns. While this wasn't officially supported - previously, setting `rake_task.pattern` to an absolute path pattern in - RSpec 3.0 and before worked since it delegated to `FileList` internally - (but now just forwards the pattern on to the `rspec` command). - (Myron Marston, rspec/rspec-core#1726) - -### 3.1.4 / 2014-09-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.3...v3.1.4) - -Bug Fixes: - -* Fix implicit `subject` when using `describe false` or `describe nil` - so that it returns the provided primitive rather than the string - representation. (Myron Marston, rspec/rspec-core#1710) -* Fix backtrace filtering to allow code in subdirectories of your - current working directory (such as vendor/bundle/...) to be filtered - from backtraces. (Myron Marston, rspec/rspec-core#1708) - -### 3.1.3 / 2014-09-15 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.2...v3.1.3) - -Bug Fixes: - -* Fix yet another regression in rake task pattern handling, to allow - `task.pattern = FileList["..."]` to work. That was never intended - to be supported but accidentally worked in 3.0 and earlier. - (Myron Marston, rspec/rspec-core#1701) -* Fix pattern handling so that files are normalized to absolute paths - before subtracting the `--exclude-pattern` matched files from the - `--pattern` matched files so that it still works even if the patterns - are in slightly different forms (e.g. one starting with `./`). - (Christian Nelson, rspec/rspec-core#1698) - -### 3.1.2 / 2014-09-08 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.1...v3.1.2) - -Bug Fixes: - -* Fix another regression in rake task pattern handling, so that patterns - that start with `./` still work. (Christian Nelson, rspec/rspec-core#1696) - -### 3.1.1 / 2014-09-05 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.0...v3.1.1) - -Bug Fixes: - -* Fix a regression in rake task pattern handling, so that `rake_task.pattern = array` - works again. While we never intended to support array values (or even knew that worked!), - the implementation from 3.0 and earlier used `FileList` internally, which allows arrays. - The fix restores the old behavior. (Myron Marston, rspec/rspec-core#1694) - -### 3.1.0 / 2014-09-04 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.4...v3.1.0) - -Enhancements: - -* Update files generated by `rspec --init` so that warnings are enabled - in commented out section of `spec_helper` rather than `.rspec` so users - have to consciously opt-in to the setting. (Andrew Hooker, rspec/rspec-core#1572) -* Update `spec_helper` generated by `rspec --init` so that it sets the new - rspec-expectations `include_chain_clauses_in_custom_matcher_descriptions` - config option (which will be on by default in RSpec 4) and also sets the - rspec-mocks `verify_partial_doubles` option (which will also default - to on in RSpec 4). (Myron Marston, rspec/rspec-core#1647) -* Provide an `inspect` output for example procsy objects (used in around - hooks) that doesn't make them look like procs. (Jon Rowe, rspec/rspec-core#1620) -* Remove a few unneeded `require` statements from - `rspec/core/rake_task.rb`, making it even more lighterweight. - (Myron Marston, rspec/rspec-core#1640) -* Allow rspec-core to be used when neither rspec-mocks or - rspec-expectations are installed, without requiring any - user configuration. (Sam Phippen, Myron Marston, rspec/rspec-core#1615) -* Don't filter out gems from backtraces by default. (The RSpec - gems will still be filtered). User feedback has indicated - that including gems in default backtraces will be useful. - (Myron Marston, rspec/rspec-core#1641) -* Add new `config.filter_gems_from_backtrace "rack", "rake"` API - to easily filter the named gems from backtraces. (Myron Marston, rspec/rspec-core#1682) -* Fix default backtrace filters so that the RSpec binary is - excluded when installing RSpec as a bundler `:git` dependency. - (Myron Marston, rspec/rspec-core#1648) -* Simplify command generated by the rake task so that it no longer - includes unnecessary `-S`. (Myron Marston, rspec/rspec-core#1559) -* Add `--exclude-pattern` CLI option, `config.exclude_pattern =` config - option and `task.exclude_pattern =` rake task config option. Matching - files will be excluded. (John Gesimondo, Myron Marston, rspec/rspec-core#1651, rspec/rspec-core#1671) -* When an around hook fails to execute the example, mark it as - pending (rather than passing) so the user is made aware of the - fact that the example did not actually run. (Myron Marston, rspec/rspec-core#1660) -* Remove dependency on `FileUtils` from the standard library so that users do - not get false positives where their code relies on it but they are not - requiring it. (Sam Phippen, rspec/rspec-core#1565) - -Bug Fixes: - -* Fix rake task `t.pattern =` option so that it does not run all specs - when it matches no files, by passing along a `--pattern` option to - the `rspec` command, rather than resolving the file list and passing - along the files individually. (Evgeny Zislis, rspec/rspec-core#1653) -* Fix rake task default pattern so that it follows symlinks properly. - (Myron Marston, rspec/rspec-core#1672) -* Fix default pattern used with `rspec` command so that it follows - symlinks properly. (Myron Marston, rspec/rspec-core#1672) -* Change how we assign constant names to example group classes so that - it avoids a problem with `describe "Core"`. (Daniela Wellisz, rspec/rspec-core#1679) -* Handle rendering exceptions that have a different encoding than that - of their original source file. (Jon Rowe, rspec/rspec-core#1681) -* Allow access to message_lines without colour for failed examples even - when they're part of a shared example group. (tomykaira, rspec/rspec-core#1689) - -### 3.0.4 / 2014-08-14 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.3...v3.0.4) - -Bug Fixes: - -* Fix processing order of CLI options so that if `config.files_to_run` - is accessed from a file loaded by `--require`, `--pattern` is still - applied. (Myron Marston, rspec/rspec-core#1652) -* Fix `config.pattern=` so that it still takes affect even if - `config.files_to_run` has already been accessed. (Myron Marston, rspec/rspec-core#1652) - -### 3.0.3 / 2014-07-21 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.2...v3.0.3) - -Bug Fixes: - -* Properly convert both parts of a description into strings before - concatenation. (@nicklink483, rspec/rspec-core#1636) -* Exclude the working directory when figuring out folders to ignore. - (Jon Rowe, Myron Marston, rspec/rspec-core#1616) -* Allow `::RSpec::Core::Notifications::FailedExampleNotification#message_lines` - to be accessed without a colouriser. (@tomykaira, rspec/rspec-core#1637) - -### 3.0.2 / 2014-06-19 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.1...v3.0.2) - -Bug Fixes: - -* Fix regression in CLI option handling that prevented `--tag slow` - passed at the command line from overriding `--tag ~slow` in `.rspec`. - (Colin Jones, rspec/rspec-core#1602) -* Fix metadata `:example_group` deprecation warning so that it gets - issued at the call site of the configuration that specified it as - a filter rather than later when an example group is defined. - (Myron Marston, rspec/rspec-core#1562) -* Make the line that is printed when a shared example group fails indicating - where the concrete example group is white, separating it from the stack trace - that is produced for the failure. (Sam Phippen, Jon Rowe, rspec/rspec-core#1606) - -### 3.0.1 / 2014-06-12 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0...v3.0.1) - -Bug Fixes: - -* Fix a couple ruby warnings caused by rspec-core when loaded. - (Prem Sichanugrist, rspec/rspec-core#1584) -* Example groups named `Config` will no longer cause a Ruby warning to be - issued. (Jimmy Cuadra, rspec/rspec-core#1580) - -### 3.0.0 / 2014-06-01 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.rc1...v3.0.0) - -Bug Fixes: - -* Fix `BaseTextFormatter` so that it does not re-close a closed output - stream. (Myron Marston) -* Fix regression in metadata that caused the metadata hash of a top-level - example group to have a `:parent_example_group` key even though it has - no parent example group. (Myron Marston) - -Enhancements: - -* Alter the default `spec_helper.rb` to no longer recommend - `config.full_backtrace = true` see rspec/rspec-core#1536 for discussion. (Jon Rowe) - -### 3.0.0.rc1 / 2014-05-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.beta2...v3.0.0.rc1) - -Breaking Changes for 3.0.0: - -* Change `described_class` so that in a nested group like `describe - MyClass`, it returns `MyClass` rather than the outer group's described - class. (Myron Marston) -* Refactor filter manager so that it no longer subclasses Hash and has a - tighter, more domain-specific interface. (Sergey Pchelincev) -* Remove legacy colours definitions from `BaseTextFormatter`. (Jon Rowe) -* Remove console color definitions from `BaseTextFormatter`. (Jon Rowe) -* Restructure example group metadata so that the computed keys are - exposed directly off of the metadata hash rather than being on - a nested `:example_group` subhash. In addition, the parent example - group metadata is now available as `[:parent_example_group]` rather - than `[:example_group][:example_group]`. Deprecated access via the - old key structure is still provided. (Myron Marston) -* Remove `:describes` metadata key. It duplicates `:described_class` - for no good reason. Deprecated access via `:describes` is still - provided. (Myron Marston) -* Rename `:example_group_block` metadata key to `:block`. - (Myron Marston) -* Remove deprecated `RSpec::Core::Example#options`. (Myron Marston) -* Move `BaseTextFormatter#colorize_summary` to `SummaryNotification#colorize_with` - (Jon Rowe). -* `describe some_hash` treated `some_hash` as metadata in RSpec 2.x but - will treat it as the described object in RSpec 3.0. Metadata must - always come after the description args. (Myron Marston) -* Remove deprecated `display_name` alias of `ExampleGroup.description`. - (Myron Marston) -* Remove deprecated `describes` alias of `ExampleGroup.described_class`. - (Myron Marston) -* Remove deprecated `RSpec::Core::ExampleGroup.alias_it_behaves_like_to`. - Use `RSpec::Core::Configuration#alias_it_behaves_like_to` instead. - (Myron Marston) -* Remove deprecated `RSpec::Core::ExampleGroup.alias_example_to`. - Use `RSpec::Core::Configuration#alias_example_to` instead. - (Myron Marston) -* Removed `focused` example alias and change example/group aliases - `fit`, `focus`, `fcontext` and `fdescribe` to no longer include - `:focused => true` metadata. They only contain `:focus => true` - metadata now. This means that you will need to filter them with - `filter_run :focus`, not `filter_run :focused`. (Myron Marston) -* Remove `--line-number` filtering. It's semantically dubious since it's - a global filter (potentially applied to multiple files) but there's no - meaningful connection between the same line number in multiple files. - Instead use the `rspec path/to/spec.rb:23:46` form, which is terser - and makes more sense as it is scoped to a file. (Myron Marston) -* Remove `--default_path` as an alias for `--default-path`. (Jon Rowe) -* Remove deprecated `share_examples_for`. There's still - `shared_examples` and `shared_examples_for`. (Myron Marston) -* Rename `RSpec::Core::Configuration#warnings` to - `RSpec::Core::Configuration#warnings?` since it's a boolean flag. - (Myron Marston) -* RSpec's global state is no longer reset after a spec run. This gives - more flexibility to alternate runners to decide when and if they - want the state reset. Alternate runners are now responsible for - calling this (or doing a similar reset) if they are going to run - the spec suite multiple times in the same process. (Sam Phippen) -* Merge `RSpec::Core::CommandLine` (never formally declared public) - into `RSpec::Core::Runner`. (Myron Marston) -* Remove `color_enabled` as an alias of `color`. (Jon Rowe) -* Remove `backtrace_cleaner` as an alias of `backtrace_formatter`. (Jon Rowe) -* Remove `filename_pattern` as an alias of `pattern`. (Jon Rowe) -* Extract support for legacy formatters to `rspec-legacy_formatters`. (Jon Rowe) -* `RSpec::Configuration#formatters` now returns a dup to prevent mutation. (Jon Rowe) -* Replace `stdlib` as an available expectation framework with `test_unit` and - `minitest`. (Aaron Kromer) -* Remove backtrace formatting helpers from `BaseTextFormatter`. (Jon Rowe) -* Extract profiler support to `ProfileFormatter` and `ProfileNotification`. - Formatters should implement `dump_profile` if they wish to respond to `--profile`. - (Jon Rowe) -* Extract remaining formatter state to reporter and notifications. Introduce - `ExamplesNotification` to share information about examples that was previously - held in `BaseFormatter`. (Jon Rowe) - -Enhancements: - -* Add `config.default_formatter` attribute, which can be used to set a - formatter which will only be used if no other formatter is set - (e.g. via `--formatter`). (Myron Marston) -* Support legacy colour definitions in `LegacyFormatterAdaptor`. (Jon Rowe) -* Migrate `execution_result` (exposed by metadata) from a hash to a - first-class object with appropriate attributes. `status` is now - stored and returned as a symbol rather than a string. It retains - deprecated hash behavior for backwards compatibility. (Myron Marston) -* Provide console code helper for formatters. (Jon Rowe) -* Use raw ruby hashes for the metadata hashes rather than a subclass of - a hash. Computed metadata entries are now computed in advance rather - than being done lazily on first access. (Myron Marston) -* Add `:block` metadata entry to the example metadata, bringing - parity with `:block` in the example group metadata. (Myron Marston) -* Add `fspecify` and `fexample` as aliases of `specify` and `example` - with `:focus => true` metadata for parity with `fit`. (Myron Marston) -* Add legacy support for `colorize_summary`. (Jon Rowe) -* Restructure runner so it can be more easily customized in a subclass - for an alternate runner. (Ben Hoskings) -* Document `RSpec::Core::ConfigurationOptions` as an officially - supported public API. (Myron Marston) -* Add `--deprecation-out` CLI option which directs deprecation warnings - to the named file. (Myron Marston) -* Minitest 5 compatability for `expect_with :stdlib` (now available as - `expect_with :minitest`). (Xavier Shay) -* Reporter now notifies formatters of the load time of RSpec and your - specs via `StartNotification` and `SummaryNotification`. (Jon Rowe) -* Add `disable_monkey_patching!` config option that disables all monkey - patching from whatever pieces of RSpec you use. (Alexey Fedorov) -* Add `Pathname` support for setting all output streams. (Aaron Kromer) -* Add `config.define_derived_metadata`, which can be used to apply - additional metadata to all groups or examples that match a given - filter. (Myron Marston) -* Provide formatted and colorized backtraces via `FailedExampleNotification` - and send `PendingExampleFixedNotifications` when the error is due to a - passing spec you expect to fail. (Jon Rowe) -* Add `dump_profile` to formatter API to allow formatters to implement - support for `--profile`. (Jon Rowe) -* Allow colourising text via `ConsoleCodes` with RSpec 'states' - (e.g. `:success`, `:failure`) rather than direct colour codes. (Jon Rowe) -* Expose `fully_formatted` methods off the formatter notification objects - that make it easy for a custom formatter to produce formatted output - like rspec-core's. (Myron Marston) - -Bug Fixes: - -* Fix `spec_helper.rb` file generated by `rspec --init` so that the - recommended settings correctly use the documentation formatter - when running one file. (Myron Marston) -* Fix ordering problem where descriptions were generated after - tearing down mocks, which resulted in unexpected exceptions. - (Bradley Schaefer, Aaron Kromer, Andrey Savchenko) -* Allow a symbol to be used as an implicit subject (e.g. `describe - :foo`). (Myron Marston) -* Prevent creating an isolated context (i.e. using `RSpec.describe`) when - already inside a context. There is no reason to do this, and it could - potentially cause unexpected bugs. (Xavier Shay) -* Fix shared example group scoping so that when two shared example - groups share the same name at different levels of nested contexts, - the one in the nearest context is used. (Myron Marston) -* Fix `--warnings` option so that it enables warnings immediately so - that it applies to files loaded by `--require`. (Myron Marston) -* Issue a warning when you set `config.deprecation_stream` too late for - it to take effect because the reporter has already been setup. (Myron Marston) -* Add the full `RSpec::Core::Example` interface to the argument yielded - to `around` hooks. (Myron Marston) -* Line number always takes precendence when running specs with filters. - (Xavier Shay) -* Ensure :if and :unless metadata filters are treated as a special case - and are always in-effect. (Bradley Schaefer) -* Ensure the currently running installation of RSpec is used when - the rake task shells out to `rspec`, even if a newer version is also - installed. (Postmodern) -* Using a legacy formatter as default no longer causes an infinite loop. - (Xavier Shay) - -### 3.0.0.beta2 / 2014-02-17 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.beta1...v3.0.0.beta2) - -Breaking Changes for 3.0.0: - -* Make `mock_with` option more strict. Strings are no longer supported - (e.g. `mock_with "mocha"`) -- use a symbol instead. Also, unrecognized - values will now result in an error rather than falling back to the - null mocking adapter. If you want to use the null mocking adapter, - use `mock_with :nothing` (as has been documented for a long time). - (Myron Marston) -* Remove support for overriding RSpec's built-in `:if` and `:unless` - filters. (Ashish Dixit) -* Custom formatters are now required to call - `RSpec::Core::Formatters.register(formatter_class, *notifications)` - where `notifications` is the list of events the formatter wishes to - be notified about. Notifications are handled by methods matching the - names on formatters. This allows us to add or remove notifications - without breaking existing formatters. (Jon Rowe) -* Change arguments passed to formatters. Rather than passing multiple - arguments (which limits are ability to add additional arguments as - doing so would break existing formatters), we now pass a notification - value object that exposes the same data via attributes. This will - allow us to add new bits of data to a notification event without - breaking existing formatters. (Jon Rowe) -* Remove support for deprecated `:alias` option for - `RSpec.configuration.add_setting`. (Myron Marston) -* Remove support for deprecated `RSpec.configuration.requires = [...]`. - (Myron Marston) -* Remove support for deprecated `--formatter` CLI option. (Myron Marston) -* Remove support for deprecated `--configure` CLI option. (Myron Marston) -* Remove support for deprecated `RSpec::Core::RakeTask#spec_opts=`. - (Myron Marston) -* An example group level `pending` block or `:pending` metadata now executes - the example and cause a failure if it passes, otherwise it will be pending if - it fails. The old "never run" behaviour is still used for `xexample`, `xit`, - and `xspecify`, or via a new `skip` method or `:skip` metadata option. - (Xavier Shay) -* After calling `pending` inside an example, the remainder of the example will - now be run. If it passes a failure is raised, otherwise the example is marked - pending. The old "never run" behaviour is provided a by a new `skip` method. - (Xavier Shay) -* Pending blocks inside an example have been removed as a feature with no - direct replacement. Use `skip` or `pending` without a block. (Xavier Shay) -* Pending statement is no longer allowed in `before(:all)` hooks. Use `skip` - instead. (Xavier Shay) -* Remove `show_failures_in_pending_blocks` configuration option. (Xavier Shay) -* Remove support for specifying the documentation formatter using - 's', 'n', 'spec' or 'nested'. (Jon Rowe) - -Enhancements: - -* Add example run time to JSON formatter output. (Karthik Kastury) -* Add more suggested settings to the files generated by - `rspec --init`. (Myron Marston) -* Add `config.alias_example_group_to`, which can be used to define a - new method that defines an example group with the provided metadata. - (Michi Huber) -* Add `xdescribe` and `xcontext` as shortcuts to skip an example group. - (Myron Marston) -* Add `fdescribe` and `fcontext` as shortcuts to focus an example group. - (Myron Marston) -* Don't autorun specs via `#at_exit` by default. `require 'rspec/autorun'` - is only needed when running specs via `ruby`, as it always has been. - Running specs via `rake` or `rspec` are both unaffected. (Ben Hoskings) -* Add `expose_dsl_globally` config option, defaulting to true. When disabled - it will remove the monkey patches rspec-core adds to `main` and `Module` - (e.g. `describe`, `shared_examples_for`, etc). (Jon Rowe) -* Expose RSpec DSL entry point methods (`describe`, - `shared_examples_for`, etc) on the `RSpec` constant. Intended for use - when `expose_dsl_globally` is set to `false`. (Jon Rowe) -* For consistency, expose all example group aliases (including - `context`) on the `RSpec` constant. If `expose_dsl_globally` is set to - `true`, also expose them on `main` and `Module`. Historically, only `describe` - was exposed. (Jon Rowe, Michi Huber) -* Add hook scope `:example` as an alias for `:each`, and `:context` as an alias - for `:all`. (John Feminella) - -Bug Fixes: - -* Fix failure (undefined method `path`) in end-of-run summary - when `raise_errors_for_deprecations!` is configured. (Myron Marston) -* Issue error when attempting to use `-i` or `--I` on command line, - too close to `-I` to be considered short hand for `--init`. (Jon Rowe) -* Prevent adding formatters to an output target if the same - formatter has already been added to that output. (Alex Peattie) -* Allow a matcher-generated example description to be used when - the example is pending. (Myron Marston) -* Ensure the configured `failure_exit_code` is used by the rake - task when there is a failure. (Jon Rowe) -* Restore behaviour whereby system exclusion filters take priority over working - directory (was broken in beta1). (Jon Rowe) -* Prevent RSpec mangling file names that have substrings containing `line_number` - or `default_path`. (Matijs van Zuijlen) -* Fix failure line detection so that it handles relative file paths - (which can happen when running specs through `ruby` using `rspec/autorun`). - (Myron Marston, rspec/rspec-core#1829) - -### 3.0.0.beta1 / 2013-11-07 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.1...v3.0.0.beta1) - -Breaking Changes for 3.0.0: - -* Remove explicit support for 1.8.6. (Jon Rowe) -* Remove `RSpec::Core::ExampleGroup#example` and - `RSpec::Core::ExampleGroup#running_example` methods. If you need - access to the example (e.g. to get its metadata), use a block arg - instead. (David Chelimsky) -* Remove `TextMateFormatter`, it has been moved to `rspec-tmbundle`. - (Aaron Kromer) -* Remove RCov integration. (Jon Rowe) -* Remove deprecated support for RSpec 1 constructs (Myron Marston): - * The `Spec` and `Rspec` constants (rather than `RSpec`). - * `Spec::Runner.configure` rather than `RSpec.configure`. - * `Rake::SpecTask` rather than `RSpec::Core::RakeTask`. -* Remove deprecated support for `share_as`. (Myron Marston) -* Remove `--debug` option (and corresponding option on - `RSpec::Core::Configuration`). Instead, use `-r` to - load whichever debugger gem you wish to use (e.g. `ruby-debug`, - `debugger`, or `pry`). (Myron Marston) -* Extract Autotest support to a seperate gem. (Jon Rowe) -* Raise an error when a `let` or `subject` declaration is - accessed in a `before(:all)` or `after(:all)` hook. (Myron Marston) -* Extract `its` support to a separate gem. (Peter Alfvin) -* Disallow use of a shared example group from sibling contexts, making them - fully isolated. 2.14 and 2.99 allowed this but printed a deprecation warning. - (Jon Rowe) -* Remove `RSpec::Core::Configuration#output` and - `RSpec::Core::Configuration#out` aliases of - `RSpec::Core::Configuration#output_stream`. (Myron Marston) -* Remove legacy ordering APIs deprecated in 2.99.0.beta1. (Myron - Marston) - -Enhancements: - -* Replace unmaintained syntax gem with coderay gem. (Xavier Shay) -* Times in profile output are now bold instead of `failure_color`. - (Matthew Boedicker) -* Add `--no-fail-fast` command line option. (Gonzalo Rodríguez-Baltanás Díaz) -* Runner now considers the local system ip address when running under Drb. - (Adrian CB) -* JsonFormatter now includes `--profile` information. (Alex / @MasterLambaster) -* Always treat symbols passed as metadata args as hash - keys with true values. RSpec 2 supported this with the - `treat_symbols_as_metadata_keys_with_true_values` but - now this behavior is always enabled. (Myron Marston) -* Add `--dry-run` option, which prints the formatter output - of your suite without running any examples or hooks. - (Thomas Stratmann, Myron Marston) -* Document the configuration options and default values in the `spec_helper.rb` - file that is generated by RSpec. (Parker Selbert) -* Give generated example group classes a friendly name derived - from the docstring, rather than something like "Nested_2". - (Myron Marston) -* Avoid affecting randomization of user code when shuffling - examples so that users can count on their own seeds - working. (Travis Herrick) -* Ordering is no longer a single global property of the test suite. - Each group can pick an ordering using `:order` metadata. (Andy - Lindeman, Sam Phippen, Myron Marston) -* Allow named custom ordering strategies to be registered, which can - then be used on individual example groups. (Andy Lindeman, Sam - Phippen, Myron Marston) - -Deprecations: - -* `treat_symbols_as_metadata_keys_with_true_values` is deprecated and no - longer has an affect now that the behavior it enabled is always - enabled. (Myron Marston) - -### 2.99.2 / 2014-08-19 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.1...v2.99.2) - -Enhancements: - -* Improve deprecation warning for RSpec 3 change in `describe ` - behavior. (Jon Rowe, rspec/rspec-core#1667) - -### 2.99.1 / 2014-06-19 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0...v2.99.1) - -Bug Fixes: - -* Add missing deprecation warning for when `RSpec::Core::Runner` is used - multiple times in the same process. In 2.x RSpec's global state was - automatically cleared between runs but in 3.0 you need to call `RSpec.reset` - manually in these situations. (Sam Phippen, rspec/rspec-core#1587) -* Prevent deprecation being accidentally issues when doubles used with `be_` - matchers due to automatically generated descriptions. (Jon Rowe, rspec/rspec-core#1573) -* Load `rspec/core` when loading `rspec/core/rake_task` to ensure we can - issue deprecations correctly. (Jon Rowe, rspec/rspec-core#1612) - -### 2.99.0 / 2014-06-01 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.rc1...v2.99.0) - -Bug Fixes: - -* Fix `BaseTextFormatter` so that it does not re-close a closed output - stream. (Myron Marston) -* Use `RSpec::Configuration#backtrace_exclusion_patterns` rather than the - deprecated `RSpec::Configuration#backtrace_clean_patterns` when mocking - with rr. (David Dollar) - -### 2.99.0.rc1 / 2014-05-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.beta2...v2.99.0.rc1) - -Enhancements: - -* Add `--deprecation-out` CLI option which directs deprecation warnings - to the named file. (Myron Marston) -* Backport support for `skip` in metadata to skip execution of an example. - (Xavier Shay, rspec/rspec-core#1472) -* Add `Pathname` support for setting all output streams. (Aaron Kromer) -* Add `test_unit` and `minitest` expectation frameworks. (Aaron Kromer) - -Deprecations: - -* Deprecate `RSpec::Core::Pending::PendingDeclaredInExample`, use - `SkipDeclaredInExample` instead. (Xavier Shay) -* Issue a deprecation when `described_class` is accessed from within - a nested `describe ` example group, since `described_class` - will return the innermost described class in RSpec 3 rather than the - outermost described class, as it behaved in RSpec 2. (Myron Marston) -* Deprecate `RSpec::Core::FilterManager::DEFAULT_EXCLUSIONS`, - `RSpec::Core::FilterManager::STANDALONE_FILTERS` and use of - `#empty_without_conditional_filters?` on those filters. (Sergey Pchelincev) -* Deprecate `RSpec::Core::Example#options` in favor of - `RSpec::Core::Example#metadata`. (Myron Marston) -* Issue warning when passing a symbol or hash to `describe` or `context` - as the first argument. In RSpec 2.x this would be treated as metadata - but in RSpec 3 it'll be treated as the described object. To continue - having it treated as metadata, pass a description before the symbol or - hash. (Myron Marston) -* Deprecate `RSpec::Core::BaseTextFormatter::VT100_COLORS` and - `RSpec::Core::BaseTextFormatter::VT100_COLOR_CODES` in favour - of `RSpec::Core::BaseTextFormatter::ConsoleCodes::VT100_CODES` and - `RSpec::Core::BaseTextFormatter::ConsoleCodes::VT100_CODE_VALUES`. - (Jon Rowe) -* Deprecate `RSpec::Core::ExampleGroup.display_name` in favor of - `RSpec::Core::ExampleGroup.description`. (Myron Marston) -* Deprecate `RSpec::Core::ExampleGroup.describes` in favor of - `RSpec::Core::ExampleGroup.described_class`. (Myron Marston) -* Deprecate `RSpec::Core::ExampleGroup.alias_example_to` in favor of - `RSpec::Core::Configuration#alias_example_to`. (Myron Marston) -* Deprecate `RSpec::Core::ExampleGroup.alias_it_behaves_like_to` in favor - of `RSpec::Core::Configuration#alias_it_behaves_like_to`. (Myron Marston) -* Deprecate `RSpec::Core::ExampleGroup.focused` in favor of - `RSpec::Core::ExampleGroup.focus`. (Myron Marston) -* Add deprecation warning for `config.filter_run :focused` since - example aliases `fit` and `focus` will no longer include - `:focused` metadata but will continue to include `:focus`. (Myron Marston) -* Deprecate filtering by `:line_number` (e.g. `--line-number` from the - CLI). Use location filtering instead. (Myron Marston) -* Deprecate `--default_path` as an alternative to `--default-path`. (Jon Rowe) -* Deprecate `RSpec::Core::Configuration#warnings` in favor of - `RSpec::Core::Configuration#warnings?`. (Myron Marston) -* Deprecate `share_examples_for` in favor of `shared_examples_for` or - just `shared_examples`. (Myron Marston) -* Deprecate `RSpec::Core::CommandLine` in favor of - `RSpec::Core::Runner`. (Myron Marston) -* Deprecate `#color_enabled`, `#color_enabled=` and `#color?` in favour of - `#color`, `#color=` and `#color_enabled? output`. (Jon Rowe) -* Deprecate `#filename_pattern` in favour of `#pattern`. (Jon Rowe) -* Deprecate `#backtrace_cleaner` in favour of `#backtrace_formatter`. (Jon Rowe) -* Deprecate mutating `RSpec::Configuration#formatters`. (Jon Rowe) -* Deprecate `stdlib` as an available expectation framework in favour of - `test_unit` and `minitest`. (Aaron Kromer) - -Bug Fixes: - -* Issue a warning when you set `config.deprecation_stream` too late for - it to take effect because the reporter has already been setup. (Myron Marston) -* `skip` with a block should not execute the block. (Xavier Shay) - -### 2.99.0.beta2 / 2014-02-17 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.beta1...v2.99.0.beta2) - -Enhancements: - -* Add `is_expected` for one-liners that read well with the - `expect`-based syntax. `is_expected` is simply defined as - `expect(subject)` and can be used in an expression like: - `it { is_expected.to read_well }`. (Myron Marston) -* Backport `skip` from RSpec 3, which acts like `pending` did in RSpec 2 - when not given a block, since the behavior of `pending` is changing in - RSpec 3. (Xavier Shay) - -Deprecations: - -* Deprecate inexact `mock_with` config options. RSpec 3 will only support - the exact symbols `:rspec`, `:mocha`, `:flexmock`, `:rr` or `:nothing` - (or any module that implements the adapter interface). RSpec 2 did - fuzzy matching but this will not be supported going forward. - (Myron Marston) -* Deprecate `show_failures_in_pending_blocks` config option. To achieve - the same behavior as the option enabled, you can use a custom - formatter instead. (Xavier Shay) -* Add a deprecation warning for the fact that the behavior of `pending` - is changing in RSpec 3 -- rather than skipping the example (as it did - in 2.x when no block was provided), it will run the example and mark - it as failed if no exception is raised. Use `skip` instead to preserve - the old behavior. (Xavier Shay) -* Deprecate 's', 'n', 'spec' and 'nested' as aliases for documentation - formatter. (Jon Rowe) -* Deprecate `RSpec::Core::Reporter#abort` in favor of - `RSpec::Core::Reporter#finish`. (Jon Rowe) - -Bug Fixes: - -* Fix failure (undefined method `path`) in end-of-run summary - when `raise_errors_for_deprecations!` is configured. (Myron Marston) -* Fix issue were overridding spec ordering from the command line wasn't - fully recognised interally. (Jon Rowe) - -### 2.99.0.beta1 / 2013-11-07 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.7...v2.99.0.beta1) - -Enhancements - -* Block-based DSL methods that run in the context of an example - (`it`, `before(:each)`, `after(:each)`, `let` and `subject`) - now yield the example as a block argument. (David Chelimsky) -* Warn when the name of more than one example group is submitted to - `include_examples` and it's aliases. (David Chelimsky) -* Add `expose_current_running_example_as` config option for - use during the upgrade process when external gems use the - deprecated `RSpec::Core::ExampleGroup#example` and - `RSpec::Core::ExampleGroup#running_example` methods. (Myron Marston) -* Limit spamminess of deprecation messages. (Bradley Schaefer, Loren Segal) -* Add `config.raise_errors_for_deprecations!` option, which turns - deprecations warnings into errors to surface the full backtrace - of the call site. (Myron Marston) - -Deprecations - -* Deprecate `RSpec::Core::ExampleGroup#example` and - `RSpec::Core::ExampleGroup#running_example` methods. If you need - access to the example (e.g. to get its metadata), use a block argument - instead. (David Chelimsky) -* Deprecate use of `autotest/rspec2` in favour of `rspec-autotest`. (Jon Rowe) -* Deprecate RSpec's built-in debugger support. Use a CLI option like - `-rruby-debug` (for the ruby-debug gem) or `-rdebugger` (for the - debugger gem) instead. (Myron Marston) -* Deprecate `RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values = false`. - RSpec 3 will not support having this option set to `false`. (Myron Marston) -* Deprecate accessing a `let` or `subject` declaration in - a `after(:all)` hook. (Myron Marston, Jon Rowe) -* Deprecate built-in `its` usage in favor of `rspec-its` gem due to planned - removal in RSpec 3. (Peter Alfvin) -* Deprecate `RSpec::Core::PendingExampleFixedError` in favor of - `RSpec::Core::Pending::PendingExampleFixedError`. (Myron Marston) -* Deprecate `RSpec::Core::Configuration#out` and - `RSpec::Core::Configuration#output` in favor of - `RSpec::Core::Configuration#output_stream`. (Myron Marston) -* Deprecate legacy ordering APIs. - * You should use `register_ordering(:global)` instead of these: - * `RSpec::Core::Configuration#order_examples` - * `RSpec::Core::Configuration#order_groups` - * `RSpec::Core::Configuration#order_groups_and_examples` - * These are deprecated with no replacement because in RSpec 3 - ordering is a property of individual example groups rather than - just a global property of the entire test suite: - * `RSpec::Core::Configuration#order` - * `RSpec::Core::Configuration#randomize?` - * `--order default` is deprecated in favor of `--order defined` - (Myron Marston) - -### 2.14.8 / 2014-02-27 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.7...v2.14.8) - -Bug fixes: - -* Fix regression with the `textmateformatter` that prevented backtrace links - from being clickable. (Stefan Daschek) - -### 2.14.7 / 2013-10-29 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.6...v2.14.7) - -Bug fixes: - -* Fix regression in 2.14.6 that broke the Fivemat formatter. - It depended upon either - `example.execution_result[:exception].pending_fixed?` (which - was removed in 2.14.6 to fix an issue with frozen error objects) - or `RSpec::Core::PendingExampleFixedError` (which was renamed - to `RSpec::Core::Pending::PendingExampleFixedError` in 2.8. - This fix makes a constant alias for the old error name. - (Myron Marston) - -### 2.14.6 / 2013-10-15 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.5...v2.14.6) - -Bug fixes: - -* Format stringified numbers correctly when mathn library is loaded. - (Jay Hayes) -* Fix an issue that prevented the use of frozen error objects. (Lars - Gierth) - -### 2.14.5 / 2013-08-13 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.4...v2.14.5) - -Bug fixes: - -* Fix a `NoMethodError` that was being raised when there were no shared - examples or contexts declared and `RSpec.world.reset` is invoked. - (thepoho, Jon Rowe, Myron Marston) -* Fix a deprecation warning that was being incorrectly displayed when - `shared_examples` are declared at top level in a `module` scope. - (Jon Rowe) -* Fix after(:all) hooks so consecutive (same context) scopes will run even if - one raises an error. (Jon Rowe, Trejkaz) -* JsonFormatter no longer dies if `dump_profile` isn't defined (Alex / @MasterLambaster, Jon Rowe) - -### 2.14.4 / 2013-07-21 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.3...v2.14.4) - -Bug fixes - -* Fix regression in 2.14: ensure configured requires (via `-r` option) - are loaded before spec files are loaded. This allows the spec files - to programatically change the file pattern (Jon Rowe). -* Autoload `RSpec::Mocks` and `RSpec::Expectations` when referenced if - they are not already loaded (`RSpec::Matches` has been autoloaded - for a while). In the `rspec` gem, we changed it recently to stop - loading `rspec/mocks` and `rspec/expectations` by default, as some - users reported problems where they were intending to use mocha, - not rspec-mocks, but rspec-mocks was loaded and causing a conflict. - rspec-core loads mocks and expectations at the appropriate time, so - it seemed like a safe change -- but caused a problem for some authors - of libraries that integrate with RSpec. This fixes that problem. - (Myron Marston) -* Gracefully handle a command like `rspec --profile path/to/spec.rb`: - the `path/to/spec.rb` arg was being wrongly treated as the `profile` - integer arg, which got cast `0` using `to_i`, causing no profiled - examples to be printed. (Jon Rowe) - -### 2.14.3 / 2013-07-13 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.2...v2.14.3) - -Bug fixes - -* Fix deprecation notices issued from `RSpec::Core::RakeTask` so - that they work properly when all of rspec-core is not loaded. - (This was a regression in 2.14) (Jon Rowe) - -### 2.14.2 / 2013-07-09 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.1...v2.14.2) - -Bug fixes - -* Fix regression caused by 2.14.1 release: formatters that - report that they `respond_to?` a notification, but had - no corresponding method would raise an error when registered. - The new fix is to just implement `start` on the deprecation - formatter to fix the original JRuby/ruby-debug issue. - (Jon Rowe) - -### 2.14.1 / 2013-07-08 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.0...v2.14.1) - -Bug fixes - -* Address deprecation formatter failure when using `ruby-debug` on - JRuby: fix `RSpec::Core::Reporter` to not send a notification - when the formatter's implementation of the notification method - comes from `Kernel` (Alex Portnov, Jon Rowe). - -### 2.14.0 / 2013-07-06 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.0.rc1...v2.14.0) - -Enhancements - -* Apply focus to examples defined with `fit` (equivalent of - `it "description", focus: true`) (Michael de Silva) - -Bug fix - -* Ensure methods defined by `let` take precedence over others - when there is a name collision (e.g. from an included module). - (Jon Rowe, Andy Lindeman and Myron Marston) - -### 2.14.0.rc1 / 2013-05-27 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.13.1...v2.14.0.rc1) - -Enhancements - -* Improved Windows detection inside Git Bash, for better `--color` handling. -* Add profiling of the slowest example groups to `--profile` option. - The output is sorted by the slowest average example groups. -* Don't show slow examples if there's a failure and both `--fail-fast` - and `--profile` options are used (Paweł Gościcki). -* Rather than always adding `spec` to the load path, add the configured - `--default-path` to the load path (which defaults to `spec`). This - better supports folks who choose to put their specs in a different - directory (John Feminella). -* Add some logic to test time duration precision. Make it a - function of time, dropping precision as the time increases. (Aaron Kromer) -* Add new `backtrace_inclusion_patterns` config option. Backtrace lines - that match one of these patterns will _always_ be included in the - backtrace, even if they match an exclusion pattern, too (Sam Phippen). -* Support ERB trim mode using the `-` when parsing `.rspec` as ERB - (Gabor Garami). -* Give a better error message when let and subject are called without a block. - (Sam Phippen). -* List the precedence of `.rspec-local` in the configuration documentation - (Sam Phippen) -* Support `{a,b}` shell expansion syntax in `--pattern` option - (Konstantin Haase). -* Add cucumber documentation for --require command line option - (Bradley Schaefer) -* Expose configuration options via config: - * `config.libs` returns the libs configured to be added onto the load path - * `full_backtrace?` returns the state of the backtrace cleaner - * `debug?` returns true when the debugger is loaded - * `line_numbers` returns the line numbers we are filtering by (if any) - * `full_description` returns the RegExp used to filter descriptions - (Jon Rowe) -* Add setters for RSpec.world and RSpec.configuration (Alex Soulim) -* Configure ruby's warning behaviour with `--warnings` (Jon Rowe) -* Fix an obscure issue on old versions of `1.8.7` where `Time.dup` wouldn't - allow access to `Time.now` (Jon Rowe) -* Make `shared_examples_for` context aware, so that keys may be safely reused - in multiple contexts without colliding. (Jon Rowe) -* Add a configurable `deprecation_stream` (Jon Rowe) -* Publish deprecations through a formatter (David Chelimsky) - -Bug fixes - -* Make JSON formatter behave the same when it comes to `--profile` as - the text formatter (Paweł Gościcki). -* Fix named subjects so that if an inner group defines a method that - overrides the named method, `subject` still retains the originally - declared value (Myron Marston). -* Fix random ordering so that it does not cause `rand` in examples in - nested sibling contexts to return the same value (Max Shytikov). -* Use the new `backtrace_inclusion_patterns` config option to ensure - that folks who develop code in a directory matching one of the default - exclusion patterns (e.g. `gems`) still get the normal backtrace - filtering (Sam Phippen). -* Fix ordering of `before` hooks so that `before` hooks declared in - `RSpec.configure` run before `before` hooks declared in a shared - context (Michi Huber and Tejas Dinkar). -* Fix `Example#full_description` so that it gets filled in by the last - matcher description (as `Example#description` already did) when no - doc string has been provided (David Chelimsky). -* Fix the memoized methods (`let` and `subject`) leaking `define_method` - as a `public` method. (Thomas Holmes and Jon Rowe) (rspec/rspec-core#873) -* Fix warnings coming from the test suite. (Pete Higgins) - -Deprecations - -* Deprecate `Configuration#backtrace_clean_patterns` in favor of - `Configuration#backtrace_exclusion_patterns` for greater consistency - and symmetry with new `backtrace_inclusion_patterns` config option - (Sam Phippen). -* Deprecate `Configuration#requires=` in favor of using ruby's - `require`. Requires specified by the command line can still be - accessed by the `Configuration#require` reader. (Bradley Schaefer) -* Deprecate calling `SharedExampleGroups` defined across sibling contexts - (Jon Rowe) - -### 2.13.1 / 2013-03-12 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.13.0...v2.13.1) - -Bug fixes - -* Use hook classes as proxies rather than extending hook blocks to support - lambdas for before/after/around hooks. (David Chelimsky) -* Fix regression in 2.13.0 that caused confusing behavior when overriding - a named subject with an unnamed subject in an inner group and then - referencing the outer group subject's name. The fix for this required - us to disallow using `super` in a named subject (which is confusing, - anyway -- named subjects create 2 methods, so which method on the - parent example group are you `super`ing to?) but `super` in an unnamed - subject continues to work (Myron Marston). -* Do not allow a referenced `let` or `subject` in `before(:all)` to cause - other `let` declarations to leak across examples (Myron Marston). -* Work around odd ruby 1.9 bug with `String#match` that was triggered - by passing it a regex from a `let` declaration. For more info, see - http://bugs.ruby-lang.org/issues/8059 (Aaron Kromer). -* Add missing `require 'set'` to `base_text_formatter.rb` (Tom - Anderson). - -Deprecations - -* Deprecate accessing `let` or `subject` declarations in `before(:all)`. - These were not intended to be called in a `before(:all)` hook, as - they exist to define state that is reset between each example, while - `before(:all)` exists to define state that is shared across examples - in an example group (Myron Marston). - -### 2.13.0 / 2013-02-23 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.2...v2.13.0) - -Enhancements - -* Allow `--profile` option to take a count argument that - determines the number of slow examples to dump - (Greggory Rothmeier). -* Add `subject!` that is the analog to `let!`. It defines an - explicit subject and sets a `before` hook that will invoke - the subject (Zubin Henner). -* Fix `let` and `subject` declaration so that `super` - and `return` can be used in them, just like in a normal - method. (Myron Marston) -* Allow output colors to be configured individually. - (Charlie Maffitt) -* Always dump slow examples when `--profile` option is given, - even when an example failed (Myron Marston). - -Bug fixes - -* Don't blow up when dumping error output for instances - of anonymous error classes (Myron Marston). -* Fix default backtrace filters so lines from projects - containing "gems" in the name are not filtered, but - lines from installed gems still are (Myron Marston). -* Fix autotest command so that is uses double quotes - rather than single quotes for windows compatibility - (Jonas Tingeborn). -* Fix `its` so that uses of `subject` in a `before` or `let` - declaration in the parent group continue to reference the - parent group's subject. (Olek Janiszewski) - -### 2.12.2 / 2012-12-13 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.1...v2.12.2) - -Bug fixes - -* Fix `RSpec::Core::RakeTask` so that it is compatible with rake 0.8.7 - on ruby 1.8.7. We had accidentally broke it in the 2.12 release - (Myron Marston). -* Fix `RSpec::Core::RakeTask` so it is tolerant of the `Rspec` constant - for backwards compatibility (Patrick Van Stee) - -### 2.12.1 / 2012-12-01 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.0...v2.12.1) - -Bug fixes - -* Specs are run even if another at\_exit hook calls `exit`. This allows - Test::Unit and RSpec to run together. (Suraj N. Kurapati) -* Fix full doc string concatenation so that it handles the case of a - method string (e.g. "#foo") being nested under a context string - (e.g. "when it is tuesday"), so that we get "when it is tuesday #foo" - rather than "when it is tuesday#foo". (Myron Marston) -* Restore public API I unintentionally broke in 2.12.0: - `RSpec::Core::Formatters::BaseFormatter#format_backtrce(backtrace, example)` - (Myron Marston). - -### 2.12.0 / 2012-11-12 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.11.1...v2.12.0) - -Enhancements - -* Add support for custom ordering strategies for groups and examples. - (Myron Marston) -* JSON Formatter (Alex Chaffee) -* Refactor rake task internals (Sam Phippen) -* Refactor HtmlFormatter (Pete Hodgson) -* Autotest supports a path to Ruby that contains spaces (dsisnero) -* Provide a helpful warning when a shared example group is redefined. - (Mark Burns). -* `--default_path` can be specified as `--default-line`. `--line_number` can be - specified as `--line-number`. Hyphens are more idiomatic command line argument - separators (Sam Phippen). -* A more useful error message is shown when an invalid command line option is - used (Jordi Polo). -* Add `format_docstrings { |str| }` config option. It can be used to - apply formatting rules to example group and example docstrings. - (Alex Tan) -* Add support for an `.rspec-local` options file. This is intended to - allow individual developers to set options in a git-ignored file that - override the common project options in `.rspec`. (Sam Phippen) -* Support for mocha 0.13.0. (Andy Lindeman) - -Bug fixes - -* Remove override of `ExampleGroup#ancestors`. This is a core ruby method that - RSpec shouldn't override. Instead, define `ExampleGroup#parent_groups`. (Myron - Marston) -* Limit monkey patching of shared example/context declaration methods - (`shared_examples_for`, etc.) to just the objects that need it rather than - every object in the system (Myron Marston). -* Fix Metadata#fetch to support computed values (Sam Goldman). -* Named subject can now be referred to from within subject block in a nested - group (tomykaira). -* Fix `fail_fast` so that it properly exits when an error occurs in a - `before(:all) hook` (Bradley Schaefer). -* Make the order spec files are loaded consistent, regardless of the - order of the files returned by the OS or the order passed at - the command line (Jo Liss and Sam Phippen). -* Ensure instance variables from `before(:all)` are always exposed - from `after(:all)`, even if an error occurs in `before(:all)` - (Sam Phippen). -* `rspec --init` no longer generates an incorrect warning about `--configure` - being deprecated (Sam Phippen). -* Fix pluralization of `1 seconds` (Odin Dutton) -* Fix ANSICON url (Jarmo Pertman) -* Use dup of Time so reporting isn't clobbered by examples that modify Time - without properly restoring it. (David Chelimsky) - -Deprecations - -* `share_as` is no longer needed. `shared_context` and/or - `RSpec::SharedContext` provide better mechanisms (Sam Phippen). -* Deprecate `RSpec.configuration` with a block (use `RSpec.configure`). - - -### 2.11.1 / 2012-07-18 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.11.0...v2.11.1) - -Bug fixes - -* Fix the way we autoload RSpec::Matchers so that custom matchers can be - defined before rspec-core has been configured to definitely use - rspec-expectations. (Myron Marston) -* Fix typo in --help message printed for -e option. (Jo Liss) -* Fix ruby warnings. (Myron Marston) -* Ignore mock expectation failures when the example has already failed. - Mock expectation failures have always been ignored in this situation, - but due to my changes in 27059bf1 it was printing a confusing message. - (Myron Marston). - -### 2.11.0 / 2012-07-07 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.10.1...v2.11.0) - -Enhancements - -* Support multiple `--example` options. (Daniel Doubrovkine @dblock) -* Named subject e.g. `subject(:article) { Article.new }` - * see [http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/](http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/) - for background. - * thanks to Bradley Schaefer for suggesting it and Avdi Grimm for almost - suggesting it. -* `config.mock_with` and `config.expect_with` yield custom config object to a - block if given - * aids decoupling from rspec-core's configuation -* `include_context` and `include_examples` support a block, which gets eval'd - in the current context (vs the nested context generated by `it_behaves_like`). -* Add `config.order = 'random'` to the `spec_helper.rb` generated by `rspec - --init`. -* Delay the loading of DRb (Myron Marston). -* Limit monkey patching of `describe` onto just the objects that need it rather - than every object in the system (Myron Marston). - -Bug fixes - -* Support alternative path separators. For example, on Windows, you can now do - this: `rspec spec\subdir`. (Jarmo Pertman @jarmo) -* When an example raises an error and an after or around hook does as - well, print out the hook error. Previously, the error was silenced and - the user got no feedback about what happened. (Myron Marston) -* `--require` and `-I` are merged among different configuration sources (Andy - Lindeman) -* Delegate to mocha methods instead of aliasing them in mocha adapter. - -### 2.10.1 / 2012-05-19 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.10.0...v2.10.1) - -Bug fixes - -* `RSpec.reset` properly reinits configuration and world -* Call `to_s` before `split` on exception messages that might not always be - Strings (slyphon) - -### 2.10.0 / 2012-05-03 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.9.0...v2.10.0) - -Enhancements - -* Add `prepend_before` and `append_after` hooks (preethiramdev) - * intended for extension libs - * restores rspec-1 behavior -* Reporting of profiled examples (moro) - * Report the total amount of time taken for the top slowest examples. - * Report what percentage the slowest examples took from the total runtime. - -Bug fixes - -* Properly parse `SPEC_OPTS` options. -* `example.description` returns the location of the example if there is no - explicit description or matcher-generated description. -* RDoc fixes (Grzegorz Świrski) -* Do not modify example ancestry when dumping errors (Michael Grosser) - -### 2.9.0 / 2012-03-17 -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0...v2.9.0) - -Enhancements - -* Support for "X minutes X seconds" spec run duration in formatter. (uzzz) -* Strip whitespace from group and example names in doc formatter. -* Removed spork-0.9 shim. If you're using spork-0.8.x, you'll need to upgrade - to 0.9.0. - -Bug fixes - -* Restore `--full_backtrace` option -* Ensure that values passed to `config.filter_run` are respected when running - over DRb (using spork). -* Ensure shared example groups are reset after a run (as example groups are). -* Remove `rescue false` from calls to filters represented as Procs -* Ensure `described_class` gets the closest constant (pyromaniac) -* In "autorun", don't run the specs in the `at_exit` hook if there was an - exception (most likely due to a SyntaxError). (sunaku) -* Don't extend groups with modules already used to extend ancestor groups. -* `its` correctly memoizes nil or false values (Yamada Masaki) - -### 2.8.0 / 2012-01-04 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0.rc2...v2.8.0) - -Bug fixes - -* For metadata filtering, restore passing the entire array to the proc, rather - than each item in the array (weidenfreak) -* Ensure each spec file is loaded only once - * Fixes a bug that caused all the examples in a file to be run when - referenced twice with line numbers in a command, e.g. - * `rspec path/to/file:37 path/to/file:42` - -### 2.8.0.rc2 / 2011-12-19 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0.rc1...v2.8.0.rc2) - -Enhancments - -* new `--init` command (Peter Schröder) - * generates `spec/spec_helper.rb` - * deletes obsolete files (on confirmation) - * merged with and deprecates `--configure` command, which generated - `.rspec` -* use `require_relative` when available (Ian Leitch) -* `include_context` and `include_examples` accept params (Calvin Bascom) -* print the time for every example in the html formatter (Richie Vos) -* several tasty refactoring niblets (Sasha) -* `it "does something", :x => [:foo,'bar',/baz/] (Ivan Neverov) - * supports matching n command line tag values with an example or group - -### 2.8.0.rc1 / 2011-11-06 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.7.1...v2.8.0.rc1) - -Enhancements - -* `--order` (Justin Ko) - * run examples in random order: `--order rand` - * specify the seed: `--order rand:123` -* `--seed SEED` - * equivalent of `--order rand:SEED` -* SharedContext supports `let` (David Chelimsky) -* Filter improvements (David Chelimsky) - * override opposing tags from the command line - * override RSpec.configure tags from the command line - * `--line_number 37` overrides all other filters - * `path/to/file.rb:37` overrides all other filters - * refactor: consolidate filter management in a FilterManger object -* Eliminate Ruby warnings (Matijs van Zuijlen) -* Make reporter.report an API (David Chelimsky) - * supports extension tools like interative_rspec - -Changes - -* change `config.color_enabled` (getter/setter/predicate) to `color` to align - with `--[no]-color` CLI option. - * `color_enabled` is still supported for now, but will likley be deprecated - in a 2.x release so we can remove it in 3.0. - -Bug fixes - -* Make sure the `bar` in `--tag foo:bar` makes it to DRb (Aaron Gibralter) -* Fix bug where full descriptions of groups nested 3 deep were repeated. -* Restore report of time to run to start after files are loaded. - * fixes bug where run times were cumalitive in spork - * fixes compatibility with time-series metrics -* Don't error out when `config.mock_with` or `expect_with` is re-specifying the - current config (Myron Marston) - -* Deprecations - * :alias option on `configuration.add_setting`. Use `:alias_with` on the - original setting declaration instead. - -### 2.7.1 / 2011-10-20 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.7.0...v2.7.1) - -Bug fixes - -* tell autotest the correct place to find the rspec executable - -### 2.7.0 / 2011-10-16 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.4...v2.7.0) - -NOTE: RSpec's release policy dictates that there should not be any backward -incompatible changes in minor releases, but we're making an exception to -release a change to how RSpec interacts with other command line tools. - -As of 2.7.0, you must explicity `require "rspec/autorun"` unless you use the -`rspec` command (which already does this for you). - -Enhancements - -* Add `example.exception` (David Chelimsky) -* `--default_path` command line option (Justin Ko) -* support multiple `--line_number` options (David J. Hamilton) - * also supports `path/to/file.rb:5:9` (runs examples on lines 5 and 9) -* Allow classes/modules to be used as shared example group identifiers (Arthur - Gunn) -* Friendly error message when shared context cannot be found (Sławosz - Sławiński) -* Clear formatters when resetting config (John Bintz) -* Add `xspecify` and xexample as temp-pending methods (David Chelimsky) -* Add `--no-drb` option (Iain Hecker) -* Provide more accurate run time by registering start time before code is - loaded (David Chelimsky) - * reverted in 2.8.0 -* Rake task default pattern finds specs in symlinked dirs (Kelly Felkins) -* Rake task no longer does anything to invoke bundler since Bundler already - handles it for us. Thanks to Andre Arko for the tip. -* Add `--failure-exit-code` option (Chris Griego) - -Bug fixes - -* Include `Rake::DSL` to remove deprecation warnings in Rake > 0.8.7 (Pivotal - Casebook) -* Only eval `let` block once even if it returns `nil` (Adam Meehan) -* Fix `--pattern` option (wasn't being recognized) (David Chelimsky) -* Only implicitly `require "rspec/autorun"` with the `rspec` command (David - Chelimsky) -* Ensure that rspec's `at_exit` defines the exit code (Daniel Doubrovkine) -* Show the correct snippet in the HTML and TextMate formatters (Brian Faherty) - -### 2.6.4 / 2011-06-06 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.3...v2.6.4) - -NOTE: RSpec's release policy dictates that there should not be new -functionality in patch releases, but this minor enhancement slipped in by -accident. As it doesn't add a new API, we decided to leave it in rather than -roll back this release. - -Enhancements - -* Add summary of commands to run individual failed examples. - -Bug fixes - -* Support exclusion filters in DRb. (Yann Lugrin) -* Fix --example escaping when run over DRb. (Elliot Winkler) -* Use standard ANSI codes for color formatting so colors work in a wider set of - color schemes. - -### 2.6.3 / 2011-05-24 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.2...v2.6.3) - -Bug fixes - -* Explicitly convert exit code to integer, avoiding TypeError when return - value of run is IO object proxied by `DRb::DRbObject` (Julian Scheid) -* Clarify behavior of `--example` command line option -* Build using a rubygems-1.6.2 to avoid downstream yaml parsing error - -### 2.6.2 / 2011-05-21 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.1...v2.6.2) - -Bug fixes - -* Warn rather than raise when HOME env var is not defined -* Properly merge command-line exclusions with default :if and :unless (joshcooper) - -### 2.6.1 / 2011-05-19 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.0...v2.6.1) - -Bug fixes - -* Don't extend nil when filters are nil -* `require 'rspec/autorun'` when running rcov. - -### 2.6.0 / 2011-05-12 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.0) - -Enhancements - -* `shared_context` (Damian Nurzynski) - * extend groups matching specific metadata with: - * method definitions - * subject declarations - * let/let! declarations - * etc (anything you can do in a group) -* `its([:key])` works for any subject with #[]. (Peter Jaros) -* `treat_symbols_as_metadata_keys_with_true_values` (Myron Marston) -* Print a deprecation warning when you configure RSpec after defining an - example. All configuration should happen before any examples are defined. - (Myron Marston) -* Pass the exit status of a DRb run to the invoking process. This causes specs - run via DRb to not just return true or false. (Ilkka Laukkanen) -* Refactoring of `ConfigurationOptions#parse_options` (Rodrigo Rosenfeld Rosas) -* Report excluded filters in runner output (tip from andyl) -* Clean up messages for filters/tags. -* Restore --pattern/-P command line option from rspec-1 -* Support false as well as true in config.full_backtrace= (Andreas Tolf - Tolfsen) - -Bug fixes - -* Don't stumble over an exception without a message (Hans Hasselberg) -* Remove non-ascii characters from comments that were choking rcov (Geoffrey - Byers) -* Fixed backtrace so it doesn't include lines from before the autorun at_exit - hook (Myron Marston) -* Include RSpec::Matchers when first example group is defined, rather than just - before running the examples. This works around an obscure bug in ruby 1.9 - that can cause infinite recursion. (Myron Marston) -* Don't send `example_group_[started|finished]` to formatters for empty groups. -* Get specs passing on jruby (Sidu Ponnappa) -* Fix bug where mixing nested groups and outer-level examples gave - unpredictable :line_number behavior (Artur Małecki) -* Regexp.escape the argument to --example (tip from Elliot Winkler) -* Correctly pass/fail pending block with message expectations -* CommandLine returns exit status (0/1) instead of true/false -* Create path to formatter output file if it doesn't exist (marekj). - - -### 2.5.1 / 2011-02-06 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.5.0...v2.5.1) - -NOTE: this release breaks compatibility with rspec/autotest/bundler -integration, but does so in order to greatly simplify it. - -With this release, if you want the generated autotest command to include -'bundle exec', require Autotest's bundler plugin in a .autotest file in the -project's root directory or in your home directory: - - require "autotest/bundler" - -Now you can just type 'autotest' on the command line and it will work as you expect. - -If you don't want 'bundle exec', there is nothing you have to do. - -### 2.5.0 / 2011-02-05 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.4.0...v2.5.0) - -Enhancements - -* Autotest::Rspec2 parses command line args passed to autotest after '--' -* --skip-bundler option for autotest command -* Autotest regexp fixes (Jon Rowe) -* Add filters to html and textmate formatters (Daniel Quimper) -* Explicit passing of block (need for JRuby 1.6) (John Firebaugh) - -Bug fixes - -* fix dom IDs in HTML formatter (Brian Faherty) -* fix bug with --drb + formatters when not running in drb -* include --tag options in drb args (monocle) -* fix regression so now SPEC_OPTS take precedence over CLI options again (Roman - Chernyatchik) -* only call its(:attribute) once (failing example from Brian Dunn) -* fix bizarre bug where rspec would hang after String.alias :to_int :to_i - (Damian Nurzynski) - -Deprecations - -* implicit inclusion of 'bundle exec' when Gemfile present (use autotest's - bundler plugin instead) - -### 2.4.0 / 2011-01-02 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.3.1...v2.4.0) - -Enhancements - -* start the debugger on -d so the stack trace is visible when it stops - (Clifford Heath) -* apply hook filtering to examples as well as groups (Myron Marston) -* support multiple formatters, each with their own output -* show exception classes in failure messages unless they come from RSpec - matchers or message expectations -* before(:all) { pending } sets all examples to pending - -Bug fixes - -* fix bug due to change in behavior of reject in Ruby 1.9.3-dev (Shota - Fukumori) -* fix bug when running in jruby: be explicit about passing block to super (John - Firebaugh) -* rake task doesn't choke on paths with quotes (Janmejay Singh) -* restore --options option from rspec-1 -* require 'ostruct' to fix bug with its([key]) (Kim Burgestrand) -* --configure option generates .rspec file instead of autotest/discover.rb - -### 2.3.1 / 2010-12-16 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.3.0...v2.3.1) - -Bug fixes - -* send debugger warning message to $stdout if RSpec.configuration.error_stream - has not been defined yet. -* HTML Formatter _finally_ properly displays nested groups (Jarmo Pertman) -* eliminate some warnings when running RSpec's own suite (Jarmo Pertman) - -### 2.3.0 / 2010-12-12 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.2.1...v2.3.0) - -Enhancements - -* tell autotest to use "rspec2" if it sees a .rspec file in the project's root - directory - * replaces the need for ./autotest/discover.rb, which will not work with - all versions of ZenTest and/or autotest -* config.expect_with - * :rspec # => rspec/expectations - * :stdlib # => test/unit/assertions - * :rspec, :stdlib # => both - -Bug fixes - -* fix dev Gemfile to work on non-mac-os machines (Lake Denman) -* ensure explicit subject is only eval'd once (Laszlo Bacsi) - -### 2.2.1 / 2010-11-28 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.2.0...v2.2.1) - -Bug fixes - -* alias_method instead of override Kernel#method_missing (John Wilger) -* changed --autotest to --tty in generated command (MIKAMI Yoshiyuki) -* revert change to debugger (had introduced conflict with Rails) - * also restored --debugger/-debug option - -### 2.2.0 / 2010-11-28 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.1.0...v2.2.0) - -Deprecations/changes - -* --debug/-d on command line is deprecated and now has no effect -* win32console is now ignored; Windows users must use ANSICON for color support - (Bosko Ivanisevic) - -Enhancements - -* When developing locally rspec-core now works with the rspec-dev setup or your - local gems -* Raise exception with helpful message when rspec-1 is loaded alongside rspec-2 - (Justin Ko) -* debugger statements _just work_ as long as ruby-debug is installed - * otherwise you get warned, but not fired -* Expose example.metadata in around hooks -* Performance improvments (much faster now) - -Bug fixes - -* Make sure --fail-fast makes it across drb -* Pass -Ilib:spec to rcov - -### 2.1.0 / 2010-11-07 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.1...v2.1.0) - -Enhancments - -* Add skip_bundler option to rake task to tell rake task to ignore the presence - of a Gemfile (jfelchner) -* Add gemfile option to rake task to tell rake task what Gemfile to look for - (defaults to 'Gemfile') -* Allow passing caller trace into Metadata to support extensions (Glenn - Vanderburg) -* Add deprecation warning for Spec::Runner.configure to aid upgrade from - RSpec-1 -* Add deprecated Spec::Rake::SpecTask to aid upgrade from RSpec-1 -* Add 'autospec' command with helpful message to aid upgrade from RSpec-1 -* Add support for filtering with tags on CLI (Lailson Bandeira) -* Add a helpful message about RUBYOPT when require fails in bin/rspec (slyphon) -* Add "-Ilib" to the default rcov options (Tianyi Cui) -* Make the expectation framework configurable (default rspec, of course) - (Justin Ko) -* Add 'pending' to be conditional (Myron Marston) -* Add explicit support for :if and :unless as metadata keys for conditional run - of examples (Myron Marston) -* Add --fail-fast command line option (Jeff Kreeftmeijer) - -Bug fixes - -* Eliminate stack overflow with "subject { self }" -* Require 'rspec/core' in the Raketask (ensures it required when running rcov) - -### 2.0.1 / 2010-10-18 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0...v2.0.1) - -Bug fixes - -* Restore color when using spork + autotest -* Pending examples without docstrings render the correct message (Josep M. - Bach) -* Fixed bug where a failure in a spec file ending in anything but _spec.rb - would fail in a confusing way. -* Support backtrace lines from erb templates in html formatter (Alex Crichton) - -### 2.0.0 / 2010-10-10 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.rc...v2.0.0) - -RSpec-1 compatibility - -* Rake task uses ENV["SPEC"] as file list if present - -Bug fixes - -* Bug Fix: optparse --out foo.txt (Leonardo Bessa) -* Suppress color codes for non-tty output (except autotest) - -### 2.0.0.rc / 2010-10-05 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.beta.22...v2.0.0.rc) - -Enhancements - -* implicitly require unknown formatters so you don't have to require the file - explicitly on the command line (Michael Grosser) -* add --out/-o option to assign output target -* added fail_fast configuration option to abort on first failure -* support a Hash subject (its([:key]) { should == value }) (Josep M. Bach) - -Bug fixes - -* Explicitly require rspec version to fix broken rdoc task (Hans de Graaff) -* Ignore backtrace lines that come from other languages, like Java or - Javascript (Charles Lowell) -* Rake task now does what is expected when setting (or not setting) - fail_on_error and verbose -* Fix bug in which before/after(:all) hooks were running on excluded nested - groups (Myron Marston) -* Fix before(:all) error handling so that it fails examples in nested groups, - too (Myron Marston) - -### 2.0.0.beta.22 / 2010-09-12 - -[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.beta.20...v2.0.0.beta.22) - -Enhancements - -* removed at_exit hook -* CTRL-C stops the run (almost) immediately - * first it cleans things up by running the appropriate after(:all) and - after(:suite) hooks - * then it reports on any examples that have already run -* cleaned up rake task - * generate correct task under variety of conditions - * options are more consistent - * deprecated redundant options -* run 'bundle exec autotest' when Gemfile is present -* support ERB in .rspec options files (Justin Ko) -* depend on bundler for development tasks (Myron Marston) -* add example_group_finished to formatters and reporter (Roman Chernyatchik) - -Bug fixes - -* support paths with spaces when using autotest (Andreas Neuhaus) -* fix module_exec with ruby 1.8.6 (Myron Marston) -* remove context method from top-level - * was conflicting with irb, for example -* errors in before(:all) are now reported correctly (Chad Humphries) - -Removals - -* removed -o --options-file command line option - * use ./.rspec and ~/.rspec diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md deleted file mode 100644 index 76dc17d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/LICENSE.md +++ /dev/null @@ -1,26 +0,0 @@ -The MIT License (MIT) -===================== - -* Copyright © 2012 Chad Humphries, David Chelimsky, Myron Marston -* Copyright © 2009 Chad Humphries, David Chelimsky -* Copyright © 2006 David Chelimsky, The RSpec Development Team -* Copyright © 2005 Steven Baker - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md deleted file mode 100644 index 8598146..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/README.md +++ /dev/null @@ -1,389 +0,0 @@ -# rspec-core [![Build Status](https://github.com/rspec/rspec-core/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-core/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-core.svg)](https://codeclimate.com/github/rspec/rspec-core) - -rspec-core provides the structure for writing executable examples of how your -code should behave, and an `rspec` command with tools to constrain which -examples get run and tailor the output. - -## Install - - gem install rspec # for rspec-core, rspec-expectations, rspec-mocks - gem install rspec-core # for rspec-core only - rspec --help - -Want to run against the `main` branch? You'll need to include the dependent -RSpec repos as well. Add the following to your `Gemfile`: - -```ruby -%w[rspec rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| - gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' -end -``` - -## Basic Structure - -RSpec uses the words "describe" and "it" so we can express concepts like a conversation: - - "Describe an order." - "It sums the prices of its line items." - -```ruby -RSpec.describe Order do - it "sums the prices of its line items" do - order = Order.new - - order.add_entry(LineItem.new(:item => Item.new( - :price => Money.new(1.11, :USD) - ))) - order.add_entry(LineItem.new(:item => Item.new( - :price => Money.new(2.22, :USD), - :quantity => 2 - ))) - - expect(order.total).to eq(Money.new(5.55, :USD)) - end -end -``` - -The `describe` method creates an [ExampleGroup](http://rubydoc.info/gems/rspec-core/RSpec/Core/ExampleGroup). Within the -block passed to `describe` you can declare examples using the `it` method. - -Under the hood, an example group is a class in which the block passed to -`describe` is evaluated. The blocks passed to `it` are evaluated in the -context of an _instance_ of that class. - -## Nested Groups - -You can also declare nested groups using the `describe` or `context` -methods: - -```ruby -RSpec.describe Order do - context "with no items" do - it "behaves one way" do - # ... - end - end - - context "with one item" do - it "behaves another way" do - # ... - end - end -end -``` - -Nested groups are subclasses of the outer example group class, providing -the inheritance semantics you'd want for free. - -## Aliases - -You can declare example groups using either `describe` or `context`. -For a top level example group, `describe` and `context` are available -off of `RSpec`. For backwards compatibility, they are also available -off of the `main` object and `Module` unless you disable monkey -patching. - -You can declare examples within a group using any of `it`, `specify`, or -`example`. - -## Shared Examples and Contexts - -Declare a shared example group using `shared_examples`, and then include it -in any group using `include_examples`. - -```ruby -RSpec.shared_examples "collections" do |collection_class| - it "is empty when first created" do - expect(collection_class.new).to be_empty - end -end - -RSpec.describe Array do - include_examples "collections", Array -end - -RSpec.describe Hash do - include_examples "collections", Hash -end -``` - -Nearly anything that can be declared within an example group can be declared -within a shared example group. This includes `before`, `after`, and `around` -hooks, `let` declarations, and nested groups/contexts. - -You can also use the names `shared_context` and `include_context`. These are -pretty much the same as `shared_examples` and `include_examples`, providing -more accurate naming when you share hooks, `let` declarations, helper methods, -etc, but no examples. - -If you want to reuse shared examples or contexts across your RSpec suite you can -define them in a stand alone _*.rb_ files (_spec/support/shared_examples/definition.rb_ -for example). But you will have to manually `require` them (there is no autoloading of -_spec/support/_ directory unless you set it up yourself). - -## Metadata - -rspec-core stores a metadata hash with every example and group, which -contains their descriptions, the locations at which they were -declared, etc, etc. This hash powers many of rspec-core's features, -including output formatters (which access descriptions and locations), -and filtering before and after hooks. - -Although you probably won't ever need this unless you are writing an -extension, you can access it from an example like this: - -```ruby -it "does something" do |example| - expect(example.metadata[:description]).to eq("does something") -end -``` - -### `described_class` - -When a class is passed to `describe`, you can access it from an example -using the `described_class` method, which is a wrapper for -`example.metadata[:described_class]`. - -```ruby -RSpec.describe Widget do - example do - expect(described_class).to equal(Widget) - end -end -``` - -This is useful in extensions or shared example groups in which the specific -class is unknown. Taking the collections shared example group from above, we can -clean it up a bit using `described_class`: - -```ruby -RSpec.shared_examples "collections" do - it "is empty when first created" do - expect(described_class.new).to be_empty - end -end - -RSpec.describe Array do - include_examples "collections" -end - -RSpec.describe Hash do - include_examples "collections" -end -``` - -## A Word on Scope - -RSpec has two scopes: - -* **Example Group**: Example groups are defined by a `describe` or - `context` block, which is eagerly evaluated when the spec file is - loaded. The block is evaluated in the context of a subclass of - `RSpec::Core::ExampleGroup`, or a subclass of the parent example group - when you're nesting them. -* **Example**: Examples -- typically defined by an `it` block -- and any other - blocks with per-example semantics -- such as a `before(:example)` hook -- are - evaluated in the context of - an _instance_ of the example group class to which the example belongs. - Examples are _not_ executed when the spec file is loaded; instead, - RSpec waits to run any examples until all spec files have been loaded, - at which point it can apply filtering, randomization, etc. - -To make this more concrete, consider this code snippet: - -``` ruby -RSpec.describe "Using an array as a stack" do - def build_stack - [] - end - - before(:example) do - @stack = build_stack - end - - it 'is initially empty' do - expect(@stack).to be_empty - end - - context "after an item has been pushed" do - before(:example) do - @stack.push :item - end - - it 'allows the pushed item to be popped' do - expect(@stack.pop).to eq(:item) - end - end -end -``` - -Under the covers, this is (roughly) equivalent to: - -``` ruby -class UsingAnArrayAsAStack < RSpec::Core::ExampleGroup - def build_stack - [] - end - - def before_example_1 - @stack = build_stack - end - - def it_is_initially_empty - expect(@stack).to be_empty - end - - class AfterAnItemHasBeenPushed < self - def before_example_2 - @stack.push :item - end - - def it_allows_the_pushed_item_to_be_popped - expect(@stack.pop).to eq(:item) - end - end -end -``` - -To run these examples, RSpec would (roughly) do the following: - -``` ruby -example_1 = UsingAnArrayAsAStack.new -example_1.before_example_1 -example_1.it_is_initially_empty - -example_2 = UsingAnArrayAsAStack::AfterAnItemHasBeenPushed.new -example_2.before_example_1 -example_2.before_example_2 -example_2.it_allows_the_pushed_item_to_be_popped -``` - -## The `rspec` Command - -When you install the rspec-core gem, it installs the `rspec` executable, -which you'll use to run rspec. The `rspec` command comes with many useful -options. -Run `rspec --help` to see the complete list. - -## Store Command Line Options `.rspec` - -You can store command line options in a `.rspec` file in the project's root -directory, and the `rspec` command will read them as though you typed them on -the command line. - -## Get Started - -Start with a simple example of behavior you expect from your system. Do -this before you write any implementation code: - -```ruby -# in spec/calculator_spec.rb -RSpec.describe Calculator do - describe '#add' do - it 'returns the sum of its arguments' do - expect(Calculator.new.add(1, 2)).to eq(3) - end - end -end -``` - -Run this with the rspec command, and watch it fail: - -``` -$ rspec spec/calculator_spec.rb -./spec/calculator_spec.rb:1: uninitialized constant Calculator -``` - -Address the failure by defining a skeleton of the `Calculator` class: - -```ruby -# in lib/calculator.rb -class Calculator - def add(a, b) - end -end -``` - -Be sure to require the implementation file in the spec: - -```ruby -# in spec/calculator_spec.rb -# - RSpec adds ./lib to the $LOAD_PATH -require "calculator" -``` - -Now run the spec again, and watch the expectation fail: - -``` -$ rspec spec/calculator_spec.rb -F - -Failures: - - 1) Calculator#add returns the sum of its arguments - Failure/Error: expect(Calculator.new.add(1, 2)).to eq(3) - - expected: 3 - got: nil - - (compared using ==) - # ./spec/calculator_spec.rb:6:in `block (3 levels) in ' - -Finished in 0.00131 seconds (files took 0.10968 seconds to load) -1 example, 1 failure - -Failed examples: - -rspec ./spec/calculator_spec.rb:5 # Calculator#add returns the sum of its arguments -``` - -Implement the simplest solution, by changing the definition of `Calculator#add` to: - -```ruby -def add(a, b) - a + b -end -``` - -Now run the spec again, and watch it pass: - -``` -$ rspec spec/calculator_spec.rb -. - -Finished in 0.000315 seconds -1 example, 0 failures -``` - -Use the `documentation` formatter to see the resulting spec: - -``` -$ rspec spec/calculator_spec.rb --format doc -Calculator - #add - returns the sum of its arguments - -Finished in 0.000379 seconds -1 example, 0 failures -``` - -## Contributing - -Once you've set up the environment, you'll need to cd into the working -directory of whichever repo you want to work in. From there you can run the -specs and cucumber features, and make patches. - -NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You -can treat each RSpec repo as an independent project. - -* [Build details](BUILD_DETAIL.md) -* [Code of Conduct](CODE_OF_CONDUCT.md) -* [Detailed contributing guide](CONTRIBUTING.md) -* [Development setup guide](DEVELOPMENT.md) - -## Also see - -* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) -* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations) -* [https://github.com/rspec/rspec-mocks](https://github.com/rspec/rspec-mocks) -* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec deleted file mode 100755 index 7ee5fd8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/exe/rspec +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby - -require 'rspec/core' -RSpec::Core::Runner.invoke diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb deleted file mode 100644 index 3080cfd..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/autorun.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'rspec/core' -# Ensure the default config is loaded -RSpec::Core::Runner.autorun diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb deleted file mode 100644 index ad9553c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core.rb +++ /dev/null @@ -1,212 +0,0 @@ -# rubocop:disable Style/GlobalVars -$_rspec_core_load_started_at = Time.now -# rubocop:enable Style/GlobalVars - -require "rspec/support" -RSpec::Support.require_rspec_support "caller_filter" - -RSpec::Support.define_optimized_require_for_rspec(:core) { |f| require_relative f } - -%w[ - version - warnings - - set - flat_map - filter_manager - dsl - notifications - reporter - - hooks - memoized_helpers - metadata - metadata_filter - pending - formatters - ordering - - world - configuration - option_parser - configuration_options - runner - invocations - example - shared_example_group - example_group -].each { |name| RSpec::Support.require_rspec_core name } - -# Namespace for all core RSpec code. -module RSpec - autoload :SharedContext, 'rspec/core/shared_context' - - extend RSpec::Core::Warnings - - class << self - # Setters for shared global objects - # @api private - attr_writer :configuration, :world - end - - # Used to ensure examples get reloaded and user configuration gets reset to - # defaults between multiple runs in the same process. - # - # Users must invoke this if they want to have the configuration reset when - # they use the runner multiple times within the same process. Users must deal - # themselves with re-configuration of RSpec before run. - def self.reset - RSpec::ExampleGroups.remove_all_constants - @world = nil - @configuration = nil - end - - # Used to ensure examples get reloaded between multiple runs in the same - # process and ensures user configuration is persisted. - # - # Users must invoke this if they want to clear all examples but preserve - # current configuration when they use the runner multiple times within the - # same process. - def self.clear_examples - world.reset - configuration.reset_reporter - configuration.start_time = ::RSpec::Core::Time.now - configuration.reset_filters - end - - # Returns the global [Configuration](RSpec/Core/Configuration) object. While - # you _can_ use this method to access the configuration, the more common - # convention is to use [RSpec.configure](RSpec#configure-class_method). - # - # @example - # RSpec.configuration.drb_port = 1234 - # @see RSpec.configure - # @see Core::Configuration - def self.configuration - @configuration ||= RSpec::Core::Configuration.new - end - - # Yields the global configuration to a block. - # @yield [Configuration] global configuration - # - # @example - # RSpec.configure do |config| - # config.add_formatter 'documentation' - # end - # @see Core::Configuration - def self.configure - yield configuration if block_given? - end - - # The example being executed. - # - # The primary audience for this method is library authors who need access - # to the example currently being executed and also want to support all - # versions of RSpec 2 and 3. - # - # @example - # - # RSpec.configure do |c| - # # context.example is deprecated, but RSpec.current_example is not - # # available until RSpec 3.0. - # fetch_current_example = RSpec.respond_to?(:current_example) ? - # proc { RSpec.current_example } : proc { |context| context.example } - # - # c.before(:example) do - # example = fetch_current_example.call(self) - # - # # ... - # end - # end - # - def self.current_example - RSpec::Support.thread_local_data[:current_example] - end - - # Set the current example being executed. - # @api private - def self.current_example=(example) - RSpec::Support.thread_local_data[:current_example] = example - end - - # Set the current scope rspec is executing in - # @api private - def self.current_scope=(scope) - RSpec::Support.thread_local_data[:current_scope] = scope - end - RSpec.current_scope = :suite - - # Get the current RSpec execution scope - # - # Returns (in order of lifecycle): - # * `:suite` as an initial value, this is outside of the test lifecycle. - # * `:before_suite_hook` during `before(:suite)` hooks. - # * `:before_context_hook` during `before(:context)` hooks. - # * `:before_example_hook` during `before(:example)` hooks and `around(:example)` before `example.run`. - # * `:example` within the example run. - # * `:after_example_hook` during `after(:example)` hooks and `around(:example)` after `example.run`. - # * `:after_context_hook` during `after(:context)` hooks. - # * `:after_suite_hook` during `after(:suite)` hooks. - # * `:suite` as a final value, again this is outside of the test lifecycle. - # - # Reminder, `:context` hooks have `:all` alias and `:example` hooks have `:each` alias. - # @return [Symbol] - def self.current_scope - RSpec::Support.thread_local_data[:current_scope] - end - - # @private - # Internal container for global non-configuration data. - def self.world - @world ||= RSpec::Core::World.new - end - - # Namespace for the rspec-core code. - module Core - autoload :ExampleStatusPersister, "rspec/core/example_status_persister" - autoload :Profiler, "rspec/core/profiler" - autoload :DidYouMean, "rspec/core/did_you_mean" - - # @private - # This avoids issues with reporting time caused by examples that - # change the value/meaning of Time.now without properly restoring - # it. - class Time - class << self - define_method(:now, &::Time.method(:now)) - end - end - - # @private path to executable file. - def self.path_to_executable - @path_to_executable ||= File.expand_path('../../../exe/rspec', __FILE__) - end - end - - # @private - MODULES_TO_AUTOLOAD = { - :Matchers => "rspec/expectations", - :Expectations => "rspec/expectations", - :Mocks => "rspec/mocks" - } - - # @private - def self.const_missing(name) - # Load rspec-expectations when RSpec::Matchers is referenced. This allows - # people to define custom matchers (using `RSpec::Matchers.define`) before - # rspec-core has loaded rspec-expectations (since it delays the loading of - # it to allow users to configure a different assertion/expectation - # framework). `autoload` can't be used since it works with ruby's built-in - # require (e.g. for files that are available relative to a load path dir), - # but not with rubygems' extended require. - # - # As of rspec 2.14.1, we no longer require `rspec/mocks` and - # `rspec/expectations` when `rspec` is required, so we want - # to make them available as an autoload. - require MODULES_TO_AUTOLOAD.fetch(name) { return super } - ::RSpec.const_get(name) - end - - Core::DSL.expose_globally! - Core::SharedExampleGroup::TopLevelDSL.expose_globally! -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb deleted file mode 100644 index e0bee52..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/backtrace_formatter.rb +++ /dev/null @@ -1,65 +0,0 @@ -module RSpec - module Core - # @private - class BacktraceFormatter - # @private - attr_accessor :exclusion_patterns, :inclusion_patterns - - def initialize - @full_backtrace = false - - patterns = %w[ /lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle: ] - patterns << "org/jruby/" if RUBY_PLATFORM == 'java' - patterns.map! { |s| Regexp.new(s.gsub("/", File::SEPARATOR)) } - - @exclusion_patterns = [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *patterns)] - @inclusion_patterns = [] - - return unless matches?(@exclusion_patterns, File.join(Dir.getwd, "lib", "foo.rb:13")) - inclusion_patterns << Regexp.new(Dir.getwd) - end - - attr_writer :full_backtrace - - def full_backtrace? - @full_backtrace || exclusion_patterns.empty? - end - - def filter_gem(gem_name) - sep = File::SEPARATOR - exclusion_patterns << /#{sep}#{gem_name}(-[^#{sep}]+)?#{sep}/ - end - - def format_backtrace(backtrace, options={}) - return [] unless backtrace - return backtrace if options[:full_backtrace] || backtrace.empty? - - backtrace.map { |l| backtrace_line(l) }.compact. - tap do |filtered| - if filtered.empty? - filtered.concat backtrace - filtered << "" - filtered << " Showing full backtrace because every line was filtered out." - filtered << " See docs for RSpec::Configuration#backtrace_exclusion_patterns and" - filtered << " RSpec::Configuration#backtrace_inclusion_patterns for more information." - end - end - end - - def backtrace_line(line) - Metadata.relative_path(line) unless exclude?(line) - end - - def exclude?(line) - return false if @full_backtrace - matches?(exclusion_patterns, line) && !matches?(inclusion_patterns, line) - end - - private - - def matches?(patterns, line) - patterns.any? { |p| line =~ p } - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb deleted file mode 100644 index c4d304b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/coordinator.rb +++ /dev/null @@ -1,62 +0,0 @@ -RSpec::Support.require_rspec_core "bisect/shell_command" -RSpec::Support.require_rspec_core "bisect/example_minimizer" -RSpec::Support.require_rspec_core "bisect/utilities" -RSpec::Support.require_rspec_core "formatters/bisect_progress_formatter" - -module RSpec - module Core - module Bisect - # The main entry point into the bisect logic. Coordinates among: - # - Bisect::ShellCommand: Generates shell commands to run spec subsets - # - Bisect::ExampleMinimizer: Contains the core bisect logic. - # - A bisect runner: runs a set of examples and returns the results. - # - A bisect formatter: provides progress updates to the user. - # @private - class Coordinator - def self.bisect_with(spec_runner, original_cli_args, formatter) - new(spec_runner, original_cli_args, formatter).bisect - end - - def initialize(spec_runner, original_cli_args, formatter) - @spec_runner = spec_runner - @shell_command = ShellCommand.new(original_cli_args) - @notifier = Bisect::Notifier.new(formatter) - end - - def bisect - repro = start_bisect_runner do |runner| - minimizer = ExampleMinimizer.new(@shell_command, runner, @notifier) - - gracefully_abort_on_sigint(minimizer) - minimizer.find_minimal_repro - minimizer.repro_command_for_currently_needed_ids - end - - @notifier.publish(:bisect_repro_command, :repro => repro) - - true - rescue BisectFailedError => e - @notifier.publish(:bisect_failed, :failure_explanation => e.message) - false - ensure - @notifier.publish(:close) - end - - private - - def start_bisect_runner(&block) - klass = @spec_runner.configuration.bisect_runner_class - klass.start(@shell_command, @spec_runner, &block) - end - - def gracefully_abort_on_sigint(minimizer) - trap('INT') do - repro = minimizer.repro_command_for_currently_needed_ids - @notifier.publish(:bisect_aborted, :repro => repro) - exit(1) - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb deleted file mode 100644 index e53ca82..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/example_minimizer.rb +++ /dev/null @@ -1,173 +0,0 @@ -RSpec::Support.require_rspec_core "bisect/utilities" - -module RSpec - module Core - module Bisect - # @private - # Contains the core bisect logic. Searches for examples we can ignore by - # repeatedly running different subsets of the suite. - class ExampleMinimizer - attr_reader :shell_command, :runner, :all_example_ids, :failed_example_ids - attr_accessor :remaining_ids - - def initialize(shell_command, runner, notifier) - @shell_command = shell_command - @runner = runner - @notifier = notifier - end - - def find_minimal_repro - prep - - _, duration = track_duration do - bisect(non_failing_example_ids) - end - - notify(:bisect_complete, :duration => duration, - :original_non_failing_count => non_failing_example_ids.size, - :remaining_count => remaining_ids.size) - - remaining_ids + failed_example_ids - end - - def bisect(candidate_ids) - notify(:bisect_dependency_check_started) - if get_expected_failures_for?([]) - notify(:bisect_dependency_check_failed) - self.remaining_ids = [] - return - end - notify(:bisect_dependency_check_passed) - - bisect_over(candidate_ids) - end - - def bisect_over(candidate_ids) - return if candidate_ids.one? - - notify( - :bisect_round_started, - :candidate_range => example_range(candidate_ids), - :candidates_count => candidate_ids.size - ) - - slice_size = (candidate_ids.length / 2.0).ceil - lhs, rhs = candidate_ids.each_slice(slice_size).to_a - - ids_to_ignore, duration = track_duration do - [lhs, rhs].find do |ids| - get_expected_failures_for?(remaining_ids - ids) - end - end - - if ids_to_ignore - self.remaining_ids -= ids_to_ignore - notify( - :bisect_round_ignoring_ids, - :ids_to_ignore => ids_to_ignore, - :ignore_range => example_range(ids_to_ignore), - :remaining_ids => remaining_ids, - :duration => duration - ) - bisect_over(candidate_ids - ids_to_ignore) - else - notify( - :bisect_round_detected_multiple_culprits, - :duration => duration - ) - bisect_over(lhs) - bisect_over(rhs) - end - end - - def currently_needed_ids - remaining_ids + failed_example_ids - end - - def repro_command_for_currently_needed_ids - return shell_command.repro_command_from(currently_needed_ids) if remaining_ids - "(Not yet enough information to provide any repro command)" - end - - # @private - # Convenience class for describing a subset of the candidate examples - ExampleRange = Struct.new(:start, :finish) do - def description - if start == finish - "example #{start}" - else - "examples #{start}-#{finish}" - end - end - end - - private - - def example_range(ids) - ExampleRange.new( - non_failing_example_ids.find_index(ids.first) + 1, - non_failing_example_ids.find_index(ids.last) + 1 - ) - end - - def prep - notify(:bisect_starting, :original_cli_args => shell_command.original_cli_args, - :bisect_runner => runner.class.name) - - _, duration = track_duration do - original_results = runner.original_results - @all_example_ids = original_results.all_example_ids - @failed_example_ids = original_results.failed_example_ids - @remaining_ids = non_failing_example_ids - end - - if @failed_example_ids.empty? - raise BisectFailedError, "\n\nNo failures found. Bisect only works " \ - "in the presence of one or more failing examples." - else - notify(:bisect_original_run_complete, :failed_example_ids => failed_example_ids, - :non_failing_example_ids => non_failing_example_ids, - :duration => duration) - end - end - - def non_failing_example_ids - @non_failing_example_ids ||= all_example_ids - failed_example_ids - end - - def get_expected_failures_for?(ids) - ids_to_run = all_example_ids & (ids + failed_example_ids) - notify( - :bisect_individual_run_start, - :command => shell_command.repro_command_from(ids_to_run), - :ids_to_run => ids_to_run - ) - - results, duration = track_duration { runner.run(ids_to_run) } - notify(:bisect_individual_run_complete, :duration => duration, :results => results) - - abort_if_ordering_inconsistent(results) - (failed_example_ids & results.failed_example_ids) == failed_example_ids - end - - def track_duration - start = ::RSpec::Core::Time.now - [yield, ::RSpec::Core::Time.now - start] - end - - def abort_if_ordering_inconsistent(results) - expected_order = all_example_ids & results.all_example_ids - return if expected_order == results.all_example_ids - - raise BisectFailedError, "\n\nThe example ordering is inconsistent. " \ - "`--bisect` relies upon consistent ordering (e.g. by passing " \ - "`--seed` if you're using random ordering) to work properly." - end - - def notify(*args) - @notifier.publish(*args) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb deleted file mode 100644 index 16d20dc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/fork_runner.rb +++ /dev/null @@ -1,140 +0,0 @@ -require 'stringio' -RSpec::Support.require_rspec_core "formatters/base_bisect_formatter" -RSpec::Support.require_rspec_core "bisect/utilities" - -module RSpec - module Core - module Bisect - # A Bisect runner that runs requested subsets of the suite by forking - # sub-processes. The main process bootstraps RSpec and the application - # environment (including preloading files specified via `--require`) so - # that the individual spec runs do not have to re-pay that cost. Each - # spec run happens in a forked process, ensuring that the spec files are - # not loaded in the main process. - # - # For most projects, bisections that use `ForkRunner` instead of - # `ShellRunner` will finish significantly faster, because the `ShellRunner` - # pays the cost of booting RSpec and the app environment on _every_ run of - # a subset. In contrast, `ForkRunner` pays that cost only once. - # - # However, not all projects can use `ForkRunner`. Obviously, on platforms - # that do not support forking (e.g. Windows), it cannot be used. In addition, - # it can cause problems for some projects that put side-effectful spec - # bootstrapping logic that should run on every spec run directly at the top - # level in a file loaded by `--require`, rather than in a `before(:suite)` - # hook. For example, consider a project that relies on some top-level logic - # in `spec_helper` to boot a Redis server for the test suite, intending the - # Redis bootstrapping to happen on every spec run. With `ShellRunner`, the - # bootstrapping logic will happen for each run of any subset of the suite, - # but for `ForkRunner`, such logic will only get run once, when the - # `RunDispatcher` boots the application environment. This might cause - # problems. The solution is for users to move the bootstrapping logic into - # a `before(:suite)` hook, or use the slower `ShellRunner`. - # - # @private - class ForkRunner - def self.start(shell_command, spec_runner) - instance = new(shell_command, spec_runner) - yield instance - ensure - instance.shutdown - end - - def self.name - :fork - end - - def initialize(shell_command, spec_runner) - @shell_command = shell_command - @channel = Channel.new - @run_dispatcher = RunDispatcher.new(spec_runner, @channel) - end - - def run(locations) - run_descriptor = ExampleSetDescriptor.new(locations, original_results.failed_example_ids) - dispatch_run(run_descriptor) - end - - def original_results - @original_results ||= dispatch_run(ExampleSetDescriptor.new( - @shell_command.original_locations, [])) - end - - def shutdown - @channel.close - end - - private - - def dispatch_run(run_descriptor) - @run_dispatcher.dispatch_specs(run_descriptor) - @channel.receive.tap do |result| - if result.is_a?(String) - raise BisectFailedError.for_failed_spec_run(result) - end - end - end - - # @private - class RunDispatcher - def initialize(runner, channel) - @runner = runner - @channel = channel - - @spec_output = StringIO.new - - runner.configuration.tap do |c| - c.reset_reporter - c.output_stream = @spec_output - c.error_stream = @spec_output - end - end - - def dispatch_specs(run_descriptor) - pid = fork { run_specs(run_descriptor) } - # We don't use Process.waitpid here as it was causing bisects to - # block due to the file descriptor limit on OSX / Linux. We need - # to detach the process to avoid having zombie processes - # consuming slots in the kernel process table during bisect runs. - Process.detach(pid) - end - - private - - def run_specs(run_descriptor) - # :nocov: - Executed in a forked process, by integration/bisect_spec - $stdout = $stderr = @spec_output - formatter = CaptureFormatter.new(run_descriptor.failed_example_ids) - - @runner.configuration.tap do |c| - c.files_or_directories_to_run = run_descriptor.all_example_ids - c.formatter = formatter - c.load_spec_files - end - - # `announce_filters` has the side effect of implementing the logic - # that honors `config.run_all_when_everything_filtered` so we need - # to call it here. When we remove `run_all_when_everything_filtered` - # (slated for RSpec 4), we can remove this call to `announce_filters`. - @runner.world.announce_filters - - @runner.run_specs(@runner.world.ordered_example_groups) - latest_run_results = formatter.results - - if latest_run_results.nil? || latest_run_results.all_example_ids.empty? - @channel.send(@spec_output.string) - else - @channel.send(latest_run_results) - end - # :nocov: - end - end - - class CaptureFormatter < Formatters::BaseBisectFormatter - attr_accessor :results - alias_method :notify_results, :results= - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb deleted file mode 100644 index 73f0299..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/server.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'drb/drb' -require 'drb/acl' -RSpec::Support.require_rspec_core "bisect/utilities" - -module RSpec - module Core - # @private - module Bisect - # @private - # A DRb server that receives run results from a separate RSpec process - # started by the bisect process. - class Server - def self.run - server = new - server.start - yield server - ensure - server.stop - end - - def capture_run_results(files_or_directories_to_run=[], expected_failures=[]) - self.expected_failures = expected_failures - self.files_or_directories_to_run = files_or_directories_to_run - self.latest_run_results = nil - run_output = yield - - if latest_run_results.nil? || latest_run_results.all_example_ids.empty? - raise BisectFailedError.for_failed_spec_run(run_output) - end - - latest_run_results - end - - def start - # Only allow remote DRb requests from this machine. - DRb.install_acl ACL.new(%w[ deny all allow localhost allow 127.0.0.1 allow ::1 ]) - - # We pass `nil` as the first arg to allow it to pick a DRb port. - @drb = DRb.start_service(nil, self) - end - - def stop - @drb.stop_service - end - - def drb_port - @drb_port ||= Integer(@drb.uri[/\d+$/]) - end - - # Fetched via DRb by the BisectDRbFormatter to determine when to abort. - attr_accessor :expected_failures - - # Set via DRb by the BisectDRbFormatter with the results of the run. - attr_accessor :latest_run_results - - # Fetched via DRb to tell clients which files to run - attr_accessor :files_or_directories_to_run - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb deleted file mode 100644 index b68f8b1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_command.rb +++ /dev/null @@ -1,126 +0,0 @@ -RSpec::Support.require_rspec_core "shell_escape" -require 'shellwords' - -module RSpec - module Core - module Bisect - # Provides an API to generate shell commands to run the suite for a - # set of locations, using the given bisect server to capture the results. - # @private - class ShellCommand - attr_reader :original_cli_args - - def initialize(original_cli_args) - @original_cli_args = original_cli_args.reject { |arg| arg.start_with?("--bisect") } - end - - def command_for(locations, server) - parts = [] - - parts << RUBY << load_path - parts << open3_safe_escape(RSpec::Core.path_to_executable) - - parts << "--format" << "bisect-drb" - parts << "--drb-port" << server.drb_port - - parts.concat(reusable_cli_options) - parts.concat(locations.map { |l| open3_safe_escape(l) }) - - parts.join(" ") - end - - def repro_command_from(locations) - parts = [] - - parts.concat environment_repro_parts - parts << "rspec" - parts.concat Formatters::Helpers.organize_ids(locations) - parts.concat original_cli_args_without_locations - - parts.join(" ") - end - - def original_locations - parsed_original_cli_options.fetch(:files_or_directories_to_run) - end - - def bisect_environment_hash - if ENV.key?('SPEC_OPTS') - { 'SPEC_OPTS' => spec_opts_without_bisect } - else - {} - end - end - - def spec_opts_without_bisect - Shellwords.join( - Shellwords.split(ENV.fetch('SPEC_OPTS', '')).reject do |arg| - arg =~ /^--bisect/ - end - ) - end - - private - - include RSpec::Core::ShellEscape - # On JRuby, Open3.popen3 does not handle shellescaped args properly: - # https://github.com/jruby/jruby/issues/2767 - if RSpec::Support::Ruby.jruby? - # :nocov: - alias open3_safe_escape quote - # :nocov: - else - alias open3_safe_escape escape - end - - def environment_repro_parts - bisect_environment_hash.map do |k, v| - %Q(#{k}="#{v}") - end - end - - def reusable_cli_options - @reusable_cli_options ||= begin - opts = original_cli_args_without_locations - - if (port = parsed_original_cli_options[:drb_port]) - opts -= %W[ --drb-port #{port} ] - end - - parsed_original_cli_options.fetch(:formatters) { [] }.each do |(name, out)| - opts -= %W[ --format #{name} -f -f#{name} ] - opts -= %W[ --out #{out} -o -o#{out} ] - end - - opts - end - end - - def original_cli_args_without_locations - @original_cli_args_without_locations ||= begin - files_or_dirs = parsed_original_cli_options.fetch(:files_or_directories_to_run) - @original_cli_args - files_or_dirs - end - end - - def parsed_original_cli_options - @parsed_original_cli_options ||= Parser.parse(@original_cli_args) - end - - def load_path - @load_path ||= "-I#{$LOAD_PATH.map { |p| open3_safe_escape(p) }.join(':')}" - end - - # Path to the currently running Ruby executable, borrowed from Rake: - # https://github.com/ruby/rake/blob/v10.4.2/lib/rake/file_utils.rb#L8-L12 - # Note that we skip `ENV['RUBY']` because we don't have to deal with running - # RSpec from within a MRI source repository: - # https://github.com/ruby/rake/commit/968682759b3b65e42748cd2befb2ff3e982272d9 - RUBY = File.join( - RbConfig::CONFIG['bindir'], - RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']). - sub(/.*\s.*/m, '"\&"') - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb deleted file mode 100644 index 34afb19..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/shell_runner.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'open3' -RSpec::Support.require_rspec_core "bisect/server" - -module RSpec - module Core - module Bisect - # Provides an API to run the suite for a set of locations, using - # the given bisect server to capture the results. - # - # Sets of specs are run by shelling out. - # @private - class ShellRunner - def self.start(shell_command, _spec_runner) - Server.run do |server| - yield new(server, shell_command) - end - end - - def self.name - :shell - end - - def initialize(server, shell_command) - @server = server - @shell_command = shell_command - end - - def run(locations) - run_locations(locations, original_results.failed_example_ids) - end - - def original_results - @original_results ||= run_locations(@shell_command.original_locations) - end - - private - - def run_locations(*capture_args) - @server.capture_run_results(*capture_args) do - run_command @shell_command.command_for([], @server) - end - end - - # `Open3.capture2e` does not work on JRuby: - # https://github.com/jruby/jruby/issues/2766 - if Open3.respond_to?(:capture2e) && !RSpec::Support::Ruby.jruby? - def run_command(cmd) - Open3.capture2e(@shell_command.bisect_environment_hash, cmd).first - end - else # for 1.8.7 - # :nocov: - def run_command(cmd) - out = err = nil - - original_spec_opts = ENV['SPEC_OPTS'] - ENV['SPEC_OPTS'] = @shell_command.spec_opts_without_bisect - - Open3.popen3(cmd) do |_, stdout, stderr| - # Reading the streams blocks until the process is complete - out = stdout.read - err = stderr.read - end - - "Stdout:\n#{out}\n\nStderr:\n#{err}" - ensure - ENV['SPEC_OPTS'] = original_spec_opts - end - # :nocov: - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb deleted file mode 100644 index 4600f35..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/bisect/utilities.rb +++ /dev/null @@ -1,69 +0,0 @@ -module RSpec - module Core - module Bisect - # @private - ExampleSetDescriptor = Struct.new(:all_example_ids, :failed_example_ids) - - # @private - class BisectFailedError < StandardError - def self.for_failed_spec_run(spec_output) - new("Failed to get results from the spec run. Spec run output:\n\n" + - spec_output) - end - end - - # Wraps a `formatter` providing a simple means to notify it in place - # of an `RSpec::Core::Reporter`, without involving configuration in - # any way. - # @private - class Notifier - def initialize(formatter) - @formatter = formatter - end - - def publish(event, *args) - return unless @formatter.respond_to?(event) - notification = Notifications::CustomNotification.for(*args) - @formatter.__send__(event, notification) - end - end - - # Wraps a pipe to support sending objects between a child and - # parent process. Where supported, encoding is explicitly - # set to ensure binary data is able to pass from child to - # parent. - # @private - class Channel - if String.method_defined?(:encoding) - MARSHAL_DUMP_ENCODING = Marshal.dump("").encoding - end - - def initialize - @read_io, @write_io = IO.pipe - - if defined?(MARSHAL_DUMP_ENCODING) && IO.method_defined?(:set_encoding) - # Ensure the pipe can send any content produced by Marshal.dump - @write_io.set_encoding MARSHAL_DUMP_ENCODING - end - end - - def send(message) - packet = Marshal.dump(message) - @write_io.write("#{packet.bytesize}\n#{packet}") - end - - # rubocop:disable Security/MarshalLoad - def receive - packet_size = Integer(@read_io.gets) - Marshal.load(@read_io.read(packet_size)) - end - # rubocop:enable Security/MarshalLoad - - def close - @read_io.close - @write_io.close - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb deleted file mode 100644 index c207b7a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb +++ /dev/null @@ -1,2419 +0,0 @@ -RSpec::Support.require_rspec_core "backtrace_formatter" -RSpec::Support.require_rspec_core "ruby_project" -RSpec::Support.require_rspec_core "formatters/deprecation_formatter" -RSpec::Support.require_rspec_core "output_wrapper" - -module RSpec - module Core - # rubocop:disable Metrics/ClassLength - - # Stores runtime configuration information. - # - # Configuration options are loaded from multiple files and joined together - # with command-line switches and the `SPEC_OPTS` environment variable. - # - # Precedence order (where later entries overwrite earlier entries on - # conflicts): - # - # * Global (`$XDG_CONFIG_HOME/rspec/options`, or `~/.rspec` if it does - # not exist) - # * Project-specific (`./.rspec`) - # * Local (`./.rspec-local`) - # * Command-line options - # * `SPEC_OPTS` - # - # For example, an option set in the local file will override an option set - # in your global file. - # - # The global, project-specific and local files can all be overridden with a - # separate custom file using the --options command-line parameter. - # - # @example Standard settings - # RSpec.configure do |c| - # c.drb = true - # c.drb_port = 1234 - # c.default_path = 'behavior' - # end - # - # @example Hooks - # RSpec.configure do |c| - # c.before(:suite) { establish_connection } - # c.before(:example) { log_in_as :authorized } - # c.around(:example) { |ex| Database.transaction(&ex) } - # end - # - # @see RSpec.configure - # @see Hooks - class Configuration - include RSpec::Core::Hooks - - # Module that holds `attr_reader` declarations. It's in a separate - # module to allow us to override those methods and use `super`. - # @private - Readers = Module.new - include Readers - - # @private - class MustBeConfiguredBeforeExampleGroupsError < StandardError; end - - # @private - def self.define_reader(name) - Readers.class_eval do - remove_method name if method_defined?(name) - attr_reader name - end - - define_method(name) { value_for(name) { super() } } - end - - # @private - def self.define_alias(name, alias_name) - alias_method alias_name, name - alias_method "#{alias_name}=", "#{name}=" - define_predicate alias_name - end - - # @private - def self.define_predicate(name) - define_method "#{name}?" do - !!send(name) - end - end - - # @private - # - # Invoked by the `add_setting` instance method. Use that method on a - # `Configuration` instance rather than this class method. - def self.add_setting(name, opts={}) - raise "Use the instance add_setting method if you want to set a default" if opts.key?(:default) - attr_writer name - add_read_only_setting name - - Array(opts[:alias_with]).each do |alias_name| - define_alias(name, alias_name) - end - end - - # @private - # - # As `add_setting` but only add the reader. - def self.add_read_only_setting(name, opts={}) - raise "Use the instance add_setting method if you want to set a default" if opts.key?(:default) - define_reader name - define_predicate name - end - - # @macro [attach] add_setting - # @!attribute [rw] $1 - # - # @macro [attach] define_reader - # @!attribute [r] $1 - - # @macro add_setting - # Path to use if no path is provided to the `rspec` command (default: - # `"spec"`). Allows you to just type `rspec` instead of `rspec spec` to - # run all the examples in the `spec` directory. - # - # @note Other scripts invoking `rspec` indirectly will ignore this - # setting. - # @return [String] - add_read_only_setting :default_path - def default_path=(path) - project_source_dirs << path - @default_path = path - end - - # @macro add_setting - # Run examples over DRb (default: `false`). RSpec doesn't supply the DRb - # server, but you can use tools like spork. - # @return [Boolean] - add_setting :drb - - # @macro add_setting - # The drb_port (default: nil). - add_setting :drb_port - - # @macro add_setting - # Default: `$stderr`. - add_setting :error_stream - - # Indicates if the DSL has been exposed off of modules and `main`. - # Default: true - # @return [Boolean] - def expose_dsl_globally? - Core::DSL.exposed_globally? - end - - # Use this to expose the core RSpec DSL via `Module` and the `main` - # object. It will be set automatically but you can override it to - # remove the DSL. - # Default: true - def expose_dsl_globally=(value) - if value - Core::DSL.expose_globally! - Core::SharedExampleGroup::TopLevelDSL.expose_globally! - else - Core::DSL.remove_globally! - Core::SharedExampleGroup::TopLevelDSL.remove_globally! - end - end - - # Determines where deprecation warnings are printed. - # Defaults to `$stderr`. - # @return [IO, String] IO or filename to write to - define_reader :deprecation_stream - - # Determines where deprecation warnings are printed. - # @param value [IO, String] IO to write to or filename to write to - def deprecation_stream=(value) - if @reporter && !value.equal?(@deprecation_stream) - warn "RSpec's reporter has already been initialized with " \ - "#{deprecation_stream.inspect} as the deprecation stream, so your change to "\ - "`deprecation_stream` will be ignored. You should configure it earlier for " \ - "it to take effect, or use the `--deprecation-out` CLI option. " \ - "(Called from #{CallerFilter.first_non_rspec_line})" - else - @deprecation_stream = value - end - end - - # @macro define_reader - # The file path to use for persisting example statuses. Necessary for the - # `--only-failures` and `--next-failure` CLI options. - # - # @overload example_status_persistence_file_path - # @return [String] the file path - # @overload example_status_persistence_file_path=(value) - # @param value [String] the file path - define_reader :example_status_persistence_file_path - - # Sets the file path to use for persisting example statuses. Necessary for the - # `--only-failures` and `--next-failure` CLI options. - def example_status_persistence_file_path=(value) - @example_status_persistence_file_path = value - clear_values_derived_from_example_status_persistence_file_path - end - - # @macro define_reader - # Indicates if the `--only-failures` (or `--next-failure`) flag is being used. - define_reader :only_failures - alias_method :only_failures?, :only_failures - - # @private - def only_failures_but_not_configured? - only_failures? && !example_status_persistence_file_path - end - - # @macro define_reader - # If specified, indicates the number of failures required before cleaning - # up and exit (default: `nil`). Can also be `true` to fail and exit on first - # failure - define_reader :fail_fast - - # @see fail_fast - def fail_fast=(value) - case value - when true, 'true' - @fail_fast = true - when false, 'false', 0 - @fail_fast = false - when nil - @fail_fast = nil - else - @fail_fast = value.to_i - - if value.to_i == 0 - # TODO: in RSpec 4, consider raising an error here. - RSpec.warning "Cannot set `RSpec.configuration.fail_fast`" \ - " to `#{value.inspect}`. Only `true`, `false`, `nil` and integers" \ - " are valid values." - @fail_fast = true - end - end - end - - # @macro add_setting - # Prints the formatter output of your suite without running any - # examples or hooks. - add_setting :dry_run - - # @macro add_setting - # The exit code to return if there are any failures (default: 1). - # @return [Integer] - add_setting :failure_exit_code - - # @macro add_setting - # The exit code to return if there are any errors outside examples (default: failure_exit_code) - # @return [Integer] - add_setting :error_exit_code - - # @macro add_setting - # Whether or not to fail when there are no RSpec examples (default: false). - # @return [Boolean] - add_setting :fail_if_no_examples - - # @macro define_reader - # Indicates files configured to be required. - # @return [Array] - define_reader :requires - - # @macro define_reader - # Returns dirs that have been prepended to the load path by the `-I` - # command line option. - # @return [Array] - define_reader :libs - - # @macro add_setting - # Determines where RSpec will send its output. - # Default: `$stdout`. - # @return [IO, String] - define_reader :output_stream - - # Set the output stream for reporter. - # @attr value [IO, String] IO to write to or filename to write to, defaults to $stdout - def output_stream=(value) - if @reporter && !value.equal?(@output_stream) - warn "RSpec's reporter has already been initialized with " \ - "#{output_stream.inspect} as the output stream, so your change to "\ - "`output_stream` will be ignored. You should configure it earlier for " \ - "it to take effect. (Called from #{CallerFilter.first_non_rspec_line})" - else - @output_stream = value - output_wrapper.output = @output_stream - end - end - - # @macro define_reader - # Load files matching this pattern (default: `'**{,/*/**}/*_spec.rb'`). - # @return [String] - define_reader :pattern - - # Set pattern to match files to load. - # @attr value [String] the filename pattern to filter spec files by - def pattern=(value) - update_pattern_attr :pattern, value - end - - # @macro define_reader - # Exclude files matching this pattern. - # @return [String] - define_reader :exclude_pattern - - # Set pattern to match files to exclude. - # @attr value [String] the filename pattern to exclude spec files by - def exclude_pattern=(value) - update_pattern_attr :exclude_pattern, value - end - - # @macro add_setting - # Specifies which directories contain the source code for your project. - # When a failure occurs, RSpec looks through the backtrace to find a - # a line of source to print. It first looks for a line coming from - # one of the project source directories so that, for example, it prints - # the expectation or assertion call rather than the source code from - # the expectation or assertion framework. - # @return [Array] - add_setting :project_source_dirs - - # @macro add_setting - # Report the times for the slowest examples (default: `false`). - # Use this to specify the number of examples to include in the profile. - # @return [Boolean] - attr_writer :profile_examples - define_predicate :profile_examples - - # @macro add_setting - # Run all examples if none match the configured filters - # (default: `false`). - # @deprecated Use {#filter_run_when_matching} instead for the specific - # filters that you want to be ignored if none match. - add_setting :run_all_when_everything_filtered - - # @macro add_setting - # Color to use to indicate success. Defaults to `:green` but can be set - # to one of the following: `[:black, :white, :red, :green, :yellow, - # :blue, :magenta, :cyan]` - # @return [Symbol] - add_setting :success_color - - # @macro add_setting - # Color to use to print pending examples. Defaults to `:yellow` but can - # be set to one of the following: `[:black, :white, :red, :green, - # :yellow, :blue, :magenta, :cyan]` - # @return [Symbol] - add_setting :pending_color - - # @macro add_setting - # Color to use to indicate failure. Defaults to `:red` but can be set to - # one of the following: `[:black, :white, :red, :green, :yellow, :blue, - # :magenta, :cyan]` - # @return [Symbol] - add_setting :failure_color - - # @macro add_setting - # The default output color. Defaults to `:white` but can be set to one of - # the following: `[:black, :white, :red, :green, :yellow, :blue, - # :magenta, :cyan]` - # @return [Symbol] - add_setting :default_color - - # @macro add_setting - # Color used when a pending example is fixed. Defaults to `:blue` but can - # be set to one of the following: `[:black, :white, :red, :green, - # :yellow, :blue, :magenta, :cyan]` - # @return [Symbol] - add_setting :fixed_color - - # @macro add_setting - # Color used to print details. Defaults to `:cyan` but can be set to one - # of the following: `[:black, :white, :red, :green, :yellow, :blue, - # :magenta, :cyan]` - # @return [Symbol] - add_setting :detail_color - - # @macro add_setting - # Don't print filter info i.e. "Run options: include {:focus=>true}" - # (default `false`). - # return [Boolean] - add_setting :silence_filter_announcements - - # @deprecated This config option was added in RSpec 2 to pave the way - # for this being the default behavior in RSpec 3. Now this option is - # a no-op. - def treat_symbols_as_metadata_keys_with_true_values=(_value) - RSpec.deprecate( - "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=", - :message => "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values= " \ - "is deprecated, it is now set to true as default and " \ - "setting it to false has no effect." - ) - end - - # @macro define_reader - # Configures how RSpec treats metadata passed as part of a shared example - # group definition. For example, given this shared example group definition: - # - # RSpec.shared_context "uses DB", :db => true do - # around(:example) do |ex| - # MyORM.transaction(:rollback => true, &ex) - # end - # end - # - # ...there are two ways RSpec can treat the `:db => true` metadata, each - # of which has a corresponding config option: - # - # 1. `:trigger_inclusion`: this shared context will be implicitly included - # in any groups (or examples) that have `:db => true` metadata. - # 2. `:apply_to_host_groups`: the metadata will be inherited by the metadata - # hash of all host groups and examples. - # - # `:trigger_inclusion` is the legacy behavior from before RSpec 3.5 but should - # be considered deprecated. Instead, you can explicitly include a group with - # `include_context`: - # - # RSpec.describe "My model" do - # include_context "uses DB" - # end - # - # ...or you can configure RSpec to include the context based on matching metadata - # using an API that mirrors configured module inclusion: - # - # RSpec.configure do |rspec| - # rspec.include_context "uses DB", :db => true - # end - # - # `:apply_to_host_groups` is a new feature of RSpec 3.5 and will be the only - # supported behavior in RSpec 4. - # - # @overload shared_context_metadata_behavior - # @return [:trigger_inclusion, :apply_to_host_groups] the configured behavior - # @overload shared_context_metadata_behavior=(value) - # @param value [:trigger_inclusion, :apply_to_host_groups] sets the configured behavior - define_reader :shared_context_metadata_behavior - # @see shared_context_metadata_behavior - def shared_context_metadata_behavior=(value) - case value - when :trigger_inclusion, :apply_to_host_groups - @shared_context_metadata_behavior = value - else - raise ArgumentError, "Cannot set `RSpec.configuration." \ - "shared_context_metadata_behavior` to `#{value.inspect}`. Only " \ - "`:trigger_inclusion` and `:apply_to_host_groups` are valid values." - end - end - - # Record the start time of the spec suite to measure load time. - # return [Time] - add_setting :start_time - - # @macro add_setting - # Use threadsafe options where available. - # Currently this will place a mutex around memoized values such as let blocks. - # return [Boolean] - add_setting :threadsafe - - # @macro add_setting - # Maximum count of failed source lines to display in the failure reports - # (defaults to `10`). - # return [Integer] - add_setting :max_displayed_failure_line_count - - # @macro full_cause_backtrace - # Display the full backtrace of an exceptions cause (defaults to `false`). - # return [Boolean] - add_setting :full_cause_backtrace - - # @macro add_setting - # Format the output for pending examples. Can be set to: - # - :full (default) - pending examples appear similarly to failures - # - :no_backtrace - same as above, but with no backtrace - # - :skip - do not show the section at all - # return [Symbol] - add_read_only_setting :pending_failure_output - def pending_failure_output=(mode) - raise ArgumentError, - "`pending_failure_output` can be set to :full, :no_backtrace, " \ - "or :skip" unless [:full, :no_backtrace, :skip].include?(mode) - @pending_failure_output = mode - end - - # Determines which bisect runner implementation gets used to run subsets - # of the suite during a bisection. Your choices are: - # - # - `:shell`: Performs a spec run by shelling out, booting RSpec and your - # application environment each time. This runner is the most widely - # compatible runner, but is not as fast. On platforms that do not - # support forking, this is the default. - # - `:fork`: Pre-boots RSpec and your application environment in a parent - # process, and then forks a child process for each spec run. This runner - # tends to be significantly faster than the `:shell` runner but cannot - # be used in some situations. On platforms that support forking, this - # is the default. If you use this runner, you should ensure that all - # of your one-time setup logic goes in a `before(:suite)` hook instead - # of getting run at the top-level of a file loaded by `--require`. - # - # @note This option will only be used by `--bisect` if you set it in a file - # loaded via `--require`. - # - # @return [Symbol] - attr_reader :bisect_runner - def bisect_runner=(value) - if @bisect_runner_class && value != @bisect_runner - raise "`config.bisect_runner = #{value.inspect}` can no longer take " \ - "effect as the #{@bisect_runner.inspect} bisect runnner is already " \ - "in use. This config setting must be set in a file loaded by a " \ - "`--require` option (passed at the CLI or in a `.rspec` file) for " \ - "it to have any effect." - end - - @bisect_runner = value - end - - # @private - # @deprecated Use {#color_mode} = :on, instead of {#color} with {#tty} - add_setting :tty - # @private - attr_writer :files_to_run - # @private - attr_accessor :filter_manager, :world - # @private - attr_accessor :static_config_filter_manager - # @private - attr_reader :backtrace_formatter, :ordering_manager, :loaded_spec_files - - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength - - # Build an object to store runtime configuration options and set defaults - def initialize - # rubocop:disable Style/GlobalVars - @start_time = $_rspec_core_load_started_at || ::RSpec::Core::Time.now - # rubocop:enable Style/GlobalVars - @expectation_frameworks = [] - @include_modules = FilterableItemRepository::QueryOptimized.new(:any?) - @extend_modules = FilterableItemRepository::QueryOptimized.new(:any?) - @prepend_modules = FilterableItemRepository::QueryOptimized.new(:any?) - - @bisect_runner = RSpec::Support::RubyFeatures.fork_supported? ? :fork : :shell - @bisect_runner_class = nil - - @before_suite_hooks = [] - @after_suite_hooks = [] - - @mock_framework = nil - @files_or_directories_to_run = [] - @loaded_spec_files = Set.new - @color = false - @color_mode = :automatic - @pattern = '**{,/*/**}/*_spec.rb' - @exclude_pattern = '' - @failure_exit_code = 1 - @error_exit_code = nil # so it can be overridden by failure exit code - @fail_if_no_examples = false - @spec_files_loaded = false - - @backtrace_formatter = BacktraceFormatter.new - - @default_path = 'spec' - @project_source_dirs = %w[ spec lib app ] - @deprecation_stream = $stderr - @output_stream = $stdout - @reporter = nil - @reporter_buffer = nil - @filter_manager = FilterManager.new - @static_config_filter_manager = FilterManager.new - @ordering_manager = Ordering::ConfigurationManager.new - @preferred_options = {} - @failure_color = :red - @success_color = :green - @pending_color = :yellow - @default_color = :white - @fixed_color = :blue - @detail_color = :cyan - @profile_examples = false - @requires = [] - @libs = [] - @derived_metadata_blocks = FilterableItemRepository::QueryOptimized.new(:any?) - @threadsafe = true - @max_displayed_failure_line_count = 10 - @full_cause_backtrace = false - @world = World::Null - @shared_context_metadata_behavior = :trigger_inclusion - @pending_failure_output = :full - - define_built_in_hooks - end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength - - # @private - # - # Used to set higher priority option values from the command line. - def force(hash) - ordering_manager.force(hash) - @preferred_options.merge!(hash) - - return unless hash.key?(:example_status_persistence_file_path) - clear_values_derived_from_example_status_persistence_file_path - end - - # @private - def reset - @spec_files_loaded = false - reset_reporter - end - - # @private - def reset_reporter - @reporter = nil - @formatter_loader = nil - @output_wrapper = nil - end - - # @private - def reset_filters - self.filter_manager = FilterManager.new - filter_manager.include_only( - Metadata.deep_hash_dup(static_config_filter_manager.inclusions.rules) - ) - filter_manager.exclude_only( - Metadata.deep_hash_dup(static_config_filter_manager.exclusions.rules) - ) - end - - # @overload add_setting(name) - # @overload add_setting(name, opts) - # @option opts [Symbol] :default - # - # Set a default value for the generated getter and predicate methods: - # - # add_setting(:foo, :default => "default value") - # - # @option opts [Symbol] :alias_with - # - # Use `:alias_with` to alias the setter, getter, and predicate to - # another name, or names: - # - # add_setting(:foo, :alias_with => :bar) - # add_setting(:foo, :alias_with => [:bar, :baz]) - # - # Adds a custom setting to the RSpec.configuration object. - # - # RSpec.configuration.add_setting :foo - # - # Used internally and by extension frameworks like rspec-rails, so they - # can add config settings that are domain specific. For example: - # - # RSpec.configure do |c| - # c.add_setting :use_transactional_fixtures, - # :default => true, - # :alias_with => :use_transactional_examples - # end - # - # `add_setting` creates three methods on the configuration object, a - # setter, a getter, and a predicate: - # - # RSpec.configuration.foo=(value) - # RSpec.configuration.foo - # RSpec.configuration.foo? # Returns true if foo returns anything but nil or false. - def add_setting(name, opts={}) - default = opts.delete(:default) - (class << self; self; end).class_exec do - add_setting(name, opts) - end - __send__("#{name}=", default) if default - end - - # Returns the configured mock framework adapter module. - # @return [Symbol] - def mock_framework - if @mock_framework.nil? - begin - mock_with :rspec - rescue LoadError - mock_with :nothing - end - end - @mock_framework - end - - # Delegates to mock_framework=(framework). - def mock_framework=(framework) - mock_with framework - end - - # Regexps used to exclude lines from backtraces. - # - # Excludes lines from ruby (and jruby) source, installed gems, anything - # in any "bin" directory, and any of the RSpec libs (outside gem - # installs) by default. - # - # You can modify the list via the getter, or replace it with the setter. - # - # To override this behaviour and display a full backtrace, use - # `--backtrace` on the command line, in a `.rspec` file, or in the - # `rspec_options` attribute of RSpec's rake task. - # @return [Array] - def backtrace_exclusion_patterns - @backtrace_formatter.exclusion_patterns - end - - # Set regular expressions used to exclude lines in backtrace. - # @param patterns [Array] set backtrace_formatter exclusion_patterns - def backtrace_exclusion_patterns=(patterns) - @backtrace_formatter.exclusion_patterns = patterns - end - - # Regexps used to include lines in backtraces. - # - # Defaults to [Regexp.new Dir.getwd]. - # - # Lines that match an exclusion _and_ an inclusion pattern - # will be included. - # - # You can modify the list via the getter, or replace it with the setter. - # @return [Array] - def backtrace_inclusion_patterns - @backtrace_formatter.inclusion_patterns - end - - # Set regular expressions used to include lines in backtrace. - # @attr patterns [Array] set backtrace_formatter inclusion_patterns - def backtrace_inclusion_patterns=(patterns) - @backtrace_formatter.inclusion_patterns = patterns - end - - # Adds {#backtrace_exclusion_patterns} that will filter lines from - # the named gems from backtraces. - # - # @param gem_names [Array] Names of the gems to filter - # - # @example - # RSpec.configure do |config| - # config.filter_gems_from_backtrace "rack", "rake" - # end - # - # @note The patterns this adds will match the named gems in their common - # locations (e.g. system gems, vendored with bundler, installed as a - # :git dependency with bundler, etc) but is not guaranteed to work for - # all possible gem locations. For example, if you have the gem source - # in a directory with a completely unrelated name, and use bundler's - # :path option, this will not filter it. - def filter_gems_from_backtrace(*gem_names) - gem_names.each do |name| - @backtrace_formatter.filter_gem(name) - end - end - - # @private - MOCKING_ADAPTERS = { - :rspec => :RSpec, - :flexmock => :Flexmock, - :rr => :RR, - :mocha => :Mocha, - :nothing => :Null - } - - # Sets the mock framework adapter module. - # - # `framework` can be a Symbol or a Module. - # - # Given any of `:rspec`, `:mocha`, `:flexmock`, or `:rr`, configures the - # named framework. - # - # Given `:nothing`, configures no framework. Use this if you don't use - # any mocking framework to save a little bit of overhead. - # - # Given a Module, includes that module in every example group. The module - # should adhere to RSpec's mock framework adapter API: - # - # setup_mocks_for_rspec - # - called before each example - # - # verify_mocks_for_rspec - # - called after each example if the example hasn't yet failed. - # Framework should raise an exception when expectations fail - # - # teardown_mocks_for_rspec - # - called after verify_mocks_for_rspec (even if there are errors) - # - # If the module responds to `configuration` and `mock_with` receives a - # block, it will yield the configuration object to the block e.g. - # - # config.mock_with OtherMockFrameworkAdapter do |mod_config| - # mod_config.custom_setting = true - # end - def mock_with(framework) - framework_module = - if framework.is_a?(Module) - framework - else - const_name = MOCKING_ADAPTERS.fetch(framework) do - raise ArgumentError, - "Unknown mocking framework: #{framework.inspect}. " \ - "Pass a module or one of #{MOCKING_ADAPTERS.keys.inspect}" - end - - RSpec::Support.require_rspec_core "mocking_adapters/#{const_name.to_s.downcase}" - RSpec::Core::MockingAdapters.const_get(const_name) - end - - new_name, old_name = [framework_module, @mock_framework].map do |mod| - mod.respond_to?(:framework_name) ? mod.framework_name : :unnamed - end - - unless new_name == old_name - assert_no_example_groups_defined(:mock_framework) - end - - if block_given? - raise "#{framework_module} must respond to `configuration` so that " \ - "mock_with can yield it." unless framework_module.respond_to?(:configuration) - yield framework_module.configuration - end - - @mock_framework = framework_module - end - - # Returns the configured expectation framework adapter module(s) - def expectation_frameworks - if @expectation_frameworks.empty? - begin - expect_with :rspec - rescue LoadError - expect_with Module.new - end - end - @expectation_frameworks - end - - # Delegates to expect_with(framework). - def expectation_framework=(framework) - expect_with(framework) - end - - # Sets the expectation framework module(s) to be included in each example - # group. - # - # `frameworks` can be `:rspec`, `:test_unit`, `:minitest`, a custom - # module, or any combination thereof: - # - # config.expect_with :rspec - # config.expect_with :test_unit - # config.expect_with :minitest - # config.expect_with :rspec, :minitest - # config.expect_with OtherExpectationFramework - # - # RSpec will translate `:rspec`, `:minitest`, and `:test_unit` into the - # appropriate modules. - # - # ## Configuration - # - # If the module responds to `configuration`, `expect_with` will - # yield the `configuration` object if given a block: - # - # config.expect_with OtherExpectationFramework do |custom_config| - # custom_config.custom_setting = true - # end - def expect_with(*frameworks) - modules = frameworks.map do |framework| - case framework - when Module - framework - when :rspec - require 'rspec/expectations' - - # Tag this exception class so our exception formatting logic knows - # that it satisfies the `MultipleExceptionError` interface. - ::RSpec::Expectations::MultipleExpectationsNotMetError.__send__( - :include, MultipleExceptionError::InterfaceTag - ) - - ::RSpec::Matchers - when :test_unit - require 'rspec/core/test_unit_assertions_adapter' - ::RSpec::Core::TestUnitAssertionsAdapter - when :minitest - require 'rspec/core/minitest_assertions_adapter' - ::RSpec::Core::MinitestAssertionsAdapter - else - raise ArgumentError, "#{framework.inspect} is not supported" - end - end - - if (modules - @expectation_frameworks).any? - assert_no_example_groups_defined(:expect_with) - end - - if block_given? - raise "expect_with only accepts a block with a single argument. " \ - "Call expect_with #{modules.length} times, " \ - "once with each argument, instead." if modules.length > 1 - raise "#{modules.first} must respond to `configuration` so that " \ - "expect_with can yield it." unless modules.first.respond_to?(:configuration) - yield modules.first.configuration - end - - @expectation_frameworks.push(*modules) - end - - # Check if full backtrace is enabled. - # @return [Boolean] is full backtrace enabled - def full_backtrace? - @backtrace_formatter.full_backtrace? - end - - # Toggle full backtrace. - # @attr true_or_false [Boolean] toggle full backtrace display - def full_backtrace=(true_or_false) - @backtrace_formatter.full_backtrace = true_or_false - end - - # Enables color output if the output is a TTY. As of RSpec 3.6, this is - # the default behavior and this option is retained only for backwards - # compatibility. - # - # @deprecated No longer recommended because of complex behavior. Instead, - # rely on the fact that TTYs will display color by default, or set - # {#color_mode} to :on to display color on a non-TTY output. - # @see color_mode - # @see color_enabled? - # @return [Boolean] - def color - value_for(:color) { @color } - end - - # The mode for determining whether to display output in color. One of: - # - # - :automatic - the output will be in color if the output is a TTY (the - # default) - # - :on - the output will be in color, whether or not the output is a TTY - # - :off - the output will not be in color - # - # @see color_enabled? - # @return [Boolean] - def color_mode - value_for(:color_mode) { @color_mode } - end - - # Check if color is enabled for a particular output. - # @param output [IO] an output stream to use, defaults to the current - # `output_stream` - # @return [Boolean] - def color_enabled?(output=output_stream) - case color_mode - when :on then true - when :off then false - else # automatic - output_to_tty?(output) || (color && tty?) - end - end - - # Set the color mode. - attr_writer :color_mode - - # Toggle output color. - # - # @deprecated No longer recommended because of complex behavior. Instead, - # rely on the fact that TTYs will display color by default, or set - # {:color_mode} to :on to display color on a non-TTY output. - attr_writer :color - - # @private - def libs=(libs) - libs.map do |lib| - @libs.unshift lib - $LOAD_PATH.unshift lib - end - end - - # Run examples matching on `description` in all files to run. - # @param description [String, Regexp] the pattern to filter on - def full_description=(description) - filter_run :full_description => Regexp.union(*Array(description).map { |d| Regexp.new(d) }) - end - - # @return [Array] full description filter - def full_description - filter.fetch :full_description, nil - end - - # @overload add_formatter(formatter) - # @overload add_formatter(formatter, output) - # - # @param formatter [Class, String, Object] formatter to use. Can be any of the - # string values supported from the CLI (`p`/`progress`, - # `d`/`doc`/`documentation`, `h`/`html`, or `j`/`json`), any - # class that implements the formatter protocol and has registered - # itself with RSpec as a formatter, or a formatter instance. - # @param output [String, IO] where the formatter will write its output. - # Can be an IO object or a string path to a file. If not provided, - # the configured `output_stream` (`$stdout`, by default) will be used. - # - # Adds a formatter to the set RSpec will use for this run. - # - # @see RSpec::Core::Formatters::Protocol - def add_formatter(formatter, output=output_wrapper) - formatter_loader.add(formatter, output) - end - alias_method :formatter=, :add_formatter - - # The formatter that will be used if no formatter has been set. - # Defaults to 'progress'. - def default_formatter - formatter_loader.default_formatter - end - - # Sets a fallback formatter to use if none other has been set. - # - # @example - # - # RSpec.configure do |rspec| - # rspec.default_formatter = 'doc' - # end - def default_formatter=(value) - formatter_loader.default_formatter = value - end - - # Returns a duplicate of the formatters currently loaded in - # the `FormatterLoader` for introspection. - # - # Note as this is a duplicate, any mutations will be disregarded. - # - # @return [Array] the formatters currently loaded - def formatters - formatter_loader.formatters.dup - end - - # @private - def formatter_loader - @formatter_loader ||= Formatters::Loader.new(Reporter.new(self)) - end - - # @private - # - # This buffer is used to capture all messages sent to the reporter during - # reporter initialization. It can then replay those messages after the - # formatter is correctly initialized. Otherwise, deprecation warnings - # during formatter initialization can cause an infinite loop. - class DeprecationReporterBuffer - def initialize - @calls = [] - end - - def deprecation(*args) - @calls << args - end - - def play_onto(reporter) - @calls.each do |args| - reporter.deprecation(*args) - end - end - end - - # @return [RSpec::Core::Reporter] the currently configured reporter - def reporter - # @reporter_buffer should only ever be set in this method to cover - # initialization of @reporter. - @reporter_buffer || @reporter ||= - begin - @reporter_buffer = DeprecationReporterBuffer.new - formatter_loader.prepare_default output_wrapper, deprecation_stream - @reporter_buffer.play_onto(formatter_loader.reporter) - @reporter_buffer = nil - formatter_loader.reporter - end - end - - # @api private - # - # Defaults `profile_examples` to 10 examples when `@profile_examples` is - # `true`. - def profile_examples - profile = value_for(:profile_examples) { @profile_examples } - if profile && !profile.is_a?(Integer) - 10 - else - profile - end - end - - # @private - def files_or_directories_to_run=(*files) - files = files.flatten - - if (command == 'rspec' || Runner.running_in_drb?) && default_path && files.empty? - files << default_path - end - - @files_or_directories_to_run = files - @files_to_run = nil - end - - # The spec files RSpec will run. - # @return [Array] specified files about to run - def files_to_run - @files_to_run ||= get_files_to_run(@files_or_directories_to_run) - end - - # @private - def last_run_statuses - @last_run_statuses ||= Hash.new(UNKNOWN_STATUS).tap do |statuses| - if (path = example_status_persistence_file_path) - begin - ExampleStatusPersister.load_from(path).inject(statuses) do |hash, example| - status = example[:status] - status = UNKNOWN_STATUS unless VALID_STATUSES.include?(status) - hash[example.fetch(:example_id)] = status - hash - end - rescue SystemCallError => e - RSpec.warning "Could not read from #{path.inspect} (configured as " \ - "`config.example_status_persistence_file_path`) due " \ - "to a system error: #{e.inspect}. Please check that " \ - "the config option is set to an accessible, valid " \ - "file path", :call_site => nil - end - end - end - end - - # @private - UNKNOWN_STATUS = "unknown".freeze - - # @private - FAILED_STATUS = "failed".freeze - - # @private - PASSED_STATUS = "passed".freeze - - # @private - PENDING_STATUS = "pending".freeze - - # @private - VALID_STATUSES = [UNKNOWN_STATUS, FAILED_STATUS, PASSED_STATUS, PENDING_STATUS] - - # @private - def spec_files_with_failures - @spec_files_with_failures ||= last_run_statuses.inject(Set.new) do |files, (id, status)| - files << Example.parse_id(id).first if status == FAILED_STATUS - files - end.to_a - end - - # Creates a method that delegates to `example` including the submitted - # `args`. Used internally to add variants of `example` like `pending`: - # @param name [String] example name alias - # @param args [Array, Hash] metadata for the generated example - # - # @note The specific example alias below (`pending`) is already - # defined for you. - # @note Use with caution. This extends the language used in your - # specs, but does not add any additional documentation. We use this - # in RSpec to define methods like `focus` and `xit`, but we also add - # docs for those methods. - # - # @example - # RSpec.configure do |config| - # config.alias_example_to :pending, :pending => true - # end - # - # # This lets you do this: - # - # RSpec.describe Thing do - # pending "does something" do - # thing = Thing.new - # end - # end - # - # # ... which is the equivalent of - # - # RSpec.describe Thing do - # it "does something", :pending => true do - # thing = Thing.new - # end - # end - def alias_example_to(name, *args) - extra_options = Metadata.build_hash_from(args) - RSpec::Core::ExampleGroup.define_example_method(name, extra_options) - end - - # Creates a method that defines an example group with the provided - # metadata. Can be used to define example group/metadata shortcuts. - # - # @example - # RSpec.configure do |config| - # config.alias_example_group_to :describe_model, :type => :model - # end - # - # shared_context_for "model tests", :type => :model do - # # define common model test helper methods, `let` declarations, etc - # end - # - # # This lets you do this: - # - # RSpec.describe_model User do - # end - # - # # ... which is the equivalent of - # - # RSpec.describe User, :type => :model do - # end - # - # @note The defined aliased will also be added to the top level - # (e.g. `main` and from within modules) if - # `expose_dsl_globally` is set to true. - # @see #alias_example_to - # @see #expose_dsl_globally= - def alias_example_group_to(new_name, *args) - extra_options = Metadata.build_hash_from(args) - RSpec::Core::ExampleGroup.define_example_group_method(new_name, extra_options) - end - - # Define an alias for it_should_behave_like that allows different - # language (like "it_has_behavior" or "it_behaves_like") to be - # employed when including shared examples. - # - # @example - # RSpec.configure do |config| - # config.alias_it_behaves_like_to(:it_has_behavior, 'has behavior:') - # end - # - # # allows the user to include a shared example group like: - # - # RSpec.describe Entity do - # it_has_behavior 'sortability' do - # let(:sortable) { Entity.new } - # end - # end - # - # # which is reported in the output as: - # # Entity - # # has behavior: sortability - # # ...sortability examples here - # - # @note Use with caution. This extends the language used in your - # specs, but does not add any additional documentation. We use this - # in RSpec to define `it_should_behave_like` (for backward - # compatibility), but we also add docs for that method. - def alias_it_behaves_like_to(new_name, report_label='') - RSpec::Core::ExampleGroup.define_nested_shared_group_method(new_name, report_label) - end - alias_method :alias_it_should_behave_like_to, :alias_it_behaves_like_to - - # Adds key/value pairs to the `inclusion_filter`. If `args` - # includes any symbols that are not part of the hash, each symbol - # is treated as a key in the hash with the value `true`. - # - # ### Note - # - # Filters set using this method can be overridden from the command line - # or config files (e.g. `.rspec`). - # - # @example - # # Given this declaration. - # describe "something", :foo => 'bar' do - # # ... - # end - # - # # Any of the following will include that group. - # config.filter_run_including :foo => 'bar' - # config.filter_run_including :foo => /^ba/ - # config.filter_run_including :foo => lambda {|v| v == 'bar'} - # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'} - # - # # Given a proc with an arity of 1, the lambda is passed the value - # # related to the key, e.g. - # config.filter_run_including :foo => lambda {|v| v == 'bar'} - # - # # Given a proc with an arity of 2, the lambda is passed the value - # # related to the key, and the metadata itself e.g. - # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'} - # - # filter_run_including :foo # same as filter_run_including :foo => true - def filter_run_including(*args) - meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering) - filter_manager.include_with_low_priority meta - static_config_filter_manager.include_with_low_priority Metadata.deep_hash_dup(meta) - end - alias_method :filter_run, :filter_run_including - - # Applies the provided filter only if any of examples match, in constrast - # to {#filter_run}, which always applies even if no examples match, in - # which case no examples will be run. This allows you to leave configured - # filters in place that are intended only for temporary use. The most common - # example is focus filtering: `config.filter_run_when_matching :focus`. - # With that configured, you can temporarily focus an example or group - # by tagging it with `:focus` metadata, or prefixing it with an `f` - # (as in `fdescribe`, `fcontext` and `fit`) since those are aliases for - # `describe`/`context`/`it` with `:focus` metadata. - def filter_run_when_matching(*args) - when_first_matching_example_defined(*args) do - filter_run(*args) - end - end - - # Clears and reassigns the `inclusion_filter`. Set to `nil` if you don't - # want any inclusion filter at all. - # - # ### Warning - # - # This overrides any inclusion filters/tags set on the command line or in - # configuration files. - def inclusion_filter=(filter) - meta = Metadata.build_hash_from([filter], :warn_about_example_group_filtering) - filter_manager.include_only meta - end - - alias_method :filter=, :inclusion_filter= - - # Returns the `inclusion_filter`. If none has been set, returns an empty - # hash. - def inclusion_filter - filter_manager.inclusions - end - - alias_method :filter, :inclusion_filter - - # Adds key/value pairs to the `exclusion_filter`. If `args` - # includes any symbols that are not part of the hash, each symbol - # is treated as a key in the hash with the value `true`. - # - # ### Note - # - # Filters set using this method can be overridden from the command line - # or config files (e.g. `.rspec`). - # - # @example - # # Given this declaration. - # describe "something", :foo => 'bar' do - # # ... - # end - # - # # Any of the following will exclude that group. - # config.filter_run_excluding :foo => 'bar' - # config.filter_run_excluding :foo => /^ba/ - # config.filter_run_excluding :foo => lambda {|v| v == 'bar'} - # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'} - # - # # Given a proc with an arity of 1, the lambda is passed the value - # # related to the key, e.g. - # config.filter_run_excluding :foo => lambda {|v| v == 'bar'} - # - # # Given a proc with an arity of 2, the lambda is passed the value - # # related to the key, and the metadata itself e.g. - # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'} - # - # filter_run_excluding :foo # same as filter_run_excluding :foo => true - def filter_run_excluding(*args) - meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering) - filter_manager.exclude_with_low_priority meta - static_config_filter_manager.exclude_with_low_priority Metadata.deep_hash_dup(meta) - end - - # Clears and reassigns the `exclusion_filter`. Set to `nil` if you don't - # want any exclusion filter at all. - # - # ### Warning - # - # This overrides any exclusion filters/tags set on the command line or in - # configuration files. - def exclusion_filter=(filter) - meta = Metadata.build_hash_from([filter], :warn_about_example_group_filtering) - filter_manager.exclude_only meta - end - - # Returns the `exclusion_filter`. If none has been set, returns an empty - # hash. - def exclusion_filter - filter_manager.exclusions - end - - # Tells RSpec to include `mod` in example groups. Methods defined in - # `mod` are exposed to examples (not example groups). Use `filters` to - # constrain the groups or examples in which to include the module. - # - # @example - # - # module AuthenticationHelpers - # def login_as(user) - # # ... - # end - # end - # - # module PreferencesHelpers - # def preferences(user, preferences = {}) - # # ... - # end - # end - # - # module UserHelpers - # def users(username) - # # ... - # end - # end - # - # RSpec.configure do |config| - # config.include(UserHelpers) # included in all groups - # - # # included in examples with `:preferences` metadata - # config.include(PreferenceHelpers, :preferences) - # - # # included in examples with `:type => :request` metadata - # config.include(AuthenticationHelpers, :type => :request) - # - # # included in examples where the `:type` metadata matches a proc condition - # config.include(AuthenticationHelpers, :type => proc { |type, _metadata| [:request, :controller].include?(type) }) - # end - # - # describe "edit profile", :preferences, :type => :request do - # it "can be viewed by owning user" do - # login_as preferences(users(:jdoe), :lang => 'es') - # get "/profiles/jdoe" - # assert_select ".username", :text => 'jdoe' - # end - # end - # - # @note Filtered module inclusions can also be applied to - # individual examples that have matching metadata. Just like - # Ruby's object model is that every object has a singleton class - # which has only a single instance, RSpec's model is that every - # example has a singleton example group containing just the one - # example. - # - # @see #include_context - # @see #extend - # @see #prepend - def include(mod, *filters) - define_mixed_in_module(mod, filters, @include_modules, :include) do |group| - safe_include(mod, group) - end - end - - # Tells RSpec to include the named shared example group in example groups. - # Use `filters` to constrain the groups or examples in which to include - # the example group. - # - # @example - # - # RSpec.shared_context "example admin user" do - # let(:admin_user) { create_user(:admin) } - # end - # - # RSpec.shared_context "example guest user" do - # let(:guest_user) { create_user(:guest) } - # end - # - # RSpec.configure do |config| - # config.include_context "example guest user", :type => :request - # config.include_context "example admin user", :admin, :type => :request - # end - # - # RSpec.describe "The admin page", :type => :request do - # it "can be viewed by admins", :admin do - # login_with admin_user - # get "/admin" - # expect(response).to be_ok - # end - # - # it "cannot be viewed by guests" do - # login_with guest_user - # get "/admin" - # expect(response).to be_forbidden - # end - # end - # - # @note Filtered context inclusions can also be applied to - # individual examples that have matching metadata. Just like - # Ruby's object model is that every object has a singleton class - # which has only a single instance, RSpec's model is that every - # example has a singleton example group containing just the one - # example. - # - # @see #include - def include_context(shared_group_name, *filters) - shared_module = world.shared_example_group_registry.find([:main], shared_group_name) - include shared_module, *filters - end - - # Tells RSpec to extend example groups with `mod`. Methods defined in - # `mod` are exposed to example groups (not examples). Use `filters` to - # constrain the groups to extend. - # - # Similar to `include`, but behavior is added to example groups, which - # are classes, rather than the examples, which are instances of those - # classes. - # - # @example - # - # module UiHelpers - # def run_in_browser - # # ... - # end - # end - # - # module PermissionHelpers - # def define_permissions - # # ... - # end - # end - # - # RSpec.configure do |config| - # config.extend(UiHelpers, :type => :request) - # config.extend(PermissionHelpers, :with_permissions, :type => :request) - # end - # - # describe "edit profile", :with_permissions, :type => :request do - # run_in_browser - # define_permissions - # - # it "does stuff in the client" do - # # ... - # end - # end - # - # @see #include - # @see #prepend - def extend(mod, *filters) - define_mixed_in_module(mod, filters, @extend_modules, :extend) do |group| - safe_extend(mod, group) - end - end - - if RSpec::Support::RubyFeatures.module_prepends_supported? - # Tells RSpec to prepend example groups with `mod`. Methods defined in - # `mod` are exposed to examples (not example groups). Use `filters` to - # constrain the groups in which to prepend the module. - # - # Similar to `include`, but module is included before the example group's class - # in the ancestor chain. - # - # @example - # - # module OverrideMod - # def override_me - # "overridden" - # end - # end - # - # RSpec.configure do |config| - # config.prepend(OverrideMod, :method => :prepend) - # end - # - # describe "overriding example's class", :method => :prepend do - # it "finds the user" do - # self.class.class_eval do - # def override_me - # end - # end - # override_me # => "overridden" - # # ... - # end - # end - # - # @see #include - # @see #extend - def prepend(mod, *filters) - define_mixed_in_module(mod, filters, @prepend_modules, :prepend) do |group| - safe_prepend(mod, group) - end - end - end - - # @private - # - # Used internally to extend a group with modules using `include`, `prepend` and/or - # `extend`. - def configure_group(group) - group.hooks.register_globals(group, hooks) - - configure_group_with group, @include_modules, :safe_include - configure_group_with group, @extend_modules, :safe_extend - configure_group_with group, @prepend_modules, :safe_prepend - end - - # @private - # - # Used internally to extend the singleton class of a single example's - # example group instance with modules using `include` and/or `extend`. - def configure_example(example, example_hooks) - example_hooks.register_global_singleton_context_hooks(example, hooks) - singleton_group = example.example_group_instance.singleton_class - - # We replace the metadata so that SharedExampleGroupModule#included - # has access to the example's metadata[:location]. - singleton_group.with_replaced_metadata(example.metadata) do - modules = @include_modules.items_for(example.metadata) - modules.each do |mod| - safe_include(mod, example.example_group_instance.singleton_class) - end - - MemoizedHelpers.define_helpers_on(singleton_group) unless modules.empty? - end - end - - # @private - def requires=(paths) - directories = ['lib', default_path].select { |p| File.directory? p } - RSpec::Core::RubyProject.add_to_load_path(*directories) - paths.each { |path| - load_file_handling_errors(:require, path) - @requires << path - } - end - - # @private - def in_project_source_dir_regex - regexes = project_source_dirs.map do |dir| - /\A#{Regexp.escape(File.expand_path(dir))}\// - end - - Regexp.union(regexes) - end - - # @private - def configure_mock_framework - RSpec::Core::ExampleGroup.__send__(:include, mock_framework) - conditionally_disable_mocks_monkey_patching - end - - # @private - def configure_expectation_framework - expectation_frameworks.each do |framework| - RSpec::Core::ExampleGroup.__send__(:include, framework) - end - conditionally_disable_expectations_monkey_patching - end - - # @private - def load_spec_files - # Note which spec files world is already aware of. - # This is generally only needed for when the user runs - # `ruby path/to/spec.rb` (and loads `rspec/autorun`) -- - # in that case, the spec file was loaded by `ruby` and - # isn't loaded by us here so we only know about it because - # of an example group being registered in it. - world.registered_example_group_files.each do |f| - loaded_spec_files << f # the registered files are already expended absolute paths - end - - files_to_run.uniq.each do |f| - file = File.expand_path(f) - load_file_handling_errors(:load, file) - loaded_spec_files << file - end - - @spec_files_loaded = true - end - - # @private - DEFAULT_FORMATTER = lambda { |string| string } - - # Formats the docstring output using the block provided. - # - # @example - # # This will strip the descriptions of both examples and example - # # groups. - # RSpec.configure do |config| - # config.format_docstrings { |s| s.strip } - # end - def format_docstrings(&block) - @format_docstrings_block = block_given? ? block : DEFAULT_FORMATTER - end - - # @private - def format_docstrings_block - @format_docstrings_block ||= DEFAULT_FORMATTER - end - - # @private - def self.delegate_to_ordering_manager(*methods) - methods.each do |method| - define_method method do |*args, &block| - ordering_manager.__send__(method, *args, &block) - end - end - end - - # @!method seed=(value) - # - # Sets the seed value and sets the default global ordering to random. - delegate_to_ordering_manager :seed= - - # @!method seed - # Seed for random ordering (default: generated randomly each run). - # - # When you run specs with `--order random`, RSpec generates a random seed - # for the randomization and prints it to the `output_stream` (assuming - # you're using RSpec's built-in formatters). If you discover an ordering - # dependency (i.e. examples fail intermittently depending on order), set - # this (on Configuration or on the command line with `--seed`) to run - # using the same seed while you debug the issue. - # - # We recommend, actually, that you use the command line approach so you - # don't accidentally leave the seed encoded. - delegate_to_ordering_manager :seed - - # @!method order=(value) - # - # Sets the default global ordering strategy. By default this can be one - # of `:defined`, `:random`, but is customizable through the - # `register_ordering` API. If order is set to `'rand:'`, - # the seed will also be set. - # - # @see #register_ordering - delegate_to_ordering_manager :order= - - # @!method register_ordering(name) - # - # Registers a named ordering strategy that can later be - # used to order an example group's subgroups by adding - # `:order => ` metadata to the example group. - # - # @param name [Symbol] The name of the ordering. - # @yield Block that will order the given examples or example groups - # @yieldparam list [Array, - # Array] The examples or groups to order - # @yieldreturn [Array, - # Array] The re-ordered examples or groups - # - # @example - # RSpec.configure do |rspec| - # rspec.register_ordering :reverse do |list| - # list.reverse - # end - # end - # - # RSpec.describe 'MyClass', :order => :reverse do - # # ... - # end - # - # @note Pass the symbol `:global` to set the ordering strategy that - # will be used to order the top-level example groups and any example - # groups that do not have declared `:order` metadata. - # - # @example - # RSpec.configure do |rspec| - # rspec.register_ordering :global do |examples| - # acceptance, other = examples.partition do |example| - # example.metadata[:type] == :acceptance - # end - # other + acceptance - # end - # end - # - # RSpec.describe 'MyClass', :type => :acceptance do - # # will run last - # end - # - # RSpec.describe 'MyClass' do - # # will run first - # end - # - delegate_to_ordering_manager :register_ordering - - # @private - delegate_to_ordering_manager :seed_used?, :ordering_registry - - # Set Ruby warnings on or off. - def warnings=(value) - $VERBOSE = !!value - end - - # @return [Boolean] Whether or not ruby warnings are enabled. - def warnings? - $VERBOSE - end - - # @private - RAISE_ERROR_WARNING_NOTIFIER = lambda { |message| raise message } - - # Turns RSpec warnings into errors. This can be useful when - # you want RSpec to run in a 'strict' no warning situation. - # (Note this does not capture or raise on Ruby warnings). - # - # @example - # - # RSpec.configure do |rspec| - # rspec.raise_on_warning = true - # end - def raise_on_warning=(value) - if value - RSpec::Support.warning_notifier = RAISE_ERROR_WARNING_NOTIFIER - else - RSpec::Support.warning_notifier = RSpec::Support::DEFAULT_WARNING_NOTIFIER - end - end - - # Exposes the current running example via the named - # helper method. RSpec 2.x exposed this via `example`, - # but in RSpec 3.0, the example is instead exposed via - # an arg yielded to `it`, `before`, `let`, etc. However, - # some extension gems (such as Capybara) depend on the - # RSpec 2.x's `example` method, so this config option - # can be used to maintain compatibility. - # - # @param method_name [Symbol] the name of the helper method - # - # @example - # - # RSpec.configure do |rspec| - # rspec.expose_current_running_example_as :example - # end - # - # RSpec.describe MyClass do - # before do - # # `example` can be used here because of the above config. - # do_something if example.metadata[:type] == "foo" - # end - # end - def expose_current_running_example_as(method_name) - ExposeCurrentExample.module_exec do - extend RSpec::SharedContext - let(method_name) { |ex| ex } - end - - include ExposeCurrentExample - end - - # @private - module ExposeCurrentExample; end - - # Turns deprecation warnings into errors, in order to surface - # the full backtrace of the call site. This can be useful when - # you need more context to address a deprecation than the - # single-line call site normally provided. - # - # @example - # - # RSpec.configure do |rspec| - # rspec.raise_errors_for_deprecations! - # end - def raise_errors_for_deprecations! - self.deprecation_stream = Formatters::DeprecationFormatter::RaiseErrorStream.new - end - - # Enables zero monkey patching mode for RSpec. It removes monkey - # patching of the top-level DSL methods (`describe`, - # `shared_examples_for`, etc) onto `main` and `Module`, instead - # requiring you to prefix these methods with `RSpec.`. It enables - # expect-only syntax for rspec-mocks and rspec-expectations. It - # simply disables monkey patching on whatever pieces of RSpec - # the user is using. - # - # @note It configures rspec-mocks and rspec-expectations only - # if the user is using those (either explicitly or implicitly - # by not setting `mock_with` or `expect_with` to anything else). - # - # @note If the user uses this options with `mock_with :mocha` - # (or similar) they will still have monkey patching active - # in their test environment from mocha. - # - # @example - # - # # It disables all monkey patching. - # RSpec.configure do |config| - # config.disable_monkey_patching! - # end - # - # # Is an equivalent to - # RSpec.configure do |config| - # config.expose_dsl_globally = false - # - # config.mock_with :rspec do |mocks| - # mocks.syntax = :expect - # mocks.patch_marshal_to_support_partial_doubles = false - # end - # - # config.expect_with :rspec do |expectations| - # expectations.syntax = :expect - # end - # end - def disable_monkey_patching! - self.expose_dsl_globally = false - self.disable_monkey_patching = true - conditionally_disable_mocks_monkey_patching - conditionally_disable_expectations_monkey_patching - end - - # @private - attr_accessor :disable_monkey_patching - - # Defines a callback that can assign derived metadata values. - # - # @param filters [Array, Hash] metadata filters that determine - # which example or group metadata hashes the callback will be triggered - # for. If none are given, the callback will be run against the metadata - # hashes of all groups and examples. - # @yieldparam metadata [Hash] original metadata hash from an example or - # group. Mutate this in your block as needed. - # - # @example - # RSpec.configure do |config| - # # Tag all groups and examples in the spec/unit directory with - # # :type => :unit - # config.define_derived_metadata(:file_path => %r{/spec/unit/}) do |metadata| - # metadata[:type] = :unit - # end - # end - def define_derived_metadata(*filters, &block) - meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering) - @derived_metadata_blocks.append(block, meta) - end - - # Defines a callback that runs after the first example with matching - # metadata is defined. If no examples are defined with matching metadata, - # it will not get called at all. - # - # This can be used to ensure some setup is performed (such as bootstrapping - # a DB or loading a specific file that adds significantly to the boot time) - # if needed (as indicated by the presence of an example with matching metadata) - # but avoided otherwise. - # - # @example - # RSpec.configure do |config| - # config.when_first_matching_example_defined(:db) do - # # Load a support file that does some heavyweight setup, - # # including bootstrapping the DB, but only if we have loaded - # # any examples tagged with `:db`. - # require 'support/db' - # end - # end - def when_first_matching_example_defined(*filters) - specified_meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering) - - callback = lambda do |example_or_group_meta| - # Example groups do not have `:example_group` metadata - # (instead they have `:parent_example_group` metadata). - return unless example_or_group_meta.key?(:example_group) - - # Ensure the callback only fires once. - @derived_metadata_blocks.delete(callback, specified_meta) - - yield - end - - @derived_metadata_blocks.append(callback, specified_meta) - end - - # @private - def apply_derived_metadata_to(metadata) - already_run_blocks = Set.new - - # We loop and attempt to re-apply metadata blocks to support cascades - # (e.g. where a derived bit of metadata triggers the application of - # another piece of derived metadata, etc) - # - # We limit our looping to 200 times as a way to detect infinitely recursing derived metadata blocks. - # It's hard to imagine a valid use case for a derived metadata cascade greater than 200 iterations. - 200.times do - return if @derived_metadata_blocks.items_for(metadata).all? do |block| - already_run_blocks.include?(block).tap do |skip_block| - block.call(metadata) unless skip_block - already_run_blocks << block - end - end - end - - # If we got here, then `@derived_metadata_blocks.items_for(metadata).all?` never returned - # `true` above and we treat this as an attempt to recurse infinitely. It's better to fail - # with a clear # error than hang indefinitely, which is what would happen if we didn't limit - # the looping above. - raise SystemStackError, "Attempted to recursively derive metadata indefinitely." - end - - # Defines a `before` hook. See {Hooks#before} for full docs. - # - # This method differs from {Hooks#before} in only one way: it supports - # the `:suite` scope. Hooks with the `:suite` scope will be run once before - # the first example of the entire suite is executed. Conditions passed along - # with `:suite` are effectively ignored. - # - # @see #prepend_before - # @see #after - # @see #append_after - def before(scope=nil, *meta, &block) - handle_suite_hook(scope, meta) do - @before_suite_hooks << Hooks::BeforeHook.new(block, {}) - end || begin - # defeat Ruby 2.5 lazy proc allocation to ensure - # the methods below are passed the same proc instances - # so `Hook` equality is preserved. For more info, see: - # https://bugs.ruby-lang.org/issues/14045#note-5 - block.__id__ - - add_hook_to_existing_matching_groups(meta, scope) { |g| g.before(scope, *meta, &block) } - super(scope, *meta, &block) - end - end - alias_method :append_before, :before - - # Adds `block` to the start of the list of `before` blocks in the same - # scope (`:example`, `:context`, or `:suite`), in contrast to {#before}, - # which adds the hook to the end of the list. - # - # See {Hooks#before} for full `before` hook docs. - # - # This method differs from {Hooks#prepend_before} in only one way: it supports - # the `:suite` scope. Hooks with the `:suite` scope will be run once before - # the first example of the entire suite is executed. Conditions passed along - # with `:suite` are effectively ignored. - # - # @see #before - # @see #after - # @see #append_after - def prepend_before(scope=nil, *meta, &block) - handle_suite_hook(scope, meta) do - @before_suite_hooks.unshift Hooks::BeforeHook.new(block, {}) - end || begin - # defeat Ruby 2.5 lazy proc allocation to ensure - # the methods below are passed the same proc instances - # so `Hook` equality is preserved. For more info, see: - # https://bugs.ruby-lang.org/issues/14045#note-5 - block.__id__ - - add_hook_to_existing_matching_groups(meta, scope) { |g| g.prepend_before(scope, *meta, &block) } - super(scope, *meta, &block) - end - end - - # Defines a `after` hook. See {Hooks#after} for full docs. - # - # This method differs from {Hooks#after} in only one way: it supports - # the `:suite` scope. Hooks with the `:suite` scope will be run once after - # the last example of the entire suite is executed. Conditions passed along - # with `:suite` are effectively ignored. - # - # @see #append_after - # @see #before - # @see #prepend_before - def after(scope=nil, *meta, &block) - handle_suite_hook(scope, meta) do - @after_suite_hooks.unshift Hooks::AfterHook.new(block, {}) - end || begin - # defeat Ruby 2.5 lazy proc allocation to ensure - # the methods below are passed the same proc instances - # so `Hook` equality is preserved. For more info, see: - # https://bugs.ruby-lang.org/issues/14045#note-5 - block.__id__ - - add_hook_to_existing_matching_groups(meta, scope) { |g| g.after(scope, *meta, &block) } - super(scope, *meta, &block) - end - end - alias_method :prepend_after, :after - - # Adds `block` to the end of the list of `after` blocks in the same - # scope (`:example`, `:context`, or `:suite`), in contrast to {#after}, - # which adds the hook to the start of the list. - # - # See {Hooks#after} for full `after` hook docs. - # - # This method differs from {Hooks#append_after} in only one way: it supports - # the `:suite` scope. Hooks with the `:suite` scope will be run once after - # the last example of the entire suite is executed. Conditions passed along - # with `:suite` are effectively ignored. - # - # @see #append_after - # @see #before - # @see #prepend_before - def append_after(scope=nil, *meta, &block) - handle_suite_hook(scope, meta) do - @after_suite_hooks << Hooks::AfterHook.new(block, {}) - end || begin - # defeat Ruby 2.5 lazy proc allocation to ensure - # the methods below are passed the same proc instances - # so `Hook` equality is preserved. For more info, see: - # https://bugs.ruby-lang.org/issues/14045#note-5 - block.__id__ - - add_hook_to_existing_matching_groups(meta, scope) { |g| g.append_after(scope, *meta, &block) } - super(scope, *meta, &block) - end - end - - # Registers `block` as an `around` hook. - # - # See {Hooks#around} for full `around` hook docs. - def around(scope=nil, *meta, &block) - # defeat Ruby 2.5 lazy proc allocation to ensure - # the methods below are passed the same proc instances - # so `Hook` equality is preserved. For more info, see: - # https://bugs.ruby-lang.org/issues/14045#note-5 - block.__id__ - - add_hook_to_existing_matching_groups(meta, scope) { |g| g.around(scope, *meta, &block) } - super(scope, *meta, &block) - end - - # @private - def with_suite_hooks - return yield if dry_run? - - begin - RSpec.current_scope = :before_suite_hook - run_suite_hooks("a `before(:suite)` hook", @before_suite_hooks) - yield - ensure - RSpec.current_scope = :after_suite_hook - run_suite_hooks("an `after(:suite)` hook", @after_suite_hooks) - RSpec.current_scope = :suite - end - end - - # @private - # Holds the various registered hooks. Here we use a FilterableItemRepository - # implementation that is specifically optimized for the read/write patterns - # of the config object. - def hooks - @hooks ||= HookCollections.new(self, FilterableItemRepository::QueryOptimized) - end - - # Invokes block before defining an example group - def on_example_group_definition(&block) - on_example_group_definition_callbacks << block - end - - # @api private - # Returns an array of blocks to call before defining an example group - def on_example_group_definition_callbacks - @on_example_group_definition_callbacks ||= [] - end - - # @private - def bisect_runner_class - @bisect_runner_class ||= begin - case bisect_runner - when :fork - RSpec::Support.require_rspec_core 'bisect/fork_runner' - Bisect::ForkRunner - when :shell - RSpec::Support.require_rspec_core 'bisect/shell_runner' - Bisect::ShellRunner - else - raise "Unsupported value for `bisect_runner` (#{bisect_runner.inspect}). " \ - "Only `:fork` and `:shell` are supported." - end - end - end - - private - - def load_file_handling_errors(method, file) - __send__(method, file) - rescue LoadError => ex - relative_file = Metadata.relative_path(file) - suggestions = DidYouMean.new(relative_file).call - reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.#{suggestions}") - RSpec.world.wants_to_quit = true - rescue SyntaxError => ex - relative_file = Metadata.relative_path(file) - reporter.notify_non_example_exception( - ex, - "While loading #{relative_file} a `raise SyntaxError` occurred, RSpec will now quit." - ) - RSpec.world.rspec_is_quitting = true - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex - relative_file = Metadata.relative_path(file) - reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.") - RSpec.world.wants_to_quit = true - rescue SystemExit => ex - relative_file = Metadata.relative_path(file) - reporter.notify_non_example_exception( - ex, - "While loading #{relative_file} an `exit` / `raise SystemExit` occurred, RSpec will now quit." - ) - RSpec.world.rspec_is_quitting = true - raise ex - end - - def handle_suite_hook(scope, meta) - return nil unless scope == :suite - - unless meta.empty? - # TODO: in RSpec 4, consider raising an error here. - # We warn only for backwards compatibility. - RSpec.warn_with "WARNING: `:suite` hooks do not support metadata since " \ - "they apply to the suite as a whole rather than " \ - "any individual example or example group that has metadata. " \ - "The metadata you have provided (#{meta.inspect}) will be ignored." - end - - yield - end - - def run_suite_hooks(hook_description, hooks) - context = SuiteHookContext.new(hook_description, reporter) - - hooks.each do |hook| - begin - hook.run(context) - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex - context.set_exception(ex) - - # Do not run subsequent `before` hooks if one fails. - # But for `after` hooks, we run them all so that all - # cleanup bits get a chance to complete, minimizing the - # chance that resources get left behind. - break if hooks.equal?(@before_suite_hooks) - end - end - end - - def get_files_to_run(paths) - files = FlatMap.flat_map(paths_to_check(paths)) do |path| - path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR - File.directory?(path) ? gather_directories(path) : extract_location(path) - end.uniq - - return files unless only_failures? - relative_files = files.map { |f| Metadata.relative_path(File.expand_path f) } - intersection = (relative_files & spec_files_with_failures.to_a) - intersection.empty? ? files : intersection - end - - def paths_to_check(paths) - return paths if pattern_might_load_specs_from_vendored_dirs? - paths + [Dir.getwd] - end - - def pattern_might_load_specs_from_vendored_dirs? - pattern.split(File::SEPARATOR).first.include?('**') - end - - def gather_directories(path) - include_files = get_matching_files(path, pattern) - exclude_files = get_matching_files(path, exclude_pattern) - (include_files - exclude_files).uniq - end - - def get_matching_files(path, pattern) - raw_files = Dir[file_glob_from(path, pattern)] - raw_files.map { |file| File.expand_path(file) }.sort - end - - def file_glob_from(path, pattern) - stripped = "{#{pattern.gsub(/\s*,\s*/, ',')}}" - return stripped if pattern =~ /^(\.\/)?#{Regexp.escape path}/ || absolute_pattern?(pattern) - File.join(path, stripped) - end - - if RSpec::Support::OS.windows? - # :nocov: - def absolute_pattern?(pattern) - pattern =~ /\A[A-Z]:\\/ || windows_absolute_network_path?(pattern) - end - - def windows_absolute_network_path?(pattern) - return false unless ::File::ALT_SEPARATOR - pattern.start_with?(::File::ALT_SEPARATOR + ::File::ALT_SEPARATOR) - end - # :nocov: - else - def absolute_pattern?(pattern) - pattern.start_with?(File::Separator) - end - end - - def extract_location(path) - match = /^(.*?)((?:\:\d+)+)$/.match(path) - - if match - captures = match.captures - path = captures[0] - lines = captures[1][1..-1].split(":").map(&:to_i) - filter_manager.add_location path, lines - else - path, scoped_ids = Example.parse_id(path) - filter_manager.add_ids(path, scoped_ids.split(/\s*,\s*/)) if scoped_ids - end - - return [] if path == default_path - File.expand_path(path) - end - - def command - $0.split(File::SEPARATOR).last - end - - def value_for(key) - @preferred_options.fetch(key) { yield } - end - - def define_built_in_hooks - around(:example, :aggregate_failures => true) do |procsy| - begin - aggregate_failures(nil, :hide_backtrace => true, &procsy) - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => exception - procsy.example.set_aggregate_failures_exception(exception) - end - end - end - - def assert_no_example_groups_defined(config_option) - return unless world.example_groups.any? - - raise MustBeConfiguredBeforeExampleGroupsError.new( - "RSpec's #{config_option} configuration option must be configured before " \ - "any example groups are defined, but you have already defined a group." - ) - end - - def output_wrapper - @output_wrapper ||= OutputWrapper.new(output_stream) - end - - def output_to_tty?(output=output_stream) - output.respond_to?(:tty?) && output.tty? - end - - def conditionally_disable_mocks_monkey_patching - return unless disable_monkey_patching && rspec_mocks_loaded? - - RSpec::Mocks.configuration.tap do |config| - config.syntax = :expect - config.patch_marshal_to_support_partial_doubles = false - end - end - - def conditionally_disable_expectations_monkey_patching - return unless disable_monkey_patching && rspec_expectations_loaded? - - RSpec::Expectations.configuration.syntax = :expect - end - - def rspec_mocks_loaded? - defined?(RSpec::Mocks.configuration) - end - - def rspec_expectations_loaded? - defined?(RSpec::Expectations.configuration) - end - - def update_pattern_attr(name, value) - if @spec_files_loaded - RSpec.warning "Configuring `#{name}` to #{value} has no effect since " \ - "RSpec has already loaded the spec files." - end - - instance_variable_set(:"@#{name}", value) - @files_to_run = nil - end - - def clear_values_derived_from_example_status_persistence_file_path - @last_run_statuses = nil - @spec_files_with_failures = nil - end - - def configure_group_with(group, module_list, application_method) - module_list.items_for(group.metadata).each do |mod| - __send__(application_method, mod, group) - end - end - - def add_hook_to_existing_matching_groups(meta, scope, &block) - # For example hooks, we have to apply it to each of the top level - # groups, even if the groups do not match. When we apply it, we - # apply it with the metadata, so it will only apply to examples - # in the group that match the metadata. - # #2280 for background and discussion. - if scope == :example || scope == :each || scope.nil? - world.example_groups.each(&block) - else - meta = Metadata.build_hash_from(meta.dup) - on_existing_matching_groups(meta, &block) - end - end - - def on_existing_matching_groups(meta) - world.traverse_example_group_trees_until do |group| - metadata_applies_to_group?(meta, group).tap do |applies| - yield group if applies - end - end - end - - def metadata_applies_to_group?(meta, group) - meta.empty? || MetadataFilter.apply?(:any?, meta, group.metadata) - end - - if RSpec::Support::RubyFeatures.module_prepends_supported? - def safe_prepend(mod, host) - host.__send__(:prepend, mod) unless host < mod - end - end - - if RUBY_VERSION.to_f >= 1.9 - def safe_include(mod, host) - host.__send__(:include, mod) unless host < mod - end - - def safe_extend(mod, host) - host.extend(mod) unless host.singleton_class < mod - end - else # for 1.8.7 - # :nocov: - def safe_include(mod, host) - host.__send__(:include, mod) unless host.included_modules.include?(mod) - end - - def safe_extend(mod, host) - host.extend(mod) unless (class << host; self; end).included_modules.include?(mod) - end - # :nocov: - end - - def define_mixed_in_module(mod, filters, mod_list, config_method, &block) - unless Module === mod - raise TypeError, "`RSpec.configuration.#{config_method}` expects a module but got: #{mod.inspect}" - end - - meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering) - mod_list.append(mod, meta) - on_existing_matching_groups(meta, &block) - end - end - # rubocop:enable Metrics/ClassLength - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb deleted file mode 100644 index fcde48f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/configuration_options.rb +++ /dev/null @@ -1,240 +0,0 @@ -require 'erb' -require 'shellwords' - -module RSpec - module Core - # Responsible for utilizing externally provided configuration options, - # whether via the command line, `.rspec`, `~/.rspec`, - # `$XDG_CONFIG_HOME/rspec/options`, `.rspec-local` or a custom options - # file. - class ConfigurationOptions - # @param args [Array] command line arguments - def initialize(args) - @args = args.dup - organize_options - end - - # Updates the provided {Configuration} instance based on the provided - # external configuration options. - # - # @param config [Configuration] the configuration instance to update - def configure(config) - process_options_into config - configure_filter_manager config.filter_manager - load_formatters_into config - end - - # @api private - # Updates the provided {FilterManager} based on the filter options. - # @param filter_manager [FilterManager] instance to update - def configure_filter_manager(filter_manager) - @filter_manager_options.each do |command, value| - filter_manager.__send__ command, value - end - end - - # @return [Hash] the final merged options, drawn from all external sources - attr_reader :options - - # @return [Array] the original command-line arguments - attr_reader :args - - private - - def organize_options - @filter_manager_options = [] - - @options = (file_options << command_line_options << env_options).each do |opts| - @filter_manager_options << [:include, opts.delete(:inclusion_filter)] if opts.key?(:inclusion_filter) - @filter_manager_options << [:exclude, opts.delete(:exclusion_filter)] if opts.key?(:exclusion_filter) - end - - @options = @options.inject(:libs => [], :requires => []) do |hash, opts| - hash.merge(opts) do |key, oldval, newval| - [:libs, :requires].include?(key) ? oldval + newval : newval - end - end - end - - UNFORCED_OPTIONS = Set.new([ - :requires, :profile, :drb, :libs, :files_or_directories_to_run, - :full_description, :full_backtrace, :tty - ]) - - UNPROCESSABLE_OPTIONS = Set.new([:formatters]) - - def force?(key) - !UNFORCED_OPTIONS.include?(key) - end - - def order(keys) - OPTIONS_ORDER.reverse_each do |key| - keys.unshift(key) if keys.delete(key) - end - keys - end - - OPTIONS_ORDER = [ - # It's important to set this before anything that might issue a - # deprecation (or otherwise access the reporter). - :deprecation_stream, - - # In order for `RSpec.configuration.dry_run?` to return `true` during - # processing the `requires` option, it must be parsed before it. - :dry_run, - - # load paths depend on nothing, but must be set before `requires` - # to support load-path-relative requires. - :libs, - - # `files_or_directories_to_run` uses `default_path` so it must be - # set before it. - :default_path, :only_failures, - - # These must be set before `requires` to support checking - # `config.files_to_run` from within `spec_helper.rb` when a - # `-rspec_helper` option is used. - :files_or_directories_to_run, :pattern, :exclude_pattern, - - # Necessary so that the `--seed` option is applied before requires, - # in case required files do something with the provided seed. - # (such as seed global randomization with it). - :order, - - # In general, we want to require the specified files as early as - # possible. The `--require` option is specifically intended to allow - # early requires. For later requires, they can just put the require in - # their spec files, but `--require` provides a unique opportunity for - # users to instruct RSpec to load an extension file early for maximum - # flexibility. - :requires - ] - - def process_options_into(config) - opts = options.reject { |k, _| UNPROCESSABLE_OPTIONS.include? k } - - order(opts.keys).each do |key| - force?(key) ? config.force(key => opts[key]) : config.__send__("#{key}=", opts[key]) - end - end - - def load_formatters_into(config) - options[:formatters].each { |pair| config.add_formatter(*pair) } if options[:formatters] - end - - def file_options - if custom_options_file - [custom_options] - else - [global_options, project_options, local_options] - end - end - - def env_options - return {} unless ENV['SPEC_OPTS'] - - parse_args_ignoring_files_or_dirs_to_run( - Shellwords.split(ENV["SPEC_OPTS"]), - "ENV['SPEC_OPTS']" - ) - end - - def command_line_options - @command_line_options ||= Parser.parse(@args) - end - - def custom_options - options_from(custom_options_file) - end - - def local_options - @local_options ||= options_from(local_options_file) - end - - def project_options - @project_options ||= options_from(project_options_file) - end - - def global_options - @global_options ||= options_from(global_options_file) - end - - def options_from(path) - args = args_from_options_file(path) - parse_args_ignoring_files_or_dirs_to_run(args, path) - end - - def parse_args_ignoring_files_or_dirs_to_run(args, source) - options = Parser.parse(args, source) - options.delete(:files_or_directories_to_run) - options - end - - def args_from_options_file(path) - return [] unless path && File.exist?(path) - config_string = options_file_as_erb_string(path) - config_lines = config_string.split(/\n+/).reject { |s| s =~ /\A\s*#/ } - FlatMap.flat_map(config_lines, &:shellsplit) - end - - # :nocov: - def options_file_as_erb_string(path) - if RUBY_VERSION >= '2.6' - ERB.new(File.read(path), :trim_mode => '-').result(binding) - else - ERB.new(File.read(path), nil, '-').result(binding) - end - end - # :nocov: - - def custom_options_file - command_line_options[:custom_options_file] - end - - def project_options_file - "./.rspec" - end - - def local_options_file - "./.rspec-local" - end - - def global_options_file - xdg_options_file_if_exists || home_options_file_path - end - - def xdg_options_file_if_exists - path = xdg_options_file_path - if path && File.exist?(path) - path - end - end - - def home_options_file_path - File.join(File.expand_path("~"), ".rspec") - rescue ArgumentError - # :nocov: - RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set" - nil - # :nocov: - end - - def xdg_options_file_path - xdg_config_home = resolve_xdg_config_home - if xdg_config_home - File.join(xdg_config_home, "rspec", "options") - end - end - - def resolve_xdg_config_home - File.expand_path(ENV.fetch("XDG_CONFIG_HOME", "~/.config")) - rescue ArgumentError - # :nocov: - # On Ruby 2.4, `File.expand("~")` works even if `ENV['HOME']` is not set. - # But on earlier versions, it fails. - nil - # :nocov: - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb deleted file mode 100644 index 643a869..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/did_you_mean.rb +++ /dev/null @@ -1,52 +0,0 @@ -module RSpec - module Core - # @private - # Wrapper around Ruby's `DidYouMean::SpellChecker` when available to provide file name suggestions. - class DidYouMean - attr_reader :relative_file_name - - def initialize(relative_file_name) - @relative_file_name = relative_file_name - end - - if defined?(::DidYouMean::SpellChecker) - # provide probable suggestions - # :nocov: - not installed on CI - def call - checker = ::DidYouMean::SpellChecker.new(:dictionary => Dir["spec/**/*.rb"]) - probables = checker.correct(relative_file_name.sub('./', ''))[0..2] - return '' unless probables.any? - - formats probables - end - # :nocov: - else - # return a hint if API for ::DidYouMean::SpellChecker not supported - # :nocov: - def call - "\nHint: Install the `did_you_mean` gem in order to provide suggestions for similarly named files." - end - # :nocov: - end - - private - - # :nocov: - def formats(probables) - rspec_format = probables.map { |s, _| "rspec ./#{s}" } - red_font(top_and_tail rspec_format) - end - - def top_and_tail(rspec_format) - spaces = ' ' * 20 - rspec_format.insert(0, ' - Did you mean?').join("\n#{spaces}") + "\n" - end - - def red_font(mytext) - colorizer = ::RSpec::Core::Formatters::ConsoleCodes - colorizer.wrap mytext, :failure - end - # :nocov: - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb deleted file mode 100644 index 31bfbf6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/drb.rb +++ /dev/null @@ -1,120 +0,0 @@ -require 'drb/drb' - -module RSpec - module Core - # @private - class DRbRunner - def initialize(options, configuration=RSpec.configuration) - @options = options - @configuration = configuration - end - - def drb_port - @options.options[:drb_port] || ENV['RSPEC_DRB'] || 8989 - end - - def run(err, out) - begin - DRb.start_service("druby://localhost:0") - rescue SocketError, Errno::EADDRNOTAVAIL - DRb.start_service("druby://:0") - end - spec_server = DRbObject.new_with_uri("druby://127.0.0.1:#{drb_port}") - spec_server.run(drb_argv, err, out) - end - - def drb_argv - @drb_argv ||= begin - @options.configure_filter_manager(@configuration.filter_manager) - DRbOptions.new(@options.options, @configuration.filter_manager).options - end - end - end - - # @private - class DRbOptions - def initialize(submitted_options, filter_manager) - @submitted_options = submitted_options - @filter_manager = filter_manager - end - - def options - argv = [] - argv << "--color" if @submitted_options[:color] - argv << "--force-color" if @submitted_options[:color_mode] == :on - argv << "--no-color" if @submitted_options[:color_mode] == :off - argv << "--profile" if @submitted_options[:profile_examples] - argv << "--backtrace" if @submitted_options[:full_backtrace] - argv << "--tty" if @submitted_options[:tty] - argv << "--fail-fast" if @submitted_options[:fail_fast] - argv << "--options" << @submitted_options[:custom_options_file] if @submitted_options[:custom_options_file] - argv << "--order" << @submitted_options[:order] if @submitted_options[:order] - - add_failure_exit_code(argv) - add_error_exit_code(argv) - add_full_description(argv) - add_filter(argv, :inclusion, @filter_manager.inclusions) - add_filter(argv, :exclusion, @filter_manager.exclusions) - add_formatters(argv) - add_libs(argv) - add_requires(argv) - - argv + @submitted_options[:files_or_directories_to_run] - end - - def add_failure_exit_code(argv) - return unless @submitted_options[:failure_exit_code] - - argv << "--failure-exit-code" << @submitted_options[:failure_exit_code].to_s - end - - def add_error_exit_code(argv) - return unless @submitted_options[:error_exit_code] - - argv << "--error-exit-code" << @submitted_options[:error_exit_code].to_s - end - - def add_full_description(argv) - return unless @submitted_options[:full_description] - - # The argument to --example is regexp-escaped before being stuffed - # into a regexp when received for the first time (see OptionParser). - # Hence, merely grabbing the source of this regexp will retain the - # backslashes, so we must remove them. - @submitted_options[:full_description].each do |description| - argv << "--example" << description.source.delete('\\') - end - end - - CONDITIONAL_FILTERS = [:if, :unless] - - def add_filter(argv, name, hash) - hash.each_pair do |k, v| - next if CONDITIONAL_FILTERS.include?(k) - tag = name == :inclusion ? k.to_s.dup : "~#{k}".dup - tag << ":#{v}" if v.is_a?(String) - argv << "--tag" << tag - end unless hash.empty? - end - - def add_formatters(argv) - @submitted_options[:formatters].each do |pair| - argv << "--format" << pair[0] - argv << "--out" << pair[1] if pair[1] - end if @submitted_options[:formatters] - end - - def add_libs(argv) - @submitted_options[:libs].each do |path| - argv << "-I" << path - end if @submitted_options[:libs] - end - - def add_requires(argv) - @submitted_options[:requires].each do |path| - argv << "--require" << path - end if @submitted_options[:requires] - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb deleted file mode 100644 index 220403e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/dsl.rb +++ /dev/null @@ -1,98 +0,0 @@ -module RSpec - module Core - # DSL defines methods to group examples, most notably `describe`, - # and exposes them as class methods of {RSpec}. They can also be - # exposed globally (on `main` and instances of `Module`) through - # the {Configuration} option `expose_dsl_globally`. - # - # By default the methods `describe`, `context` and `example_group` - # are exposed. These methods define a named context for one or - # more examples. The given block is evaluated in the context of - # a generated subclass of {RSpec::Core::ExampleGroup}. - # - # ## Examples: - # - # RSpec.describe "something" do - # context "when something is a certain way" do - # it "does something" do - # # example code goes here - # end - # end - # end - # - # @see ExampleGroup - # @see ExampleGroup.example_group - module DSL - # @private - def self.example_group_aliases - @example_group_aliases ||= [] - end - - # @private - def self.exposed_globally? - @exposed_globally ||= false - end - - # @private - def self.expose_example_group_alias(name) - return if example_group_aliases.include?(name) - - example_group_aliases << name - - (class << RSpec; self; end).__send__(:define_method, name) do |*args, &example_group_block| - group = RSpec::Core::ExampleGroup.__send__(name, *args, &example_group_block) - RSpec.world.record(group) - group - end - - expose_example_group_alias_globally(name) if exposed_globally? - end - - class << self - # @private - attr_accessor :top_level - end - - # Adds the describe method to Module and the top level binding. - # @api private - def self.expose_globally! - return if exposed_globally? - - example_group_aliases.each do |method_name| - expose_example_group_alias_globally(method_name) - end - - @exposed_globally = true - end - - # Removes the describe method from Module and the top level binding. - # @api private - def self.remove_globally! - return unless exposed_globally? - - example_group_aliases.each do |method_name| - change_global_dsl { undef_method method_name } - end - - @exposed_globally = false - end - - # @private - def self.expose_example_group_alias_globally(method_name) - change_global_dsl do - remove_method(method_name) if method_defined?(method_name) - define_method(method_name) { |*a, &b| ::RSpec.__send__(method_name, *a, &b) } - end - end - - # @private - def self.change_global_dsl(&changes) - (class << top_level; self; end).class_exec(&changes) - Module.class_exec(&changes) - end - end - end -end - -# Capture main without an eval. -::RSpec::Core::DSL.top_level = self diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb deleted file mode 100644 index 1688f51..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example.rb +++ /dev/null @@ -1,666 +0,0 @@ -module RSpec - module Core - # Wrapper for an instance of a subclass of {ExampleGroup}. An instance of - # `RSpec::Core::Example` is returned by example definition methods - # such as {ExampleGroup.it it} and is yielded to the {ExampleGroup.it it}, - # {Hooks#before before}, {Hooks#after after}, {Hooks#around around}, - # {MemoizedHelpers::ClassMethods#let let} and - # {MemoizedHelpers::ClassMethods#subject subject} blocks. - # - # This allows us to provide rich metadata about each individual - # example without adding tons of methods directly to the ExampleGroup - # that users may inadvertently redefine. - # - # Useful for configuring logging and/or taking some action based - # on the state of an example's metadata. - # - # @example - # - # RSpec.configure do |config| - # config.before do |example| - # log example.description - # end - # - # config.after do |example| - # log example.description - # end - # - # config.around do |example| - # log example.description - # example.run - # end - # end - # - # shared_examples "auditable" do - # it "does something" do - # log "#{example.full_description}: #{auditable.inspect}" - # auditable.should do_something - # end - # end - # - # @see ExampleGroup - # @note Example blocks are evaluated in the context of an instance - # of an `ExampleGroup`, not in the context of an instance of `Example`. - class Example - # @private - # - # Used to define methods that delegate to this example's metadata. - def self.delegate_to_metadata(key) - define_method(key) { @metadata[key] } - end - - # @return [ExecutionResult] represents the result of running this example. - delegate_to_metadata :execution_result - # @return [String] the relative path to the file where this example was - # defined. - delegate_to_metadata :file_path - # @return [String] the full description (including the docstrings of - # all parent example groups). - delegate_to_metadata :full_description - # @return [String] the exact source location of this example in a form - # like `./path/to/spec.rb:17` - delegate_to_metadata :location - # @return [Boolean] flag that indicates that the example is not expected - # to pass. It will be run and will either have a pending result (if a - # failure occurs) or a failed result (if no failure occurs). - delegate_to_metadata :pending - # @return [Boolean] flag that will cause the example to not run. - # The {ExecutionResult} status will be `:pending`. - delegate_to_metadata :skip - - # Returns the string submitted to `example` or its aliases (e.g. - # `specify`, `it`, etc). If no string is submitted (e.g. - # `it { is_expected.to do_something }`) it returns the message generated - # by the matcher if there is one, otherwise returns a message including - # the location of the example. - def description - description = if metadata[:description].to_s.empty? - location_description - else - metadata[:description] - end - - RSpec.configuration.format_docstrings_block.call(description) - end - - # Returns a description of the example that always includes the location. - def inspect_output - inspect_output = "\"#{description}\"" - unless metadata[:description].to_s.empty? - inspect_output += " (#{location})" - end - inspect_output - end - - # Returns the location-based argument that can be passed to the `rspec` command to rerun this example. - def location_rerun_argument - @location_rerun_argument ||= begin - loaded_spec_files = RSpec.configuration.loaded_spec_files - - Metadata.ascending(metadata) do |meta| - break meta[:location] if loaded_spec_files.include?(meta[:absolute_file_path]) - end - end - end - - # Returns the location-based argument that can be passed to the `rspec` command to rerun this example. - # - # @deprecated Use {#location_rerun_argument} instead. - # @note If there are multiple examples identified by this location, they will use {#id} - # to rerun instead, but this method will still return the location (that's why it is deprecated!). - def rerun_argument - location_rerun_argument - end - - # @return [String] the unique id of this example. Pass - # this at the command line to re-run this exact example. - def id - @id ||= Metadata.id_from(metadata) - end - - # @private - def self.parse_id(id) - # http://rubular.com/r/OMZSAPcAfn - id.match(/\A(.*?)(?:\[([\d\s:,]+)\])?\z/).captures - end - - # Duplicates the example and overrides metadata with the provided - # hash. - # - # @param metadata_overrides [Hash] the hash to override the example metadata - # @return [Example] a duplicate of the example with modified metadata - def duplicate_with(metadata_overrides={}) - new_metadata = metadata.clone.merge(metadata_overrides) - - RSpec::Core::Metadata::RESERVED_KEYS.each do |reserved_key| - new_metadata.delete reserved_key - end - - # don't clone the example group because the new example - # must belong to the same example group (not a clone). - # - # block is nil in new_metadata so we have to get it from metadata. - Example.new(example_group, description.clone, - new_metadata, metadata[:block]) - end - - # @private - def update_inherited_metadata(updates) - metadata.update(updates) do |_key, existing_example_value, _new_inherited_value| - existing_example_value - end - end - - # @attr_reader - # - # Returns the first exception raised in the context of running this - # example (nil if no exception is raised). - attr_reader :exception - - # @attr_reader - # - # Returns the metadata object associated with this example. - attr_reader :metadata - - # @attr_reader - # @private - # - # Returns the example_group_instance that provides the context for - # running this example. - attr_reader :example_group_instance - - # @attr - # @private - attr_accessor :clock - - # Creates a new instance of Example. - # @param example_group_class [Class] the subclass of ExampleGroup in which - # this Example is declared - # @param description [String] the String passed to the `it` method (or - # alias) - # @param user_metadata [Hash] additional args passed to `it` to be used as - # metadata - # @param example_block [Proc] the block of code that represents the - # example - # @api private - def initialize(example_group_class, description, user_metadata, example_block=nil) - @example_group_class = example_group_class - @example_block = example_block - - # Register the example with the group before creating the metadata hash. - # This is necessary since creating the metadata hash triggers - # `when_first_matching_example_defined` callbacks, in which users can - # load RSpec support code which defines hooks. For that to work, the - # examples and example groups must be registered at the time the - # support code is called or be defined afterwards. - # Begin defined beforehand but registered afterwards causes hooks to - # not be applied where they should. - example_group_class.examples << self - - @metadata = Metadata::ExampleHash.create( - @example_group_class.metadata, user_metadata, - example_group_class.method(:next_runnable_index_for), - description, example_block - ) - - config = RSpec.configuration - config.apply_derived_metadata_to(@metadata) - - # This should perhaps be done in `Metadata::ExampleHash.create`, - # but the logic there has no knowledge of `RSpec.world` and we - # want to keep it that way. It's easier to just assign it here. - @metadata[:last_run_status] = config.last_run_statuses[id] - - @example_group_instance = @exception = nil - @clock = RSpec::Core::Time - @reporter = RSpec::Core::NullReporter - end - - # Provide a human-readable representation of this class - def inspect - "#<#{self.class.name} #{description.inspect}>" - end - alias to_s inspect - - # @return [RSpec::Core::Reporter] the current reporter for the example - attr_reader :reporter - - # Returns the example group class that provides the context for running - # this example. - def example_group - @example_group_class - end - - def pending? - !!pending - end - - def skipped? - !!skip - end - - # @api private - # instance_execs the block passed to the constructor in the context of - # the instance of {ExampleGroup}. - # @param example_group_instance the instance of an ExampleGroup subclass - def run(example_group_instance, reporter) - @example_group_instance = example_group_instance - @reporter = reporter - RSpec.configuration.configure_example(self, hooks) - RSpec.current_example = self - - start(reporter) - Pending.mark_pending!(self, pending) if pending? - - begin - if skipped? - Pending.mark_pending! self, skip - elsif !RSpec.configuration.dry_run? - with_around_and_singleton_context_hooks do - begin - run_before_example - RSpec.current_scope = :example - @example_group_instance.instance_exec(self, &@example_block) - - if pending? - Pending.mark_fixed! self - - raise Pending::PendingExampleFixedError, - 'Expected example to fail since it is pending, but it passed.', - [location] - end - rescue Pending::SkipDeclaredInExample => _ - # The "=> _" is normally useless but on JRuby it is a workaround - # for a bug that prevents us from getting backtraces: - # https://github.com/jruby/jruby/issues/4467 - # - # no-op, required metadata has already been set by the `skip` - # method. - rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e - set_exception(e) - ensure - RSpec.current_scope = :after_example_hook - run_after_example - end - end - end - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e - set_exception(e) - ensure - @example_group_instance = nil # if you love something... let it go - end - - finish(reporter) - ensure - execution_result.ensure_timing_set(clock) - RSpec.current_example = nil - end - - if RSpec::Support::Ruby.jruby? || RUBY_VERSION.to_f < 1.9 - # :nocov: - # For some reason, rescuing `Support::AllExceptionsExceptOnesWeMustNotRescue` - # in place of `Exception` above can cause the exit status to be the wrong - # thing. I have no idea why. See: - # https://github.com/rspec/rspec-core/pull/2063#discussion_r38284978 - # @private - AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt = Exception - # :nocov: - else - # @private - AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt = Support::AllExceptionsExceptOnesWeMustNotRescue - end - - # Wraps both a `Proc` and an {Example} for use in {Hooks#around - # around} hooks. In around hooks we need to yield this special - # kind of object (rather than the raw {Example}) because when - # there are multiple `around` hooks we have to wrap them recursively. - # - # @example - # - # RSpec.configure do |c| - # c.around do |ex| # Procsy which wraps the example - # if ex.metadata[:key] == :some_value && some_global_condition - # raise "some message" - # end - # ex.run # run delegates to ex.call. - # end - # end - # - # @note This class also exposes the instance methods of {Example}, - # proxying them through to the wrapped {Example} instance. - class Procsy - # The {Example} instance. - attr_reader :example - - Example.public_instance_methods(false).each do |name| - name_sym = name.to_sym - next if name_sym == :run || name_sym == :inspect || name_sym == :to_s - - define_method(name) { |*a, &b| @example.__send__(name, *a, &b) } - end - - Proc.public_instance_methods(false).each do |name| - name_sym = name.to_sym - next if name_sym == :call || name_sym == :inspect || name_sym == :to_s || name_sym == :to_proc - - define_method(name) { |*a, &b| @proc.__send__(name, *a, &b) } - end - - # Calls the proc and notes that the example has been executed. - def call(*args, &block) - @executed = true - @proc.call(*args, &block) - end - alias run call - - # Provides a wrapped proc that will update our `executed?` state when - # executed. - def to_proc - method(:call).to_proc - end - - def initialize(example, &block) - @example = example - @proc = block - @executed = false - end - - # @private - def wrap(&block) - self.class.new(example, &block) - end - - # Indicates whether or not the around hook has executed the example. - def executed? - @executed - end - - # @private - def inspect - @example.inspect.gsub('Example', 'Example::Procsy') - end - end - - # @private - # - # The exception that will be displayed to the user -- either the failure of - # the example or the `pending_exception` if the example is pending. - def display_exception - @exception || execution_result.pending_exception - end - - # @private - # - # Assigns the exception that will be displayed to the user -- either the failure of - # the example or the `pending_exception` if the example is pending. - def display_exception=(ex) - if pending? && !(Pending::PendingExampleFixedError === ex) - @exception = nil - execution_result.pending_fixed = false - execution_result.pending_exception = ex - else - @exception = ex - end - end - - # rubocop:disable Naming/AccessorMethodName - - # @private - # - # Used internally to set an exception in an after hook, which - # captures the exception but doesn't raise it. - def set_exception(exception) - return self.display_exception = exception unless display_exception - - unless RSpec::Core::MultipleExceptionError === display_exception - self.display_exception = RSpec::Core::MultipleExceptionError.new(display_exception) - end - - display_exception.add exception - end - - # @private - # - # Used to set the exception when `aggregate_failures` fails. - def set_aggregate_failures_exception(exception) - return set_exception(exception) unless display_exception - - exception = RSpec::Core::MultipleExceptionError::InterfaceTag.for(exception) - exception.add display_exception - self.display_exception = exception - end - - # rubocop:enable Naming/AccessorMethodName - - # @private - # - # Used internally to set an exception and fail without actually executing - # the example when an exception is raised in before(:context). - def fail_with_exception(reporter, exception) - start(reporter) - set_exception(exception) - finish(reporter) - end - - # @private - # - # Used internally to skip without actually executing the example when - # skip is used in before(:context). - def skip_with_exception(reporter, exception) - start(reporter) - Pending.mark_skipped! self, exception.argument - finish(reporter) - end - - # @private - def instance_exec(*args, &block) - @example_group_instance.instance_exec(*args, &block) - end - - private - - def hooks - example_group_instance.singleton_class.hooks - end - - def with_around_example_hooks - RSpec.current_scope = :before_example_hook - hooks.run(:around, :example, self) { yield } - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e - set_exception(e) - end - - def start(reporter) - reporter.example_started(self) - execution_result.started_at = clock.now - end - - def finish(reporter) - pending_message = execution_result.pending_message - - if @exception - execution_result.exception = @exception - record_finished :failed, reporter - reporter.example_failed self - false - elsif pending_message - execution_result.pending_message = pending_message - record_finished :pending, reporter - reporter.example_pending self - true - else - record_finished :passed, reporter - reporter.example_passed self - true - end - end - - def record_finished(status, reporter) - execution_result.record_finished(status, clock.now) - reporter.example_finished(self) - end - - def run_before_example - @example_group_instance.setup_mocks_for_rspec - hooks.run(:before, :example, self) - end - - def with_around_and_singleton_context_hooks - singleton_context_hooks_host = example_group_instance.singleton_class - singleton_context_hooks_host.run_before_context_hooks(example_group_instance) - with_around_example_hooks { yield } - ensure - singleton_context_hooks_host.run_after_context_hooks(example_group_instance) - end - - def run_after_example - assign_generated_description if defined?(::RSpec::Matchers) - hooks.run(:after, :example, self) - verify_mocks - ensure - @example_group_instance.teardown_mocks_for_rspec - end - - def verify_mocks - @example_group_instance.verify_mocks_for_rspec if mocks_need_verification? - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e - set_exception(e) - end - - def mocks_need_verification? - exception.nil? || execution_result.pending_fixed? - end - - def assign_generated_description - if metadata[:description].empty? && (description = generate_description) - metadata[:description] = description - metadata[:full_description] += description - end - ensure - RSpec::Matchers.clear_generated_description - end - - def generate_description - RSpec::Matchers.generated_description - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e - location_description + " (Got an error when generating description " \ - "from matcher: #{e.class}: #{e.message} -- #{e.backtrace.first})" - end - - def location_description - "example at #{location}" - end - - # Represents the result of executing an example. - # Behaves like a hash for backwards compatibility. - class ExecutionResult - include HashImitatable - - # @return [Symbol] `:passed`, `:failed` or `:pending`. - attr_accessor :status - - # @return [Exception, nil] The failure, if there was one. - attr_accessor :exception - - # @return [Time] When the example started. - attr_accessor :started_at - - # @return [Time] When the example finished. - attr_accessor :finished_at - - # @return [Float] How long the example took in seconds. - attr_accessor :run_time - - # @return [String, nil] The reason the example was pending, - # or nil if the example was not pending. - attr_accessor :pending_message - - # @return [Exception, nil] The exception triggered while - # executing the pending example. If no exception was triggered - # it would no longer get a status of `:pending` unless it was - # tagged with `:skip`. - attr_accessor :pending_exception - - # @return [Boolean] For examples tagged with `:pending`, - # this indicates whether or not it now passes. - attr_accessor :pending_fixed - - def pending_fixed? - !!pending_fixed - end - - # @return [Boolean] Indicates if the example was completely skipped - # (typically done via `:skip` metadata or the `skip` method). Skipped examples - # will have a `:pending` result. A `:pending` result can also come from examples - # that were marked as `:pending`, which causes them to be run, and produces a - # `:failed` result if the example passes. - def example_skipped? - status == :pending && !pending_exception - end - - # @api private - # Records the finished status of the example. - def record_finished(status, finished_at) - self.status = status - calculate_run_time(finished_at) - end - - # @api private - # Populates finished_at and run_time if it has not yet been set - def ensure_timing_set(clock) - calculate_run_time(clock.now) unless finished_at - end - - private - - def calculate_run_time(finished_at) - self.finished_at = finished_at - self.run_time = (finished_at - started_at).to_f - end - - # For backwards compatibility we present `status` as a string - # when presenting the legacy hash interface. - def hash_for_delegation - super.tap do |hash| - hash[:status] &&= status.to_s - end - end - - def set_value(name, value) - value &&= value.to_sym if name == :status - super(name, value) - end - - def get_value(name) - if name == :status - status.to_s if status - else - super - end - end - - def issue_deprecation(_method_name, *_args) - RSpec.deprecate("Treating `metadata[:execution_result]` as a hash", - :replacement => "the attributes methods to access the data") - end - end - end - - # @private - # Provides an execution context for before/after :suite hooks. - class SuiteHookContext < Example - def initialize(hook_description, reporter) - super(AnonymousExampleGroup, hook_description, {}) - @example_group_instance = AnonymousExampleGroup.new - @reporter = reporter - end - - # rubocop:disable Naming/AccessorMethodName - def set_exception(exception) - reporter.notify_non_example_exception(exception, "An error occurred in #{description}.") - RSpec.world.wants_to_quit = true - end - # rubocop:enable Naming/AccessorMethodName - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb deleted file mode 100644 index 64fd497..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb +++ /dev/null @@ -1,912 +0,0 @@ -RSpec::Support.require_rspec_support 'recursive_const_methods' - -module RSpec - module Core - # rubocop:disable Metrics/ClassLength - - # ExampleGroup and {Example} are the main structural elements of - # rspec-core. Consider this example: - # - # RSpec.describe Thing do - # it "does something" do - # end - # end - # - # The object returned by `describe Thing` is a subclass of ExampleGroup. - # The object returned by `it "does something"` is an instance of Example, - # which serves as a wrapper for an instance of the ExampleGroup in which it - # is declared. - # - # Example group bodies (e.g. `describe` or `context` blocks) are evaluated - # in the context of a new subclass of ExampleGroup. Individual examples are - # evaluated in the context of an instance of the specific ExampleGroup - # subclass to which they belong. - # - # Besides the class methods defined here, there are other interesting macros - # defined in {Hooks}, {MemoizedHelpers::ClassMethods} and - # {SharedExampleGroup}. There are additional instance methods available to - # your examples defined in {MemoizedHelpers} and {Pending}. - class ExampleGroup - extend Hooks - - include MemoizedHelpers - extend MemoizedHelpers::ClassMethods - include Pending - extend SharedExampleGroup - - # Define a singleton method for the singleton class (remove the method if - # it's already been defined). - # @private - def self.idempotently_define_singleton_method(name, &definition) - (class << self; self; end).module_exec do - remove_method(name) if method_defined?(name) && instance_method(name).owner == self - define_method(name, &definition) - end - end - - # @!group Metadata - - # The [Metadata](Metadata) object associated with this group. - # @see Metadata - def self.metadata - @metadata ||= nil - end - - # Temporarily replace the provided metadata. - # Intended primarily to allow an example group's singleton class - # to return the metadata of the example that it exists for. This - # is necessary for shared example group inclusion to work properly - # with singleton example groups. - # @private - def self.with_replaced_metadata(meta) - orig_metadata = metadata - @metadata = meta - yield - ensure - @metadata = orig_metadata - end - - # @private - # @return [Metadata] belonging to the parent of a nested {ExampleGroup} - def self.superclass_metadata - @superclass_metadata ||= superclass.respond_to?(:metadata) ? superclass.metadata : nil - end - - # @private - def self.delegate_to_metadata(*names) - names.each do |name| - idempotently_define_singleton_method(name) { metadata.fetch(name) } - end - end - - delegate_to_metadata :described_class, :file_path, :location - - # @return [String] the current example group description - def self.description - description = metadata[:description] - RSpec.configuration.format_docstrings_block.call(description) - end - - # Returns the class or module passed to the `describe` method (or alias). - # Returns nil if the subject is not a class or module. - # @example - # RSpec.describe Thing do - # it "does something" do - # described_class == Thing - # end - # end - # - def described_class - self.class.described_class - end - - # @!endgroup - - # @!group Defining Examples - - # @private - # @macro [attach] define_example_method - # @!scope class - # @method $1 - # @overload $1 - # @overload $1(&example_implementation) - # @param example_implementation [Block] The implementation of the example. - # @overload $1(doc_string, *metadata) - # @param doc_string [String] The example's doc string. - # @param metadata [Array, Hash] Metadata for the example. - # Symbols will be transformed into hash entries with `true` values. - # @overload $1(doc_string, *metadata, &example_implementation) - # @param doc_string [String] The example's doc string. - # @param metadata [Array, Hash] Metadata for the example. - # Symbols will be transformed into hash entries with `true` values. - # @param example_implementation [Block] The implementation of the example. - # @yield [Example] the example object - # @example - # $1 do - # end - # - # $1 "does something" do - # end - # - # $1 "does something", :slow, :uses_js do - # end - # - # $1 "does something", :with => 'additional metadata' do - # end - # - # $1 "does something" do |ex| - # # ex is the Example object that contains metadata about the example - # end - # - # @example - # $1 "does something", :slow, :load_factor => 100 do - # end - # - def self.define_example_method(name, extra_options={}) - idempotently_define_singleton_method(name) do |*all_args, &block| - desc, *args = *all_args - - options = Metadata.build_hash_from(args) - options.update(:skip => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block - options.update(extra_options) - - RSpec::Core::Example.new(self, desc, options, block) - end - end - - # Defines an example within a group. - define_example_method :example - # Defines an example within a group. - # This is the primary API to define a code example. - define_example_method :it - # Defines an example within a group. - # Useful for when your docstring does not read well off of `it`. - # @example - # RSpec.describe MyClass do - # specify "#do_something is deprecated" do - # # ... - # end - # end - define_example_method :specify - - # Shortcut to define an example with `:focus => true`. - # @see example - define_example_method :focus, :focus => true - # Shortcut to define an example with `:focus => true`. - # @see example - define_example_method :fexample, :focus => true - # Shortcut to define an example with `:focus => true`. - # @see example - define_example_method :fit, :focus => true - # Shortcut to define an example with `:focus => true`. - # @see example - define_example_method :fspecify, :focus => true - # Shortcut to define an example with `:skip => 'Temporarily skipped with xexample'`. - # @see example - define_example_method :xexample, :skip => 'Temporarily skipped with xexample' - # Shortcut to define an example with `:skip => 'Temporarily skipped with xit'`. - # @see example - define_example_method :xit, :skip => 'Temporarily skipped with xit' - # Shortcut to define an example with `:skip => 'Temporarily skipped with xspecify'`. - # @see example - define_example_method :xspecify, :skip => 'Temporarily skipped with xspecify' - # Shortcut to define an example with `:skip => true` - # @see example - define_example_method :skip, :skip => true - # Shortcut to define an example with `:pending => true` - # @see example - define_example_method :pending, :pending => true - - # @!endgroup - - # @!group Defining Example Groups - - # @private - # @macro [attach] define_example_group_method - # @!scope class - # @method $1 - # @overload $1 - # @overload $1(&example_group_definition) - # @param example_group_definition [Block] The definition of the example group. - # @overload $1(doc_string, *metadata, &example_implementation) - # @param doc_string [String] The group's doc string. - # @param metadata [Array, Hash] Metadata for the group. - # Symbols will be transformed into hash entries with `true` values. - # @param example_group_definition [Block] The definition of the example group. - # @return [RSpec::Core::ExampleGroup] - # - # Generates a subclass of this example group which inherits - # everything except the examples themselves. - # - # @example - # - # RSpec.describe "something" do # << This describe method is defined in - # # << RSpec::Core::DSL, included in the - # # << global namespace (optional) - # before do - # do_something_before - # end - # - # before(:example, :clean_env) do - # env.clear! - # end - # - # let(:thing) { Thing.new } - # - # $1 "attribute (of something)" do - # # examples in the group get the before hook - # # declared above, and can access `thing` - # end - # - # $1 "needs additional setup", :clean_env, :implementation => JSON do - # # specifies that hooks with matching metadata - # # should be be run additionally - # end - # end - # - # @see DSL#describe - def self.define_example_group_method(name, metadata={}) - idempotently_define_singleton_method(name) do |*args, &example_group_block| - thread_data = RSpec::Support.thread_local_data - top_level = self == ExampleGroup - - registration_collection = - if top_level - if thread_data[:in_example_group] - raise "Creating an isolated context from within a context is " \ - "not allowed. Change `RSpec.#{name}` to `#{name}` or " \ - "move this to a top-level scope." - end - - thread_data[:in_example_group] = true - RSpec.world.example_groups - else - children - end - - begin - description = args.shift - combined_metadata = metadata.dup - combined_metadata.merge!(args.pop) if args.last.is_a? Hash - args << combined_metadata - - subclass(self, description, args, registration_collection, &example_group_block) - ensure - thread_data.delete(:in_example_group) if top_level - end - end - - RSpec::Core::DSL.expose_example_group_alias(name) - end - - define_example_group_method :example_group - - # An alias of `example_group`. Generally used when grouping examples by a - # thing you are describing (e.g. an object, class or method). - # @see example_group - define_example_group_method :describe - - # An alias of `example_group`. Generally used when grouping examples - # contextually (e.g. "with xyz", "when xyz" or "if xyz"). - # @see example_group - define_example_group_method :context - - # Shortcut to temporarily make an example group skipped. - # @see example_group - define_example_group_method :xdescribe, :skip => "Temporarily skipped with xdescribe" - - # Shortcut to temporarily make an example group skipped. - # @see example_group - define_example_group_method :xcontext, :skip => "Temporarily skipped with xcontext" - - # Shortcut to define an example group with `:focus => true`. - # @see example_group - define_example_group_method :fdescribe, :focus => true - - # Shortcut to define an example group with `:focus => true`. - # @see example_group - define_example_group_method :fcontext, :focus => true - - # @!endgroup - - # @!group Including Shared Example Groups - - # @private - # @macro [attach] define_nested_shared_group_method - # @!scope class - # @method $1(name, *args, &block) - # @param name [String, Symbol] The name of the shared group to include. - # @param args [Array] Pass parameters to a shared example group - # @param block [Block] Additional context to pass to the shared group. - # @return [RSpec::Core::ExampleGroup] - # - # @see SharedExampleGroup - def self.define_nested_shared_group_method(new_name, report_label="it should behave like") - idempotently_define_singleton_method(new_name) do |name, *args, &customization_block| - # Pass :caller so the :location metadata is set properly. - # Otherwise, it'll be set to the next line because that's - # the block's source_location. - group = example_group("#{report_label} #{name}", :caller => (the_caller = caller)) do - find_and_eval_shared("examples", name, the_caller.first, *args, &customization_block) - end - group.metadata[:shared_group_name] = name - group - end - end - - # Generates a nested example group and includes the shared content - # mapped to `name` in the nested group. - define_nested_shared_group_method :it_behaves_like, "behaves like" - # Generates a nested example group and includes the shared content - # mapped to `name` in the nested group. - define_nested_shared_group_method :it_should_behave_like - - # Includes shared content mapped to `name` directly in the group in which - # it is declared, as opposed to `it_behaves_like`, which creates a nested - # group. If given a block, that block is also eval'd in the current - # context. - # - # @see SharedExampleGroup - def self.include_context(name, *args, &block) - find_and_eval_shared("context", name, caller.first, *args, &block) - end - - # Includes shared content mapped to `name` directly in the group in which - # it is declared, as opposed to `it_behaves_like`, which creates a nested - # group. If given a block, that block is also eval'd in the current - # context. - # - # @see SharedExampleGroup - def self.include_examples(name, *args, &block) - find_and_eval_shared("examples", name, caller.first, *args, &block) - end - - # Clear memoized values when adding/removing examples - # @private - def self.reset_memoized - @descendant_filtered_examples = nil - @_descendants = nil - @parent_groups = nil - @declaration_locations = nil - end - - # Adds an example to the example group - def self.add_example(example) - reset_memoized - examples << example - end - - # Removes an example from the example group - def self.remove_example(example) - reset_memoized - examples.delete example - end - - # @private - def self.find_and_eval_shared(label, name, inclusion_location, *args, &customization_block) - shared_module = RSpec.world.shared_example_group_registry.find(parent_groups, name) - - unless shared_module - raise ArgumentError, "Could not find shared #{label} #{name.inspect}" - end - - shared_module.include_in( - self, Metadata.relative_path(inclusion_location), - args, customization_block - ) - end - - # @!endgroup - - # @private - def self.subclass(parent, description, args, registration_collection, &example_group_block) - subclass = Class.new(parent) - subclass.set_it_up(description, args, registration_collection, &example_group_block) - subclass.module_exec(&example_group_block) if example_group_block - - # The LetDefinitions module must be included _after_ other modules - # to ensure that it takes precedence when there are name collisions. - # Thus, we delay including it until after the example group block - # has been eval'd. - MemoizedHelpers.define_helpers_on(subclass) - - subclass - end - - # @private - def self.set_it_up(description, args, registration_collection, &example_group_block) - # Ruby 1.9 has a bug that can lead to infinite recursion and a - # SystemStackError if you include a module in a superclass after - # including it in a subclass: https://gist.github.com/845896 - # To prevent this, we must include any modules in - # RSpec::Core::ExampleGroup before users create example groups and have - # a chance to include the same module in a subclass of - # RSpec::Core::ExampleGroup. So we need to configure example groups - # here. - ensure_example_groups_are_configured - - # Register the example with the group before creating the metadata hash. - # This is necessary since creating the metadata hash triggers - # `when_first_matching_example_defined` callbacks, in which users can - # load RSpec support code which defines hooks. For that to work, the - # examples and example groups must be registered at the time the - # support code is called or be defined afterwards. - # Begin defined beforehand but registered afterwards causes hooks to - # not be applied where they should. - registration_collection << self - - @user_metadata = Metadata.build_hash_from(args) - - @metadata = Metadata::ExampleGroupHash.create( - superclass_metadata, @user_metadata, - superclass.method(:next_runnable_index_for), - description, *args, &example_group_block - ) - - config = RSpec.configuration - config.apply_derived_metadata_to(@metadata) - - ExampleGroups.assign_const(self) - - @currently_executing_a_context_hook = false - - config.configure_group(self) - end - - # @private - def self.examples - @examples ||= [] - end - - # @private - def self.filtered_examples - RSpec.world.filtered_examples[self] - end - - # @private - def self.descendant_filtered_examples - @descendant_filtered_examples ||= filtered_examples + - FlatMap.flat_map(children, &:descendant_filtered_examples) - end - - # @private - def self.children - @children ||= [] - end - - # @private - # Traverses the tree of groups, starting with `self`, then the children, recursively. - # Halts the traversal of a branch of the tree as soon as the passed block returns true. - # Note that siblings groups and their sub-trees will continue to be explored. - # This is intended to make it easy to find the top-most group that satisfies some - # condition. - def self.traverse_tree_until(&block) - return if yield self - - children.each do |child| - child.traverse_tree_until(&block) - end - end - - # @private - def self.next_runnable_index_for(file) - if self == ExampleGroup - # We add 1 so the ids start at 1 instead of 0. This is - # necessary for this branch (but not for the other one) - # because we register examples and groups with the - # `children` and `examples` collection BEFORE this - # method is called as part of metadata hash creation, - # but the example group is recorded with - # `RSpec.world.example_group_counts_by_spec_file` AFTER - # the metadata hash is created and the group is returned - # to the caller. - RSpec.world.num_example_groups_defined_in(file) + 1 - else - children.count + examples.count - end - end - - # @private - def self.descendants - @_descendants ||= [self] + FlatMap.flat_map(children, &:descendants) - end - - ## @private - def self.parent_groups - @parent_groups ||= ancestors.select { |a| a < RSpec::Core::ExampleGroup } - end - - # @private - def self.top_level? - superclass == ExampleGroup - end - - # @private - def self.ensure_example_groups_are_configured - unless defined?(@@example_groups_configured) - RSpec.configuration.configure_mock_framework - RSpec.configuration.configure_expectation_framework - # rubocop:disable Style/ClassVars - @@example_groups_configured = true - # rubocop:enable Style/ClassVars - end - end - - # @private - def self.before_context_ivars - @before_context_ivars ||= {} - end - - # @private - def self.store_before_context_ivars(example_group_instance) - each_instance_variable_for_example(example_group_instance) do |ivar| - before_context_ivars[ivar] = example_group_instance.instance_variable_get(ivar) - end - end - - # Returns true if a `before(:context)` or `after(:context)` - # hook is currently executing. - def self.currently_executing_a_context_hook? - @currently_executing_a_context_hook - end - - # @private - def self.run_before_context_hooks(example_group_instance) - set_ivars(example_group_instance, superclass_before_context_ivars) - - @currently_executing_a_context_hook = true - - ContextHookMemoized::Before.isolate_for_context_hook(example_group_instance) do - hooks.run(:before, :context, example_group_instance) - end - ensure - store_before_context_ivars(example_group_instance) - @currently_executing_a_context_hook = false - end - - if RUBY_VERSION.to_f >= 1.9 - # @private - def self.superclass_before_context_ivars - superclass.before_context_ivars - end - else # 1.8.7 - # :nocov: - # @private - def self.superclass_before_context_ivars - if superclass.respond_to?(:before_context_ivars) - superclass.before_context_ivars - else - # `self` must be the singleton class of an ExampleGroup instance. - # On 1.8.7, the superclass of a singleton class of an instance of A - # is A's singleton class. On 1.9+, it's A. On 1.8.7, the first ancestor - # is A, so we can mirror 1.8.7's behavior here. Note that we have to - # search for the first that responds to `before_context_ivars` - # in case a module has been included in the singleton class. - ancestors.find { |a| a.respond_to?(:before_context_ivars) }.before_context_ivars - end - end - # :nocov: - end - - # @private - def self.run_after_context_hooks(example_group_instance) - set_ivars(example_group_instance, before_context_ivars) - - @currently_executing_a_context_hook = true - - ContextHookMemoized::After.isolate_for_context_hook(example_group_instance) do - hooks.run(:after, :context, example_group_instance) - end - ensure - before_context_ivars.clear - @currently_executing_a_context_hook = false - end - - # Runs all the examples in this group. - def self.run(reporter=RSpec::Core::NullReporter) - return if RSpec.world.wants_to_quit - reporter.example_group_started(self) - - should_run_context_hooks = descendant_filtered_examples.any? - begin - RSpec.current_scope = :before_context_hook - run_before_context_hooks(new('before(:context) hook')) if should_run_context_hooks - result_for_this_group = run_examples(reporter) - results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all? - result_for_this_group && results_for_descendants - rescue Pending::SkipDeclaredInExample => ex - for_filtered_examples(reporter) { |example| example.skip_with_exception(reporter, ex) } - true - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex - for_filtered_examples(reporter) { |example| example.fail_with_exception(reporter, ex) } - RSpec.world.wants_to_quit = true if reporter.fail_fast_limit_met? - false - ensure - RSpec.current_scope = :after_context_hook - run_after_context_hooks(new('after(:context) hook')) if should_run_context_hooks - reporter.example_group_finished(self) - end - end - - # @private - def self.ordering_strategy - order = metadata.fetch(:order, :global) - registry = RSpec.configuration.ordering_registry - - registry.fetch(order) do - warn <<-WARNING.gsub(/^ +\|/, '') - |WARNING: Ignoring unknown ordering specified using `:order => #{order.inspect}` metadata. - | Falling back to configured global ordering. - | Unrecognized ordering specified at: #{location} - WARNING - - registry.fetch(:global) - end - end - - # @private - def self.run_examples(reporter) - ordering_strategy.order(filtered_examples).map do |example| - next if RSpec.world.wants_to_quit - instance = new(example.inspect_output) - set_ivars(instance, before_context_ivars) - succeeded = example.run(instance, reporter) - if !succeeded && reporter.fail_fast_limit_met? - RSpec.world.wants_to_quit = true - end - succeeded - end.all? - end - - # @private - def self.for_filtered_examples(reporter, &block) - filtered_examples.each(&block) - - children.each do |child| - reporter.example_group_started(child) - child.for_filtered_examples(reporter, &block) - reporter.example_group_finished(child) - end - false - end - - # @private - def self.declaration_locations - @declaration_locations ||= [Metadata.location_tuple_from(metadata)] + - examples.map { |e| Metadata.location_tuple_from(e.metadata) } + - FlatMap.flat_map(children, &:declaration_locations) - end - - # @return [String] the unique id of this example group. Pass - # this at the command line to re-run this exact example group. - def self.id - Metadata.id_from(metadata) - end - - # @private - def self.top_level_description - parent_groups.last.description - end - - # @private - def self.set_ivars(instance, ivars) - ivars.each { |name, value| instance.instance_variable_set(name, value) } - end - - if RUBY_VERSION.to_f < 1.9 - # :nocov: - # @private - INSTANCE_VARIABLE_TO_IGNORE = '@__inspect_output'.freeze - # :nocov: - else - # @private - INSTANCE_VARIABLE_TO_IGNORE = :@__inspect_output - end - - # @private - def self.each_instance_variable_for_example(group) - group.instance_variables.each do |ivar| - yield ivar unless ivar == INSTANCE_VARIABLE_TO_IGNORE - end - end - - # @private - def initialize(inspect_output=nil) - @__inspect_output = inspect_output || '(no description provided)' - super() # no args get passed - end - - # @private - def inspect - "#<#{self.class} #{@__inspect_output}>" - end - - unless method_defined?(:singleton_class) # for 1.8.7 - # :nocov: - # @private - def singleton_class - class << self; self; end - end - # :nocov: - end - - # @private - def self.update_inherited_metadata(updates) - metadata.update(updates) do |key, existing_group_value, new_inherited_value| - @user_metadata.key?(key) ? existing_group_value : new_inherited_value - end - - RSpec.configuration.configure_group(self) - examples.each { |ex| ex.update_inherited_metadata(updates) } - children.each { |group| group.update_inherited_metadata(updates) } - end - - # Raised when an RSpec API is called in the wrong scope, such as `before` - # being called from within an example rather than from within an example - # group block. - WrongScopeError = Class.new(NoMethodError) - - def self.method_missing(name, *args) - if method_defined?(name) - raise WrongScopeError, - "`#{name}` is not available on an example group (e.g. a " \ - "`describe` or `context` block). It is only available from " \ - "within individual examples (e.g. `it` blocks) or from " \ - "constructs that run in the scope of an example (e.g. " \ - "`before`, `let`, etc)." - end - - super - end - private_class_method :method_missing - - private - - def method_missing(name, *args) - if self.class.respond_to?(name) - raise WrongScopeError, - "`#{name}` is not available from within an example (e.g. an " \ - "`it` block) or from constructs that run in the scope of an " \ - "example (e.g. `before`, `let`, etc). It is only available " \ - "on an example group (e.g. a `describe` or `context` block)." - end - - super(name, *args) - end - ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) - end - # rubocop:enable Metrics/ClassLength - - # @private - # Unnamed example group used by `SuiteHookContext`. - class AnonymousExampleGroup < ExampleGroup - def self.metadata - {} - end - end - - # Contains information about the inclusion site of a shared example group. - class SharedExampleGroupInclusionStackFrame - # @return [String] the name of the shared example group - attr_reader :shared_group_name - # @return [String] the location where the shared example was included - attr_reader :inclusion_location - - # @private - def initialize(shared_group_name, inclusion_location) - @shared_group_name = shared_group_name - @inclusion_location = inclusion_location - end - - # @return [String] The {#inclusion_location}, formatted for display by a formatter. - def formatted_inclusion_location - @formatted_inclusion_location ||= begin - RSpec.configuration.backtrace_formatter.backtrace_line( - inclusion_location.sub(/(:\d+):in .+$/, '\1') - ) - end - end - - # @return [String] Description of this stack frame, in the form used by - # RSpec's built-in formatters. - def description - @description ||= "Shared Example Group: #{shared_group_name.inspect} " \ - "called from #{formatted_inclusion_location}" - end - - # @private - def self.current_backtrace - shared_example_group_inclusions.reverse - end - - # @private - def self.with_frame(name, location) - current_stack = shared_example_group_inclusions - if current_stack.any? { |frame| frame.shared_group_name == name } - raise ArgumentError, "can't include shared examples recursively" - else - current_stack << new(name, location) - yield - end - ensure - current_stack.pop - end - - # @private - def self.shared_example_group_inclusions - RSpec::Support.thread_local_data[:shared_example_group_inclusions] ||= [] - end - end - end - - # @private - # - # Namespace for the example group subclasses generated by top-level - # `describe`. - module ExampleGroups - extend Support::RecursiveConstMethods - - def self.assign_const(group) - base_name = base_name_for(group) - const_scope = constant_scope_for(group) - name = disambiguate(base_name, const_scope) - - const_scope.const_set(name, group) - end - - def self.constant_scope_for(group) - const_scope = group.superclass - const_scope = self if const_scope == ::RSpec::Core::ExampleGroup - const_scope - end - - def self.remove_all_constants - constants.each do |constant| - __send__(:remove_const, constant) - end - end - - def self.base_name_for(group) - return "Anonymous".dup if group.description.empty? - - # Convert to CamelCase. - name = ' ' + group.description - name.gsub!(/[^0-9a-zA-Z]+([0-9a-zA-Z])/) do - match = ::Regexp.last_match[1] - match.upcase! - match - end - - name.lstrip! # Remove leading whitespace - name.gsub!(/\W/, ''.freeze) # JRuby, RBX and others don't like non-ascii in const names - - # Ruby requires first const letter to be A-Z. Use `Nested` - # as necessary to enforce that. - name.gsub!(/\A([^A-Z]|\z)/, 'Nested\1'.freeze) - - name - end - - if RUBY_VERSION == '1.9.2' - # :nocov: - class << self - alias _base_name_for base_name_for - def base_name_for(group) - _base_name_for(group) + '_' - end - end - private_class_method :_base_name_for - # :nocov: - end - - def self.disambiguate(name, const_scope) - return name unless const_defined_on?(const_scope, name) - - # Add a trailing number if needed to disambiguate from an existing - # constant. - name << "_2" - name.next! while const_defined_on?(const_scope, name) - name - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb deleted file mode 100644 index d628b76..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/example_status_persister.rb +++ /dev/null @@ -1,235 +0,0 @@ -RSpec::Support.require_rspec_support "directory_maker" - -module RSpec - module Core - # Persists example ids and their statuses so that we can filter - # to just the ones that failed the last time they ran. - # @private - class ExampleStatusPersister - def self.load_from(file_name) - return [] unless File.exist?(file_name) - ExampleStatusParser.parse(File.read(file_name)) - end - - def self.persist(examples, file_name) - new(examples, file_name).persist - end - - def initialize(examples, file_name) - @examples = examples - @file_name = file_name - end - - def persist - RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(@file_name)) - File.open(@file_name, File::RDWR | File::CREAT) do |f| - # lock the file while reading / persisting to avoid a race - # condition where parallel or unrelated spec runs race to - # update the same file - f.flock(File::LOCK_EX) - unparsed_previous_runs = f.read - f.rewind - f.write(dump_statuses(unparsed_previous_runs)) - f.flush - f.truncate(f.pos) - end - end - - private - - def dump_statuses(unparsed_previous_runs) - statuses_from_previous_runs = ExampleStatusParser.parse(unparsed_previous_runs) - merged_statuses = ExampleStatusMerger.merge(statuses_from_this_run, statuses_from_previous_runs) - ExampleStatusDumper.dump(merged_statuses) - end - - def statuses_from_this_run - @examples.map do |ex| - result = ex.execution_result - - { - :example_id => ex.id, - :status => result.status ? result.status.to_s : Configuration::UNKNOWN_STATUS, - :run_time => result.run_time ? Formatters::Helpers.format_duration(result.run_time) : "" - } - end - end - end - - # Merges together a list of example statuses from this run - # and a list from previous runs (presumably loaded from disk). - # Each example status object is expected to be a hash with - # at least an `:example_id` and a `:status` key. Examples that - # were loaded but not executed (due to filtering, `--fail-fast` - # or whatever) should have a `:status` of `UNKNOWN_STATUS`. - # - # This will produce a new list that: - # - Will be missing examples from previous runs that we know for sure - # no longer exist. - # - Will have the latest known status for any examples that either - # definitively do exist or may still exist. - # - Is sorted by file name and example definition order, so that - # the saved file is easily scannable if users want to inspect it. - # @private - class ExampleStatusMerger - def self.merge(this_run, from_previous_runs) - new(this_run, from_previous_runs).merge - end - - def initialize(this_run, from_previous_runs) - @this_run = hash_from(this_run) - @from_previous_runs = hash_from(from_previous_runs) - @file_exists_cache = Hash.new { |hash, file| hash[file] = File.exist?(file) } - end - - def merge - delete_previous_examples_that_no_longer_exist - - @this_run.merge(@from_previous_runs) do |_ex_id, new, old| - new.fetch(:status) == Configuration::UNKNOWN_STATUS ? old : new - end.values.sort_by(&method(:sort_value_from)) - end - - private - - def hash_from(example_list) - example_list.inject({}) do |hash, example| - hash[example.fetch(:example_id)] = example - hash - end - end - - def delete_previous_examples_that_no_longer_exist - @from_previous_runs.delete_if do |ex_id, _| - example_must_no_longer_exist?(ex_id) - end - end - - def example_must_no_longer_exist?(ex_id) - # Obviously, it exists if it was loaded for this spec run... - return false if @this_run.key?(ex_id) - - spec_file = spec_file_from(ex_id) - - # `this_run` includes examples that were loaded but not executed. - # Given that, if the spec file for this example was loaded, - # but the id does not still exist, it's safe to assume that - # the example must no longer exist. - return true if loaded_spec_files.include?(spec_file) - - # The example may still exist as long as the file exists... - !@file_exists_cache[spec_file] - end - - def loaded_spec_files - @loaded_spec_files ||= Set.new(@this_run.keys.map(&method(:spec_file_from))) - end - - def spec_file_from(ex_id) - ex_id.split("[").first - end - - def sort_value_from(example) - file, scoped_id = Example.parse_id(example.fetch(:example_id)) - [file, *scoped_id.split(":").map(&method(:Integer))] - end - end - - # Dumps a list of hashes in a pretty, human readable format - # for later parsing. The hashes are expected to have symbol - # keys and string values, and each hash should have the same - # set of keys. - # @private - class ExampleStatusDumper - def self.dump(examples) - new(examples).dump - end - - def initialize(examples) - @examples = examples - end - - def dump - return nil if @examples.empty? - (formatted_header_rows + formatted_value_rows).join("\n") << "\n" - end - - private - - def formatted_header_rows - @formatted_header_rows ||= begin - dividers = column_widths.map { |w| "-" * w } - [formatted_row_from(headers.map(&:to_s)), formatted_row_from(dividers)] - end - end - - def formatted_value_rows - @formatted_value_rows ||= rows.map do |row| - formatted_row_from(row) - end - end - - def rows - @rows ||= @examples.map { |ex| ex.values_at(*headers) } - end - - def formatted_row_from(row_values) - padded_values = row_values.each_with_index.map do |value, index| - value.ljust(column_widths[index]) - end - - padded_values.join(" | ") << " |" - end - - def headers - @headers ||= @examples.first.keys - end - - def column_widths - @column_widths ||= begin - value_sets = rows.transpose - - headers.each_with_index.map do |header, index| - values = value_sets[index] << header.to_s - values.map(&:length).max - end - end - end - end - - # Parses a string that has been previously dumped by ExampleStatusDumper. - # Note that this parser is a bit naive in that it does a simple split on - # "\n" and " | ", with no concern for handling escaping. For now, that's - # OK because the values we plan to persist (example id, status, and perhaps - # example duration) are highly unlikely to contain "\n" or " | " -- after - # all, who puts those in file names? - # @private - class ExampleStatusParser - def self.parse(string) - new(string).parse - end - - def initialize(string) - @header_line, _, *@row_lines = string.lines.to_a - end - - def parse - @row_lines.map { |line| parse_row(line) } - end - - private - - def parse_row(line) - Hash[headers.zip(split_line(line))] - end - - def headers - @headers ||= split_line(@header_line).grep(/\S/).map(&:to_sym) - end - - def split_line(line) - line.split(/\s+\|\s+?/, -1) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb deleted file mode 100644 index 8d2de0e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/filter_manager.rb +++ /dev/null @@ -1,231 +0,0 @@ -module RSpec - module Core - # @private - class FilterManager - attr_reader :exclusions, :inclusions - - def initialize - @exclusions, @inclusions = FilterRules.build - end - - # @api private - # - # @param file_path [String] - # @param line_numbers [Array] - def add_location(file_path, line_numbers) - # locations is a hash of expanded paths to arrays of line - # numbers to match against. e.g. - # { "path/to/file.rb" => [37, 42] } - add_path_to_arrays_filter(:locations, File.expand_path(file_path), line_numbers) - end - - def add_ids(rerun_path, scoped_ids) - # ids is a hash of relative paths to arrays of ids - # to match against. e.g. - # { "./path/to/file.rb" => ["1:1", "2:4"] } - rerun_path = Metadata.relative_path(File.expand_path rerun_path) - add_path_to_arrays_filter(:ids, rerun_path, scoped_ids) - end - - def empty? - inclusions.empty? && exclusions.empty? - end - - def prune(examples) - # Semantically, this is unnecessary (the filtering below will return the empty - # array unmodified), but for perf reasons it's worth exiting early here. Users - # commonly have top-level examples groups that do not have any direct examples - # and instead have nested groups with examples. In that kind of situation, - # `examples` will be empty. - return examples if examples.empty? - - examples = prune_conditionally_filtered_examples(examples) - - if inclusions.standalone? - examples.select { |e| inclusions.include_example?(e) } - else - locations, ids, non_scoped_inclusions = inclusions.split_file_scoped_rules - - examples.select do |ex| - file_scoped_include?(ex.metadata, ids, locations) do - !exclusions.include_example?(ex) && non_scoped_inclusions.include_example?(ex) - end - end - end - end - - def exclude(*args) - exclusions.add(args.last) - end - - def exclude_only(*args) - exclusions.use_only(args.last) - end - - def exclude_with_low_priority(*args) - exclusions.add_with_low_priority(args.last) - end - - def include(*args) - inclusions.add(args.last) - end - - def include_only(*args) - inclusions.use_only(args.last) - end - - def include_with_low_priority(*args) - inclusions.add_with_low_priority(args.last) - end - - private - - def add_path_to_arrays_filter(filter_key, path, values) - filter = inclusions.delete(filter_key) || Hash.new { |h, k| h[k] = [] } - filter[path].concat(values) - inclusions.add(filter_key => filter) - end - - def prune_conditionally_filtered_examples(examples) - examples.reject do |ex| - meta = ex.metadata - !meta.fetch(:if, true) || meta[:unless] - end - end - - # When a user specifies a particular spec location, that takes priority - # over any exclusion filters (such as if the spec is tagged with `:slow` - # and there is a `:slow => true` exclusion filter), but only for specs - # defined in the same file as the location filters. Excluded specs in - # other files should still be excluded. - def file_scoped_include?(ex_metadata, ids, locations) - no_id_filters = ids[ex_metadata[:rerun_file_path]].empty? - no_location_filters = locations[ - File.expand_path(ex_metadata[:rerun_file_path]) - ].empty? - - return yield if no_location_filters && no_id_filters - - MetadataFilter.filter_applies?(:ids, ids, ex_metadata) || - MetadataFilter.filter_applies?(:locations, locations, ex_metadata) - end - end - - # @private - class FilterRules - PROC_HEX_NUMBER = /0x[0-9a-f]+@?/ - PROJECT_DIR = File.expand_path('.') - - attr_accessor :opposite - attr_reader :rules - - def self.build - exclusions = ExclusionRules.new - inclusions = InclusionRules.new - exclusions.opposite = inclusions - inclusions.opposite = exclusions - [exclusions, inclusions] - end - - def initialize(rules={}) - @rules = rules - end - - def add(updated) - @rules.merge!(updated).each_key { |k| opposite.delete(k) } - end - - def add_with_low_priority(updated) - updated = updated.merge(@rules) - opposite.each_pair { |k, v| updated.delete(k) if updated[k] == v } - @rules.replace(updated) - end - - def use_only(updated) - updated.each_key { |k| opposite.delete(k) } - @rules.replace(updated) - end - - def clear - @rules.clear - end - - def delete(key) - @rules.delete(key) - end - - def fetch(*args, &block) - @rules.fetch(*args, &block) - end - - def [](key) - @rules[key] - end - - def empty? - rules.empty? - end - - def each_pair(&block) - @rules.each_pair(&block) - end - - def description - rules.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)', '') - end - - def include_example?(example) - MetadataFilter.apply?(:any?, @rules, example.metadata) - end - end - - # @private - ExclusionRules = FilterRules - - # @private - class InclusionRules < FilterRules - def add(*args) - apply_standalone_filter(*args) || super - end - - def add_with_low_priority(*args) - apply_standalone_filter(*args) || super - end - - def include_example?(example) - @rules.empty? || super - end - - def standalone? - is_standalone_filter?(@rules) - end - - def split_file_scoped_rules - rules_dup = @rules.dup - locations = rules_dup.delete(:locations) { Hash.new { [] } } - ids = rules_dup.delete(:ids) { Hash.new { [] } } - - return locations, ids, self.class.new(rules_dup) - end - - private - - def apply_standalone_filter(updated) - return true if standalone? - return nil unless is_standalone_filter?(updated) - - replace_filters(updated) - true - end - - def replace_filters(new_rules) - @rules.replace(new_rules) - opposite.clear - end - - def is_standalone_filter?(rules) - rules.key?(:full_description) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb deleted file mode 100644 index 0e30cce..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/flat_map.rb +++ /dev/null @@ -1,20 +0,0 @@ -module RSpec - module Core - # @private - module FlatMap - if [].respond_to?(:flat_map) - def flat_map(array, &block) - array.flat_map(&block) - end - else # for 1.8.7 - # :nocov: - def flat_map(array, &block) - array.map(&block).flatten(1) - end - # :nocov: - end - - module_function :flat_map - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb deleted file mode 100644 index f0238f8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters.rb +++ /dev/null @@ -1,279 +0,0 @@ -RSpec::Support.require_rspec_support "directory_maker" - -# ## Built-in Formatters -# -# * progress (default) - Prints dots for passing examples, `F` for failures, `*` -# for pending. -# * documentation - Prints the docstrings passed to `describe` and `it` methods -# (and their aliases). -# * html -# * json - Useful for archiving data for subsequent analysis. -# -# The progress formatter is the default, but you can choose any one or more of -# the other formatters by passing with the `--format` (or `-f` for short) -# command-line option, e.g. -# -# rspec --format documentation -# -# You can also send the output of multiple formatters to different streams, e.g. -# -# rspec --format documentation --format html --out results.html -# -# This example sends the output of the documentation formatter to `$stdout`, and -# the output of the html formatter to results.html. -# -# ## Custom Formatters -# -# You can tell RSpec to use a custom formatter by passing its path and name to -# the `rspec` command. For example, if you define MyCustomFormatter in -# path/to/my_custom_formatter.rb, you would type this command: -# -# rspec --require path/to/my_custom_formatter.rb --format MyCustomFormatter -# -# The reporter calls every formatter with this protocol: -# -# * To start -# * `start(StartNotification)` -# * Once per example group -# * `example_group_started(GroupNotification)` -# * Once per example -# * `example_started(ExampleNotification)` -# * One of these per example, depending on outcome -# * `example_passed(ExampleNotification)` -# * `example_failed(FailedExampleNotification)` -# * `example_pending(ExampleNotification)` -# * Optionally at any time -# * `message(MessageNotification)` -# * At the end of the suite -# * `stop(ExamplesNotification)` -# * `start_dump(NullNotification)` -# * `dump_pending(ExamplesNotification)` -# * `dump_failures(ExamplesNotification)` -# * `dump_summary(SummaryNotification)` -# * `seed(SeedNotification)` -# * `close(NullNotification)` -# -# Only the notifications to which you subscribe your formatter will be called -# on your formatter. To subscribe your formatter use: -# `RSpec::Core::Formatters#register` e.g. -# -# `RSpec::Core::Formatters.register FormatterClassName, :example_passed, :example_failed` -# -# We recommend you implement the methods yourself; for simplicity we provide the -# default formatter output via our notification objects but if you prefer you -# can subclass `RSpec::Core::Formatters::BaseTextFormatter` and override the -# methods you wish to enhance. -# -# @see RSpec::Core::Formatters::BaseTextFormatter -# @see RSpec::Core::Reporter -module RSpec::Core::Formatters - autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter' - autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter' - autoload :FallbackMessageFormatter, 'rspec/core/formatters/fallback_message_formatter' - autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter' - autoload :ProfileFormatter, 'rspec/core/formatters/profile_formatter' - autoload :JsonFormatter, 'rspec/core/formatters/json_formatter' - autoload :BisectDRbFormatter, 'rspec/core/formatters/bisect_drb_formatter' - autoload :ExceptionPresenter, 'rspec/core/formatters/exception_presenter' - autoload :FailureListFormatter, 'rspec/core/formatters/failure_list_formatter' - - # Register the formatter class - # @param formatter_class [Class] formatter class to register - # @param notifications [Array] one or more notifications to be - # registered to the specified formatter - # - # @see RSpec::Core::Formatters::BaseFormatter - def self.register(formatter_class, *notifications) - Loader.formatters[formatter_class] = notifications - end - - # @api private - # - # `RSpec::Core::Formatters::Loader` is an internal class for - # managing formatters used by a particular configuration. It is - # not expected to be used directly, but only through the configuration - # interface. - class Loader - # @api private - # - # Internal formatters are stored here when loaded. - def self.formatters - @formatters ||= {} - end - - # @api private - def initialize(reporter) - @formatters = [] - @reporter = reporter - self.default_formatter = 'progress' - end - - # @return [Array] the loaded formatters - attr_reader :formatters - - # @return [Reporter] the reporter - attr_reader :reporter - - # @return [String] the default formatter to setup, defaults to `progress` - attr_accessor :default_formatter - - # @private - def prepare_default(output_stream, deprecation_stream) - reporter.prepare_default(self, output_stream, deprecation_stream) - end - - # @private - def setup_default(output_stream, deprecation_stream) - add default_formatter, output_stream if @formatters.empty? - - unless @formatters.any? { |formatter| DeprecationFormatter === formatter } - add DeprecationFormatter, deprecation_stream, output_stream - end - - unless existing_formatter_implements?(:message) - add FallbackMessageFormatter, output_stream - end - - return unless RSpec.configuration.profile_examples? - return if existing_formatter_implements?(:dump_profile) - - add RSpec::Core::Formatters::ProfileFormatter, output_stream - end - - # @private - def add(formatter_to_use, *paths) - # If a formatter instance was passed, we can register it directly, - # with no need for any of the further processing that happens below. - if Loader.formatters.key?(formatter_to_use.class) - register formatter_to_use, notifications_for(formatter_to_use.class) - return - end - - formatter_class = find_formatter(formatter_to_use) - - args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) } - - if !Loader.formatters[formatter_class].nil? - formatter = formatter_class.new(*args) - register formatter, notifications_for(formatter_class) - elsif defined?(RSpec::LegacyFormatters) - formatter = RSpec::LegacyFormatters.load_formatter formatter_class, *args - register formatter, formatter.notifications - else - call_site = "Formatter added at: #{::RSpec::CallerFilter.first_non_rspec_line}" - - RSpec.warn_deprecation <<-WARNING.gsub(/\s*\|/, ' ') - |The #{formatter_class} formatter uses the deprecated formatter - |interface not supported directly by RSpec 3. - | - |To continue to use this formatter you must install the - |`rspec-legacy_formatters` gem, which provides support - |for legacy formatters or upgrade the formatter to a - |compatible version. - | - |#{call_site} - WARNING - end - end - - private - - def find_formatter(formatter_to_use) - built_in_formatter(formatter_to_use) || - custom_formatter(formatter_to_use) || - (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - " \ - "maybe you meant 'documentation' or 'progress'?.") - end - - def register(formatter, notifications) - return if duplicate_formatter_exists?(formatter) - @reporter.register_listener formatter, *notifications - @formatters << formatter - formatter - end - - def duplicate_formatter_exists?(new_formatter) - @formatters.any? do |formatter| - formatter.class == new_formatter.class && - has_matching_output?(formatter, new_formatter) - end - end - - def has_matching_output?(formatter, new_formatter) - return true unless formatter.respond_to?(:output) && new_formatter.respond_to?(:output) - formatter.output == new_formatter.output - end - - def existing_formatter_implements?(notification) - @reporter.registered_listeners(notification).any? - end - - def built_in_formatter(key) - case key.to_s - when 'd', 'doc', 'documentation' - DocumentationFormatter - when 'h', 'html' - HtmlFormatter - when 'p', 'progress' - ProgressFormatter - when 'j', 'json' - JsonFormatter - when 'bisect-drb' - BisectDRbFormatter - when 'f', 'failures' - FailureListFormatter - end - end - - def notifications_for(formatter_class) - formatter_class.ancestors.inject(::RSpec::Core::Set.new) do |notifications, klass| - notifications.merge Loader.formatters.fetch(klass) { ::RSpec::Core::Set.new } - end - end - - def custom_formatter(formatter_ref) - if Class === formatter_ref - formatter_ref - elsif string_const?(formatter_ref) - begin - formatter_ref.gsub(/^::/, '').split('::').inject(Object) { |a, e| a.const_get e } - rescue NameError - require(path_for(formatter_ref)) ? retry : raise - end - end - end - - def string_const?(str) - str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str - end - - def path_for(const_ref) - underscore_with_fix_for_non_standard_rspec_naming(const_ref) - end - - def underscore_with_fix_for_non_standard_rspec_naming(string) - underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2') - end - - # activesupport/lib/active_support/inflector/methods.rb, line 48 - def underscore(camel_cased_word) - word = camel_cased_word.to_s.dup - word.gsub!(/::/, '/') - word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2') - word.gsub!(/([a-z\d])([A-Z])/, '\1_\2') - word.tr!("-", "_") - word.downcase! - word - end - - def open_stream(path_or_wrapper) - if RSpec::Core::OutputWrapper === path_or_wrapper - path_or_wrapper.output = open_stream(path_or_wrapper.output) - path_or_wrapper - else - RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path_or_wrapper)) - File.new(path_or_wrapper, 'w') - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb deleted file mode 100644 index 4159cba..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_bisect_formatter.rb +++ /dev/null @@ -1,45 +0,0 @@ -RSpec::Support.require_rspec_core "bisect/utilities" - -module RSpec - module Core - module Formatters - # Contains common logic for formatters used by `--bisect` to communicate results - # back to the bisect runner. - # - # Subclasses must define a `notify_results(all_example_ids, failed_example_ids)` - # method. - # @private - class BaseBisectFormatter - def self.inherited(formatter) - Formatters.register formatter, :start_dump, :example_failed, :example_finished - end - - def initialize(expected_failures) - @all_example_ids = [] - @failed_example_ids = [] - @remaining_failures = expected_failures - end - - def example_failed(notification) - @failed_example_ids << notification.example.id - end - - def example_finished(notification) - @all_example_ids << notification.example.id - return unless @remaining_failures.include?(notification.example.id) - @remaining_failures.delete(notification.example.id) - - status = notification.example.execution_result.status - return if status == :failed && !@remaining_failures.empty? - RSpec.world.wants_to_quit = true - end - - def start_dump(_notification) - # `notify_results` is defined in the subclass - notify_results(Bisect::ExampleSetDescriptor.new( - @all_example_ids, @failed_example_ids)) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb deleted file mode 100644 index dca4b6d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_formatter.rb +++ /dev/null @@ -1,70 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/helpers" -require 'stringio' - -module RSpec - module Core - module Formatters - # RSpec's built-in formatters are all subclasses of - # RSpec::Core::Formatters::BaseFormatter. - # - # @see RSpec::Core::Formatters::BaseTextFormatter - # @see RSpec::Core::Reporter - # @see RSpec::Core::Formatters::Protocol - class BaseFormatter - # All formatters inheriting from this formatter will receive these - # notifications. - Formatters.register self, :start, :example_group_started, :close - attr_accessor :example_group - attr_reader :output - - # @api public - # @param output [IO] the formatter output - # @see RSpec::Core::Formatters::Protocol#initialize - def initialize(output) - @output = output || StringIO.new - @example_group = nil - end - - # @api public - # - # @param notification [StartNotification] - # @see RSpec::Core::Formatters::Protocol#start - def start(notification) - start_sync_output - @example_count = notification.count - end - - # @api public - # - # @param notification [GroupNotification] containing example_group - # subclass of `RSpec::Core::ExampleGroup` - # @see RSpec::Core::Formatters::Protocol#example_group_started - def example_group_started(notification) - @example_group = notification.group - end - - # @api public - # - # @param _notification [NullNotification] (Ignored) - # @see RSpec::Core::Formatters::Protocol#close - def close(_notification) - restore_sync_output - end - - private - - def start_sync_output - @old_sync, output.sync = output.sync, true if output_supports_sync - end - - def restore_sync_output - output.sync = @old_sync if output_supports_sync && !output.closed? - end - - def output_supports_sync - output.respond_to?(:sync=) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb deleted file mode 100644 index 5d9daba..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/base_text_formatter.rb +++ /dev/null @@ -1,75 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/base_formatter" - -module RSpec - module Core - module Formatters - # Base for all of RSpec's built-in formatters. See - # RSpec::Core::Formatters::BaseFormatter to learn more about all of the - # methods called by the reporter. - # - # @see RSpec::Core::Formatters::BaseFormatter - # @see RSpec::Core::Reporter - class BaseTextFormatter < BaseFormatter - Formatters.register self, - :message, :dump_summary, :dump_failures, :dump_pending, :seed - - # @api public - # - # Used by the reporter to send messages to the output stream. - # - # @param notification [MessageNotification] containing message - def message(notification) - output.puts notification.message - end - - # @api public - # - # Dumps detailed information about each example failure. - # - # @param notification [NullNotification] - def dump_failures(notification) - return if notification.failure_notifications.empty? - output.puts notification.fully_formatted_failed_examples - end - - # @api public - # - # This method is invoked after the dumping of examples and failures. - # Each parameter is assigned to a corresponding attribute. - # - # @param summary [SummaryNotification] containing duration, - # example_count, failure_count and pending_count - def dump_summary(summary) - output.puts summary.fully_formatted - end - - # @private - def dump_pending(notification) - return if notification.pending_examples.empty? - output.puts notification.fully_formatted_pending_examples - end - - # @private - def seed(notification) - return unless notification.seed_used? - output.puts notification.fully_formatted - end - - # @api public - # - # Invoked at the end of a suite run. Allows the formatter to do any - # tidying up, but be aware that formatter output streams may be used - # elsewhere so don't actually close them. - # - # @param _notification [NullNotification] (Ignored) - def close(_notification) - return if output.closed? - - output.puts - - output.flush - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb deleted file mode 100644 index 9fb1299..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_drb_formatter.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'drb/drb' -RSpec::Support.require_rspec_core "formatters/base_bisect_formatter" - -module RSpec - module Core - module Formatters - # Used by `--bisect`. When it shells out and runs a portion of the suite, it uses - # this formatter as a means to have the status reported back to it, via DRb. - # - # Note that since DRb calls carry considerable overhead compared to normal - # method calls, we try to minimize the number of DRb calls for perf reasons, - # opting to communicate only at the start and the end of the run, rather than - # after each example. - # @private - class BisectDRbFormatter < BaseBisectFormatter - def initialize(_output) - drb_uri = "druby://localhost:#{RSpec.configuration.drb_port}" - @bisect_server = DRbObject.new_with_uri(drb_uri) - RSpec.configuration.files_or_directories_to_run = @bisect_server.files_or_directories_to_run - super(Set.new(@bisect_server.expected_failures)) - end - - def notify_results(results) - @bisect_server.latest_run_results = results - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb deleted file mode 100644 index 35f01a6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/bisect_progress_formatter.rb +++ /dev/null @@ -1,157 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/base_text_formatter" - -module RSpec - module Core - module Formatters - # @private - # Produces progress output while bisecting. - class BisectProgressFormatter < BaseTextFormatter - def initialize(output, bisect_runner) - super(output) - @bisect_runner = bisect_runner - end - - def bisect_starting(notification) - @round_count = 0 - output.puts bisect_started_message(notification) - output.print "Running suite to find failures..." - end - - def bisect_original_run_complete(notification) - failures = Helpers.pluralize(notification.failed_example_ids.size, "failing example") - non_failures = Helpers.pluralize(notification.non_failing_example_ids.size, "non-failing example") - - output.puts " (#{Helpers.format_duration(notification.duration)})" - output.puts "Starting bisect with #{failures} and #{non_failures}." - end - - def bisect_dependency_check_started(_notification) - output.print "Checking that failure(s) are order-dependent.." - end - - def bisect_dependency_check_passed(_notification) - output.puts " failure appears to be order-dependent" - end - - def bisect_dependency_check_failed(_notification) - output.puts " failure(s) do not require any non-failures to run first" - - if @bisect_runner == :fork - output.puts - output.puts "=" * 80 - output.puts "NOTE: this bisect run used `config.bisect_runner = :fork`, which generally" - output.puts "provides significantly faster bisection runs than the old shell-based runner," - output.puts "but may inaccurately report that no non-failures are required. If this result" - output.puts "is unexpected, consider setting `config.bisect_runner = :shell` and trying again." - output.puts "=" * 80 - end - end - - def bisect_round_started(notification, include_trailing_space=true) - @round_count += 1 - range_desc = notification.candidate_range.description - - output.print "\nRound #{@round_count}: bisecting over non-failing #{range_desc}" - output.print " " if include_trailing_space - end - - def bisect_round_ignoring_ids(notification) - range_desc = notification.ignore_range.description - - output.print " ignoring #{range_desc}" - output.print " (#{Helpers.format_duration(notification.duration)})" - end - - def bisect_round_detected_multiple_culprits(notification) - output.print " multiple culprits detected - splitting candidates" - output.print " (#{Helpers.format_duration(notification.duration)})" - end - - def bisect_individual_run_complete(_) - output.print '.' - end - - def bisect_complete(notification) - output.puts "\nBisect complete! Reduced necessary non-failing examples " \ - "from #{notification.original_non_failing_count} to " \ - "#{notification.remaining_count} in " \ - "#{Helpers.format_duration(notification.duration)}." - end - - def bisect_repro_command(notification) - output.puts "\nThe minimal reproduction command is:\n #{notification.repro}" - end - - def bisect_failed(notification) - output.puts "\nBisect failed! #{notification.failure_explanation}" - end - - def bisect_aborted(notification) - output.puts "\n\nBisect aborted!" - output.puts "\nThe most minimal reproduction command discovered so far is:\n #{notification.repro}" - end - - private - - def bisect_started_message(notification) - options = notification.original_cli_args.join(' ') - "Bisect started using options: #{options.inspect}" - end - end - - # @private - # Produces detailed debug output while bisecting. Used when bisect is - # performed with `--bisect=verbose`. Designed to provide details for - # us when we need to troubleshoot bisect bugs. - class BisectDebugFormatter < BisectProgressFormatter - def bisect_original_run_complete(notification) - output.puts " (#{Helpers.format_duration(notification.duration)})" - - output.puts " - #{describe_ids 'Failing examples', notification.failed_example_ids}" - output.puts " - #{describe_ids 'Non-failing examples', notification.non_failing_example_ids}" - end - - def bisect_individual_run_start(notification) - output.print "\n - Running: #{notification.command}" - end - - def bisect_individual_run_complete(notification) - output.print " (#{Helpers.format_duration(notification.duration)})" - end - - def bisect_dependency_check_passed(_notification) - output.print "\n - Failure appears to be order-dependent" - end - - def bisect_dependency_check_failed(_notification) - output.print "\n - Failure is not order-dependent" - end - - def bisect_round_started(notification) - super(notification, false) - end - - def bisect_round_ignoring_ids(notification) - output.print "\n - #{describe_ids 'Examples we can safely ignore', notification.ids_to_ignore}" - output.print "\n - #{describe_ids 'Remaining non-failing examples', notification.remaining_ids}" - end - - def bisect_round_detected_multiple_culprits(_notification) - output.print "\n - Multiple culprits detected - splitting candidates" - end - - private - - def describe_ids(description, ids) - organized_ids = Formatters::Helpers.organize_ids(ids) - formatted_ids = organized_ids.map { |id| " - #{id}" }.join("\n") - "#{description} (#{ids.size}):\n#{formatted_ids}" - end - - def bisect_started_message(notification) - "#{super} and bisect runner: #{notification.bisect_runner.inspect}" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb deleted file mode 100644 index 79e3062..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/console_codes.rb +++ /dev/null @@ -1,76 +0,0 @@ -module RSpec - module Core - module Formatters - # ConsoleCodes provides helpers for formatting console output - # with ANSI codes, e.g. color's and bold. - module ConsoleCodes - # @private - VT100_CODES = - { - :black => 30, - :red => 31, - :green => 32, - :yellow => 33, - :blue => 34, - :magenta => 35, - :cyan => 36, - :white => 37, - :bold_black => '1;30', - :bold_red => '1;31', - :bold_green => '1;32', - :bold_yellow => '1;33', - :bold_blue => '1;34', - :bold_magenta => '1;35', - :bold_cyan => '1;36', - :bold_white => '1;37', - :bold => 1, - } - # @private - VT100_CODE_VALUES = VT100_CODES.invert - - module_function - - # @private - def config_colors_to_methods - @config_colors_to_methods ||= - Configuration.instance_methods.grep(/_color\z/).inject({}) do |hash, method| - hash[method.to_s.sub(/_color\z/, '').to_sym] = method - hash - end - end - - # Fetches the correct code for the supplied symbol, or checks - # that a code is valid. Defaults to white (37). - # - # @param code_or_symbol [Symbol, Fixnum] Symbol or code to check - # @return [Fixnum] a console code - def console_code_for(code_or_symbol) - if (config_method = config_colors_to_methods[code_or_symbol]) - console_code_for RSpec.configuration.__send__(config_method) - elsif VT100_CODE_VALUES.key?(code_or_symbol) - code_or_symbol - else - VT100_CODES.fetch(code_or_symbol) do - console_code_for(:white) - end - end - end - - # Wraps a piece of text in ANSI codes with the supplied code. Will - # only apply the control code if `RSpec.configuration.color_enabled?` - # returns true. - # - # @param text [String] the text to wrap - # @param code_or_symbol [Symbol, Fixnum] the desired control code - # @return [String] the wrapped text - def wrap(text, code_or_symbol) - if RSpec.configuration.color_enabled? - "\e[#{console_code_for(code_or_symbol)}m#{text}\e[0m" - else - text - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb deleted file mode 100644 index 110a71f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/deprecation_formatter.rb +++ /dev/null @@ -1,223 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/helpers" - -module RSpec - module Core - module Formatters - # @private - class DeprecationFormatter - Formatters.register self, :deprecation, :deprecation_summary - - attr_reader :count, :deprecation_stream, :summary_stream - - def initialize(deprecation_stream, summary_stream) - @deprecation_stream = deprecation_stream - @summary_stream = summary_stream - @seen_deprecations = Set.new - @count = 0 - end - alias :output :deprecation_stream - - def printer - @printer ||= case deprecation_stream - when File - ImmediatePrinter.new(FileStream.new(deprecation_stream), - summary_stream, self) - when RaiseErrorStream - ImmediatePrinter.new(deprecation_stream, summary_stream, self) - else - DelayedPrinter.new(deprecation_stream, summary_stream, self) - end - end - - def deprecation(notification) - return if @seen_deprecations.include? notification - - @count += 1 - printer.print_deprecation_message notification - @seen_deprecations << notification - end - - def deprecation_summary(_notification) - printer.deprecation_summary - end - - def deprecation_message_for(data) - if data.message - SpecifiedDeprecationMessage.new(data) - else - GeneratedDeprecationMessage.new(data) - end - end - - RAISE_ERROR_CONFIG_NOTICE = <<-EOS.gsub(/^\s+\|/, '') - | - |If you need more of the backtrace for any of these deprecations to - |identify where to make the necessary changes, you can configure - |`config.raise_errors_for_deprecations!`, and it will turn the - |deprecation warnings into errors, giving you the full backtrace. - EOS - - DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set " \ - "`config.deprecation_stream` to a file for full output." - TOO_MANY_WARNINGS_NOTICE = "Too many similar deprecation messages " \ - "reported, disregarding further reports. #{DEPRECATION_STREAM_NOTICE}" - - # @private - SpecifiedDeprecationMessage = Struct.new(:type) do - def initialize(data) - @message = data.message - super deprecation_type_for(data) - end - - def to_s - output_formatted @message - end - - def too_many_warnings_message - TOO_MANY_WARNINGS_NOTICE - end - - private - - def output_formatted(str) - return str unless str.lines.count > 1 - separator = '-' * 80 - "#{separator}\n#{str.chomp}\n#{separator}" - end - - def deprecation_type_for(data) - data.message.gsub(/(\w+\/)+\w+\.rb:\d+/, '') - end - end - - # @private - GeneratedDeprecationMessage = Struct.new(:type) do - def initialize(data) - @data = data - super data.deprecated - end - - def to_s - msg = String.new("#{@data.deprecated} is deprecated.") - msg << " Use #{@data.replacement} instead." if @data.replacement - msg << " Called from #{@data.call_site}." if @data.call_site - msg - end - - def too_many_warnings_message - "Too many uses of deprecated '#{type}'. #{DEPRECATION_STREAM_NOTICE}" - end - end - - # @private - class ImmediatePrinter - attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter - - def initialize(deprecation_stream, summary_stream, deprecation_formatter) - @deprecation_stream = deprecation_stream - - @summary_stream = summary_stream - @deprecation_formatter = deprecation_formatter - end - - def print_deprecation_message(data) - deprecation_message = deprecation_formatter.deprecation_message_for(data) - deprecation_stream.puts deprecation_message.to_s - end - - def deprecation_summary - return if deprecation_formatter.count.zero? - deprecation_stream.summarize(summary_stream, deprecation_formatter.count) - end - end - - # @private - class DelayedPrinter - TOO_MANY_USES_LIMIT = 4 - - attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter - - def initialize(deprecation_stream, summary_stream, deprecation_formatter) - @deprecation_stream = deprecation_stream - @summary_stream = summary_stream - @deprecation_formatter = deprecation_formatter - @seen_deprecations = Hash.new { 0 } - @deprecation_messages = Hash.new { |h, k| h[k] = [] } - end - - def print_deprecation_message(data) - deprecation_message = deprecation_formatter.deprecation_message_for(data) - @seen_deprecations[deprecation_message] += 1 - - stash_deprecation_message(deprecation_message) - end - - def stash_deprecation_message(deprecation_message) - if @seen_deprecations[deprecation_message] < TOO_MANY_USES_LIMIT - @deprecation_messages[deprecation_message] << deprecation_message.to_s - elsif @seen_deprecations[deprecation_message] == TOO_MANY_USES_LIMIT - @deprecation_messages[deprecation_message] << deprecation_message.too_many_warnings_message - end - end - - def deprecation_summary - return unless @deprecation_messages.any? - - print_deferred_deprecation_warnings - deprecation_stream.puts RAISE_ERROR_CONFIG_NOTICE - - summary_stream.puts "\n#{Helpers.pluralize(deprecation_formatter.count, 'deprecation warning')} total" - end - - def print_deferred_deprecation_warnings - deprecation_stream.puts "\nDeprecation Warnings:\n\n" - @deprecation_messages.keys.sort_by(&:type).each do |deprecation| - messages = @deprecation_messages[deprecation] - messages.each { |msg| deprecation_stream.puts msg } - deprecation_stream.puts - end - end - end - - # @private - # Not really a stream, but is usable in place of one. - class RaiseErrorStream - def puts(message) - raise DeprecationError, message - end - - def summarize(summary_stream, deprecation_count) - summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} found." - end - end - - # @private - # Wraps a File object and provides file-specific operations. - class FileStream - def initialize(file) - @file = file - - # In one of my test suites, I got lots of duplicate output in the - # deprecation file (e.g. 200 of the same deprecation, even though - # the `puts` below was only called 6 times). Setting `sync = true` - # fixes this (but we really have no idea why!). - @file.sync = true - end - - def puts(*args) - @file.puts(*args) - end - - def summarize(summary_stream, deprecation_count) - path = @file.respond_to?(:path) ? @file.path : @file.inspect - summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} logged to #{path}" - puts RAISE_ERROR_CONFIG_NOTICE - end - end - end - end - - # Deprecation Error. - DeprecationError = Class.new(StandardError) - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb deleted file mode 100644 index f64919c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/documentation_formatter.rb +++ /dev/null @@ -1,102 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/base_text_formatter" -RSpec::Support.require_rspec_core "formatters/console_codes" - -module RSpec - module Core - module Formatters - # @private - class DocumentationFormatter < BaseTextFormatter - Formatters.register self, :example_started, :example_group_started, :example_group_finished, - :example_passed, :example_pending, :example_failed - - def initialize(output) - super - @group_level = 0 - - @example_running = false - @messages = [] - end - - def example_started(_notification) - @example_running = true - end - - def example_group_started(notification) - output.puts if @group_level == 0 - output.puts "#{current_indentation}#{notification.group.description.strip}" - - @group_level += 1 - end - - def example_group_finished(_notification) - @group_level -= 1 if @group_level > 0 - end - - def example_passed(passed) - output.puts passed_output(passed.example) - - flush_messages - @example_running = false - end - - def example_pending(pending) - output.puts pending_output(pending.example, - pending.example.execution_result.pending_message) - - flush_messages - @example_running = false - end - - def example_failed(failure) - output.puts failure_output(failure.example) - - flush_messages - @example_running = false - end - - def message(notification) - if @example_running - @messages << notification.message - else - output.puts "#{current_indentation}#{notification.message}" - end - end - - private - - def flush_messages - @messages.each do |message| - output.puts "#{current_indentation(1)}#{message}" - end - - @messages.clear - end - - def passed_output(example) - ConsoleCodes.wrap("#{current_indentation}#{example.description.strip}", :success) - end - - def pending_output(example, message) - ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \ - "(PENDING: #{message})", - :pending) - end - - def failure_output(example) - ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \ - "(FAILED - #{next_failure_index})", - :failure) - end - - def next_failure_index - @next_failure_index ||= 0 - @next_failure_index += 1 - end - - def current_indentation(offset=0) - ' ' * (@group_level + offset) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb deleted file mode 100644 index 1f9ed37..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/exception_presenter.rb +++ /dev/null @@ -1,553 +0,0 @@ -# encoding: utf-8 -RSpec::Support.require_rspec_core "formatters/console_codes" -RSpec::Support.require_rspec_core "formatters/snippet_extractor" -RSpec::Support.require_rspec_core 'formatters/syntax_highlighter' -RSpec::Support.require_rspec_support "encoded_string" - -module RSpec - module Core - module Formatters - # @private - class ExceptionPresenter - attr_reader :exception, :example, :description, :message_color, - :detail_formatter, :extra_detail_formatter, :backtrace_formatter - private :message_color, :detail_formatter, :extra_detail_formatter, :backtrace_formatter - - def initialize(exception, example, options={}) - @exception = exception - @example = example - @message_color = options.fetch(:message_color) { RSpec.configuration.failure_color } - @description = options.fetch(:description) { example.full_description } - @detail_formatter = options.fetch(:detail_formatter) { Proc.new {} } - @extra_detail_formatter = options.fetch(:extra_detail_formatter) { Proc.new {} } - @backtrace_formatter = options.fetch(:backtrace_formatter) { RSpec.configuration.backtrace_formatter } - @indentation = options.fetch(:indentation, 2) - @skip_shared_group_trace = options.fetch(:skip_shared_group_trace, false) - @failure_lines = options[:failure_lines] - end - - def message_lines - add_shared_group_lines(failure_lines, Notifications::NullColorizer) - end - - def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - add_shared_group_lines(failure_lines, colorizer).map do |line| - colorizer.wrap line, message_color - end - end - - def formatted_backtrace(exception=@exception) - backtrace_formatter.format_backtrace(exception.backtrace, example.metadata) + - formatted_cause(exception) - end - - if RSpec::Support::RubyFeatures.supports_exception_cause? - def formatted_cause(exception) - last_cause = final_exception(exception, [exception]) - cause = [] - - if exception.cause - cause << '------------------' - cause << '--- Caused by: ---' - cause << "#{exception_class_name(last_cause)}:" unless exception_class_name(last_cause) =~ /RSpec/ - - encoded_string(exception_message_string(last_cause)).split("\n").each do |line| - cause << " #{line}" - end - - unless last_cause.backtrace.nil? || last_cause.backtrace.empty? - lines = backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata) - lines = [lines[0]] unless RSpec.configuration.full_cause_backtrace # rubocop:disable Metrics/BlockNesting - - lines.each do |line| - cause << (" #{line}") - end - end - end - - cause - end - else - # :nocov: - def formatted_cause(_) - [] - end - # :nocov: - end - - def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - formatted_backtrace.map do |backtrace_info| - colorizer.wrap "# #{backtrace_info}", RSpec.configuration.detail_color - end - end - - def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) - lines = fully_formatted_lines(failure_number, colorizer) - lines.join("\n") << "\n" - end - - def fully_formatted_lines(failure_number, colorizer) - lines = [ - encoded_description(description), - detail_formatter.call(example, colorizer), - formatted_message_and_backtrace(colorizer), - extra_detail_formatter.call(failure_number, colorizer), - ].compact.flatten - - lines = indent_lines(lines, failure_number) - lines.unshift("") - lines - end - - private - - def final_exception(exception, previous=[]) - cause = exception.cause - - if cause && Exception === cause && !previous.include?(cause) - previous << cause - final_exception(cause, previous) - else - exception - end - end - - if String.method_defined?(:encoding) - def encoding_of(string) - string.encoding - end - - def encoded_string(string) - RSpec::Support::EncodedString.new(string, Encoding.default_external) - end - else # for 1.8.7 - # :nocov: - def encoding_of(_string) - end - - def encoded_string(string) - RSpec::Support::EncodedString.new(string) - end - # :nocov: - end - - def indent_lines(lines, failure_number) - alignment_basis = ' ' * @indentation - alignment_basis << "#{failure_number}) " if failure_number - indentation = ' ' * alignment_basis.length - - lines.each_with_index.map do |line, index| - if index == 0 - "#{alignment_basis}#{line}" - elsif line.empty? - line - else - "#{indentation}#{line}" - end - end - end - - def exception_class_name(exception=@exception) - name = exception.class.name.to_s - name = "(anonymous error class)" if name == '' - name - end - - def failure_lines - @failure_lines ||= [].tap do |lines| - lines.concat(failure_slash_error_lines) - - sections = [failure_slash_error_lines, exception_lines] - if sections.any? { |section| section.size > 1 } && !exception_lines.first.empty? - lines << '' - end - - lines.concat(exception_lines) - lines.concat(extra_failure_lines) - end - end - - def failure_slash_error_lines - lines = read_failed_lines - if lines.count == 1 - lines[0] = "Failure/Error: #{lines[0].strip}" - else - least_indentation = SnippetExtractor.least_indentation_from(lines) - lines = lines.map { |line| line.sub(/^#{least_indentation}/, ' ') } - lines.unshift('Failure/Error:') - end - lines - end - - # rubocop:disable Lint/RescueException - # :nocov: - if SyntaxError.instance_methods.include?(:detailed_message) - def exception_message_string(exception) - case exception - when SyntaxError then exception.detailed_message.to_s - else - exception.message.to_s - end - rescue Exception => other - "A #{exception.class} for which `exception.message.to_s` raises #{other.class}." - end - else - def exception_message_string(exception) - exception.message.to_s - rescue Exception => other - "A #{exception.class} for which `exception.message.to_s` raises #{other.class}." - end - end - # :nocov: - # rubocop:enable Lint/RescueException - - def exception_lines - @exception_lines ||= begin - lines = [] - lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/ - encoded_string(exception_message_string(exception)).split("\n").each do |line| - lines << (line.empty? ? line : " #{line}") - end - lines - end - end - - def extra_failure_lines - @extra_failure_lines ||= begin - lines = Array(example.metadata[:extra_failure_lines]) - unless lines.empty? - lines.unshift('') unless lines.first == '' - lines.push('') unless lines.last == '' - end - lines - end - end - - def add_shared_group_lines(lines, colorizer) - return lines if @skip_shared_group_trace - - example.metadata[:shared_group_inclusion_backtrace].each do |frame| - lines << colorizer.wrap(frame.description, RSpec.configuration.default_color) - end - - lines - end - - def read_failed_lines - matching_line = find_failed_line - unless matching_line - return ["Unable to find matching line from backtrace"] - end - - file_and_line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/) - - unless file_and_line_number - return ["Unable to infer file and line number from backtrace"] - end - - file_path, line_number = file_and_line_number[1..2] - max_line_count = RSpec.configuration.max_displayed_failure_line_count - lines = SnippetExtractor.extract_expression_lines_at(file_path, line_number.to_i, max_line_count) - RSpec.world.syntax_highlighter.highlight(lines) - rescue SnippetExtractor::NoSuchFileError - ["Unable to find #{file_path} to read failed line"] - rescue SnippetExtractor::NoSuchLineError - ["Unable to find matching line in #{file_path}"] - rescue SecurityError - # :nocov: - SecurityError is no longer produced starting in ruby 2.7 - ["Unable to read failed line"] - # :nocov: - end - - def find_failed_line - line_regex = RSpec.configuration.in_project_source_dir_regex - loaded_spec_files = RSpec.configuration.loaded_spec_files - - reduced_backtrace = - exception_backtrace.reject do |line| - line.start_with?(" "#{@example.full_description} FIXED", - :message_color => RSpec.configuration.fixed_color, - :failure_lines => [ - "Expected pending '#{@execution_result.pending_message}' to fail. No error was raised." - ] - } - elsif @execution_result.status == :pending - options = { - :message_color => RSpec.configuration.pending_color, - :detail_formatter => PENDING_DETAIL_FORMATTER - } - if RSpec.configuration.pending_failure_output == :no_backtrace - options[:backtrace_formatter] = EmptyBacktraceFormatter - end - options - end - end - - def with_multiple_error_options_as_needed(exception, options) - return options unless multiple_exceptions_error?(exception) - - options = options.merge( - :failure_lines => [], - :extra_detail_formatter => sub_failure_list_formatter(exception, options[:message_color]), - :detail_formatter => multiple_exception_summarizer(exception, - options[:detail_formatter], - options[:message_color]) - ) - - return options unless exception.aggregation_metadata[:hide_backtrace] - options[:backtrace_formatter] = EmptyBacktraceFormatter - options - end - - def multiple_exceptions_error?(exception) - MultipleExceptionError::InterfaceTag === exception - end - - def multiple_exception_summarizer(exception, prior_detail_formatter, color) - lambda do |example, colorizer| - summary = if exception.aggregation_metadata[:hide_backtrace] - # Since the backtrace is hidden, the subfailures will come - # immediately after this, and using `:` will read well. - "Got #{exception.exception_count_description}:" - else - # The backtrace comes after this, so using a `:` doesn't make sense - # since the failures may be many lines below. - "#{exception.summary}." - end - - summary = colorizer.wrap(summary, color || RSpec.configuration.failure_color) - return summary unless prior_detail_formatter - [ - prior_detail_formatter.call(example, colorizer), - summary - ] - end - end - - def sub_failure_list_formatter(exception, message_color) - common_backtrace_truncater = CommonBacktraceTruncater.new(exception) - - lambda do |failure_number, colorizer| - FlatMap.flat_map(exception.all_exceptions.each_with_index) do |failure, index| - options = with_multiple_error_options_as_needed( - failure, - :description => nil, - :indentation => 0, - :message_color => message_color || RSpec.configuration.failure_color, - :skip_shared_group_trace => true - ) - - failure = common_backtrace_truncater.with_truncated_backtrace(failure) - presenter = ExceptionPresenter.new(failure, @example, options) - presenter.fully_formatted_lines( - "#{"#{failure_number}." if failure_number}#{index + 1}", - colorizer - ) - end - end - end - - # @private - # Used to prevent a confusing backtrace from showing up from the `aggregate_failures` - # block declared for `:aggregate_failures` metadata. - module EmptyBacktraceFormatter - def self.format_backtrace(*) - [] - end - end - - # @private - class CommonBacktraceTruncater - def initialize(parent) - @parent = parent - end - - def with_truncated_backtrace(child) - child_bt = child.backtrace - parent_bt = @parent.backtrace - return child if child_bt.nil? || child_bt.empty? || parent_bt.nil? - - index_before_first_common_frame = -1.downto(-child_bt.size).find do |index| - parent_bt[index] != child_bt[index] - end - - return child if index_before_first_common_frame.nil? - return child if index_before_first_common_frame == -1 - - child = child.dup - child.set_backtrace(child_bt[0..index_before_first_common_frame]) - child - end - end - end - - # @private - PENDING_DETAIL_FORMATTER = Proc.new do |example, colorizer| - colorizer.wrap("# #{example.execution_result.pending_message}", :detail) - end - end - end - - # Provides a single exception instance that provides access to - # multiple sub-exceptions. This is used in situations where a single - # individual spec has multiple exceptions, such as one in the `it` block - # and one in an `after` block. - class MultipleExceptionError < StandardError - # @private - # Used so there is a common module in the ancestor chain of this class - # and `RSpec::Expectations::MultipleExpectationsNotMetError`, which allows - # code to detect exceptions that are instances of either, without first - # checking to see if rspec-expectations is loaded. - module InterfaceTag - # Appends the provided exception to the list. - # @param exception [Exception] Exception to append to the list. - # @private - def add(exception) - # `PendingExampleFixedError` can be assigned to an example that initially has no - # failures, but when the `aggregate_failures` around hook completes, it notifies of - # a failure. If we do not ignore `PendingExampleFixedError` it would be surfaced to - # the user as part of a multiple exception error, which is undesirable. While it's - # pretty weird we handle this here, it's the best solution I've been able to come - # up with, and `PendingExampleFixedError` always represents the _lack_ of any exception - # so clearly when we are transitioning to a `MultipleExceptionError`, it makes sense to - # ignore it. - return if Pending::PendingExampleFixedError === exception - - return if exception == self - - all_exceptions << exception - - if exception.class.name =~ /RSpec/ - failures << exception - else - other_errors << exception - end - end - - # Provides a way to force `ex` to be something that satisfies the multiple - # exception error interface. If it already satisfies it, it will be returned; - # otherwise it will wrap it in a `MultipleExceptionError`. - # @private - def self.for(ex) - return ex if self === ex - MultipleExceptionError.new(ex) - end - end - - include InterfaceTag - - # @return [Array] The list of failures. - attr_reader :failures - - # @return [Array] The list of other errors. - attr_reader :other_errors - - # @return [Array] The list of failures and other exceptions, combined. - attr_reader :all_exceptions - - # @return [Hash] Metadata used by RSpec for formatting purposes. - attr_reader :aggregation_metadata - - # @return [nil] Provided only for interface compatibility with - # `RSpec::Expectations::MultipleExpectationsNotMetError`. - attr_reader :aggregation_block_label - - # @param exceptions [Array] The initial list of exceptions. - def initialize(*exceptions) - super() - - @failures = [] - @other_errors = [] - @all_exceptions = [] - @aggregation_metadata = { :hide_backtrace => true } - @aggregation_block_label = nil - - exceptions.each { |e| add e } - end - - # @return [String] Combines all the exception messages into a single string. - # @note RSpec does not actually use this -- instead it formats each exception - # individually. - def message - all_exceptions.map(&:message).join("\n\n") - end - - # @return [String] A summary of the failure, including the block label and a count of failures. - def summary - "Got #{exception_count_description}" - end - - # return [String] A description of the failure/error counts. - def exception_count_description - failure_count = Formatters::Helpers.pluralize(failures.size, "failure") - return failure_count if other_errors.empty? - error_count = Formatters::Helpers.pluralize(other_errors.size, "other error") - "#{failure_count} and #{error_count}" - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb deleted file mode 100644 index a071dfe..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/failure_list_formatter.rb +++ /dev/null @@ -1,23 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/base_formatter" - -module RSpec - module Core - module Formatters - # @private - class FailureListFormatter < BaseFormatter - Formatters.register self, :example_failed, :dump_profile, :message - - def example_failed(failure) - output.puts "#{failure.example.location}:#{failure.example.description}" - end - - # Discard profile and messages - # - # These outputs are not really relevant in the context of this failure - # list formatter. - def dump_profile(_profile); end - def message(_message); end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb deleted file mode 100644 index db4423f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/fallback_message_formatter.rb +++ /dev/null @@ -1,28 +0,0 @@ -module RSpec - module Core - module Formatters - # @api private - # Formatter for providing message output as a fallback when no other - # profiler implements #message - class FallbackMessageFormatter - Formatters.register self, :message - - def initialize(output) - @output = output - end - - # @private - attr_reader :output - - # @api public - # - # Used by the reporter to send messages to the output stream. - # - # @param notification [MessageNotification] containing message - def message(notification) - output.puts notification.message - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb deleted file mode 100644 index f62709d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/helpers.rb +++ /dev/null @@ -1,118 +0,0 @@ -RSpec::Support.require_rspec_core "shell_escape" - -module RSpec - module Core - module Formatters - # Formatters helpers. - module Helpers - # @private - SUB_SECOND_PRECISION = 5 - - # @private - DEFAULT_PRECISION = 2 - - # @api private - # - # Formats seconds into a human-readable string. - # - # @param duration [Float, Fixnum] in seconds - # @return [String] human-readable time - # - # @example - # format_duration(1) #=> "1 minute 1 second" - # format_duration(135.14) #=> "2 minutes 15.14 seconds" - def self.format_duration(duration) - precision = case - when duration < 1 then SUB_SECOND_PRECISION - when duration < 120 then DEFAULT_PRECISION - when duration < 300 then 1 - else 0 - end - - if duration > 60 - minutes = (duration.round / 60).to_i - seconds = (duration - minutes * 60) - - "#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds, precision), 'second')}" - else - pluralize(format_seconds(duration, precision), 'second') - end - end - - # @api private - # - # Formats seconds to have 5 digits of precision with trailing zeros - # removed if the number is less than 1 or with 2 digits of precision if - # the number is greater than zero. - # - # @param float [Float] - # @return [String] formatted float - # - # @example - # format_seconds(0.000006) #=> "0.00001" - # format_seconds(0.020000) #=> "0.02" - # format_seconds(1.00000000001) #=> "1" - # - # The precision used is set in {Helpers::SUB_SECOND_PRECISION} and - # {Helpers::DEFAULT_PRECISION}. - # - # @see #strip_trailing_zeroes - def self.format_seconds(float, precision=nil) - return '0' if float < 0 - precision ||= (float < 1) ? SUB_SECOND_PRECISION : DEFAULT_PRECISION - formatted = "%.#{precision}f" % float - strip_trailing_zeroes(formatted) - end - - # @api private - # - # Remove trailing zeros from a string. - # - # Only remove trailing zeros after a decimal place. - # see: http://rubular.com/r/ojtTydOgpn - # - # @param string [String] string with trailing zeros - # @return [String] string with trailing zeros removed - def self.strip_trailing_zeroes(string) - string.sub(/(?:(\..*[^0])0+|\.0+)$/, '\1') - end - private_class_method :strip_trailing_zeroes - - # @api private - # - # Pluralize a word based on a count. - # - # @param count [Fixnum] number of objects - # @param string [String] word to be pluralized - # @return [String] pluralized word - def self.pluralize(count, string) - pluralized_string = if count.to_f == 1 - string - elsif string.end_with?('s') # e.g. "process" - "#{string}es" # e.g. "processes" - else - "#{string}s" - end - - "#{count} #{pluralized_string}" - end - - # @api private - # Given a list of example ids, organizes them into a compact, ordered list. - def self.organize_ids(ids) - grouped = ids.inject(Hash.new { |h, k| h[k] = [] }) do |hash, id| - file, id = Example.parse_id(id) - hash[file] << id - hash - end - - grouped.sort_by(&:first).map do |file, grouped_ids| - grouped_ids = grouped_ids.sort_by { |id| id.split(':').map(&:to_i) } - id = Metadata.id_from(:rerun_file_path => file, :scoped_id => grouped_ids.join(',')) - ShellEscape.conditionally_quote(id) - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb deleted file mode 100644 index e7eff66..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_formatter.rb +++ /dev/null @@ -1,153 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/base_text_formatter" -RSpec::Support.require_rspec_core "formatters/html_printer" - -module RSpec - module Core - module Formatters - # @private - class HtmlFormatter < BaseFormatter - Formatters.register self, :start, :example_group_started, :start_dump, - :example_started, :example_passed, :example_failed, - :example_pending, :dump_summary - - def initialize(output) - super(output) - @failed_examples = [] - @example_group_number = 0 - @example_number = 0 - @header_red = nil - @printer = HtmlPrinter.new(output) - end - - def start(notification) - super - @printer.print_html_start - @printer.flush - end - - def example_group_started(notification) - super - @example_group_red = false - @example_group_number += 1 - - @printer.print_example_group_end unless example_group_number == 1 - @printer.print_example_group_start(example_group_number, - notification.group.description, - notification.group.parent_groups.size) - @printer.flush - end - - def start_dump(_notification) - @printer.print_example_group_end - @printer.flush - end - - def example_started(_notification) - @example_number += 1 - end - - def example_passed(passed) - @printer.move_progress(percent_done) - @printer.print_example_passed(passed.example.description, passed.example.execution_result.run_time) - @printer.flush - end - - def example_failed(failure) - @failed_examples << failure.example - unless @header_red - @header_red = true - @printer.make_header_red - end - - unless @example_group_red - @example_group_red = true - @printer.make_example_group_header_red(example_group_number) - end - - @printer.move_progress(percent_done) - - example = failure.example - - exception = failure.exception - message_lines = failure.fully_formatted_lines(nil, RSpec::Core::Notifications::NullColorizer) - exception_details = if exception - { - # drop 2 removes the description (regardless of newlines) and leading blank line - :message => message_lines.drop(2).join("\n"), - :backtrace => failure.formatted_backtrace.join("\n"), - } - end - extra = extra_failure_content(failure) - - @printer.print_example_failed( - example.execution_result.pending_fixed, - example.description, - example.execution_result.run_time, - @failed_examples.size, - exception_details, - (extra == "") ? false : extra - ) - @printer.flush - end - - def example_pending(pending) - example = pending.example - - @printer.make_header_yellow unless @header_red - @printer.make_example_group_header_yellow(example_group_number) unless @example_group_red - @printer.move_progress(percent_done) - @printer.print_example_pending(example.description, example.execution_result.pending_message) - @printer.flush - end - - def dump_summary(summary) - @printer.print_summary( - summary.duration, - summary.example_count, - summary.failure_count, - summary.pending_count - ) - @printer.flush - end - - private - - # If these methods are declared with attr_reader Ruby will issue a - # warning because they are private. - # rubocop:disable Style/TrivialAccessors - - # The number of the currently running example_group. - def example_group_number - @example_group_number - end - - # The number of the currently running example (a global counter). - def example_number - @example_number - end - # rubocop:enable Style/TrivialAccessors - - def percent_done - result = 100.0 - if @example_count > 0 - result = (((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0).to_f - end - result - end - - # Override this method if you wish to output extra HTML for a failed - # spec. For example, you could output links to images or other files - # produced during the specs. - def extra_failure_content(failure) - RSpec::Support.require_rspec_core "formatters/html_snippet_extractor" - backtrace = (failure.exception.backtrace || []).map do |line| - RSpec.configuration.backtrace_formatter.backtrace_line(line) - end - backtrace.compact! - @snippet_extractor ||= HtmlSnippetExtractor.new - "
#{@snippet_extractor.snippet(backtrace)}
" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb deleted file mode 100644 index 79d27e1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_printer.rb +++ /dev/null @@ -1,412 +0,0 @@ -require 'erb' - -module RSpec - module Core - module Formatters - # @private - class HtmlPrinter - include ERB::Util # For the #h method. - def initialize(output) - @output = output - end - - def print_html_start - @output.puts HTML_HEADER - @output.puts REPORT_HEADER - end - - def print_example_group_end - @output.puts " " - @output.puts "" - end - - def print_example_group_start(group_id, description, number_of_parents) - @output.puts "
" - @output.puts "
" - @output.puts "
#{h(description)}
" - end - - def print_example_passed(description, run_time) - formatted_run_time = "%.5f" % run_time - @output.puts "
" \ - "#{h(description)}" \ - "#{formatted_run_time}s
" - end - - def print_example_failed(pending_fixed, description, run_time, failure_id, - exception, extra_content) - formatted_run_time = "%.5f" % run_time - - @output.puts "
" - @output.puts " #{h(description)}" - @output.puts " #{formatted_run_time}s" - @output.puts "
" - if exception - @output.puts "
#{h(exception[:message])}
" - @output.puts "
#{h exception[:backtrace]}
" - end - @output.puts extra_content if extra_content - @output.puts "
" - @output.puts "
" - end - - def print_example_pending(description, pending_message) - @output.puts "
" \ - "#{h(description)} " \ - "(PENDING: #{h(pending_message)})
" - end - - def print_summary(duration, example_count, failure_count, pending_count) - totals = String.new( - "#{example_count} example#{'s' unless example_count == 1}, " - ) - totals << "#{failure_count} failure#{'s' unless failure_count == 1}" - totals << ", #{pending_count} pending" if pending_count > 0 - - formatted_duration = "%.5f" % duration - - @output.puts "" - @output.puts "" - @output.puts "
" - @output.puts "" - @output.puts "" - @output.puts "" - end - - def flush - @output.flush - end - - def move_progress(percent_done) - @output.puts " " - @output.flush - end - - def make_header_red - @output.puts " " - end - - def make_header_yellow - @output.puts " " - end - - def make_example_group_header_red(group_id) - @output.puts " " - @output.puts " " - end - - def make_example_group_header_yellow(group_id) - @output.puts " " - @output.puts " " - end - - private - - def indentation_style(number_of_parents) - "style=\"margin-left: #{(number_of_parents - 1) * 15}px;\"" - end - - REPORT_HEADER = <<-EOF -
- -
-
-

RSpec Code Examples

-
- -
- - - -
- -
-

 

-

 

-
-
- - -
-EOF - - GLOBAL_SCRIPTS = <<-EOF - -function addClass(element_id, classname) { - document.getElementById(element_id).className += (" " + classname); -} - -function removeClass(element_id, classname) { - var elem = document.getElementById(element_id); - var classlist = elem.className.replace(classname,''); - elem.className = classlist; -} - -function moveProgressBar(percentDone) { - document.getElementById("rspec-header").style.width = percentDone +"%"; -} - -function makeRed(element_id) { - removeClass(element_id, 'passed'); - removeClass(element_id, 'not_implemented'); - addClass(element_id,'failed'); -} - -function makeYellow(element_id) { - var elem = document.getElementById(element_id); - if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed - if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented - removeClass(element_id, 'passed'); - addClass(element_id,'not_implemented'); - } - } -} - -function apply_filters() { - var passed_filter = document.getElementById('passed_checkbox').checked; - var failed_filter = document.getElementById('failed_checkbox').checked; - var pending_filter = document.getElementById('pending_checkbox').checked; - - assign_display_style("example passed", passed_filter); - assign_display_style("example failed", failed_filter); - assign_display_style("example not_implemented", pending_filter); - - assign_display_style_for_group("example_group passed", passed_filter); - assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter); - assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter); -} - -function get_display_style(display_flag) { - var style_mode = 'none'; - if (display_flag == true) { - style_mode = 'block'; - } - return style_mode; -} - -function assign_display_style(classname, display_flag) { - var style_mode = get_display_style(display_flag); - var elems = document.getElementsByClassName(classname) - for (var i=0; i - - - RSpec results - - - - - - - - -EOF - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb deleted file mode 100644 index 992704b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/html_snippet_extractor.rb +++ /dev/null @@ -1,122 +0,0 @@ -module RSpec - module Core - module Formatters - # @api private - # - # Extracts code snippets by looking at the backtrace of the passed error - # and applies synax highlighting and line numbers using html. - class HtmlSnippetExtractor - # @private - module NullConverter - def self.convert(code) - %Q(#{code}\n# Install the coderay gem to get syntax highlighting) - end - end - - # @private - module CoderayConverter - def self.convert(code) - CodeRay.scan(code, :ruby).html(:line_numbers => false) - end - end - - # rubocop:disable Style/ClassVars - # @private - @@converter = NullConverter - - begin - require 'coderay' - RSpec::Support.require_rspec_core 'formatters/syntax_highlighter' - RSpec::Core::Formatters::SyntaxHighlighter.attempt_to_add_rspec_terms_to_coderay_keywords - @@converter = CoderayConverter - # rubocop:disable Lint/HandleExceptions - rescue LoadError - # it'll fall back to the NullConverter assigned above - # rubocop:enable Lint/HandleExceptions - end - - # rubocop:enable Style/ClassVars - - # @api private - # - # Extract lines of code corresponding to a backtrace. - # - # @param backtrace [String] the backtrace from a test failure - # @return [String] highlighted code snippet indicating where the test - # failure occurred - # - # @see #post_process - def snippet(backtrace) - raw_code, line = snippet_for(backtrace[0]) - highlighted = @@converter.convert(raw_code) - post_process(highlighted, line) - end - # rubocop:enable Style/ClassVars - - # @api private - # - # Create a snippet from a line of code. - # - # @param error_line [String] file name with line number (i.e. - # 'foo_spec.rb:12') - # @return [String] lines around the target line within the file - # - # @see #lines_around - def snippet_for(error_line) - if error_line =~ /(.*):(\d+)/ - file = Regexp.last_match[1] - line = Regexp.last_match[2].to_i - [lines_around(file, line), line] - else - ["# Couldn't get snippet for #{error_line}", 1] - end - end - - # @api private - # - # Extract lines of code centered around a particular line within a - # source file. - # - # @param file [String] filename - # @param line [Fixnum] line number - # @return [String] lines around the target line within the file (2 above - # and 1 below). - def lines_around(file, line) - if File.file?(file) - lines = File.read(file).split("\n") - min = [0, line - 3].max - max = [line + 1, lines.length - 1].min - selected_lines = [] - selected_lines.join("\n") - lines[min..max].join("\n") - else - "# Couldn't get snippet for #{file}" - end - rescue SecurityError - # :nocov: - SecurityError is no longer produced starting in ruby 2.7 - "# Couldn't get snippet for #{file}" - # :nocov: - end - - # @api private - # - # Adds line numbers to all lines and highlights the line where the - # failure occurred using html `span` tags. - # - # @param highlighted [String] syntax-highlighted snippet surrounding the - # offending line of code - # @param offending_line [Fixnum] line where failure occurred - # @return [String] completed snippet - def post_process(highlighted, offending_line) - new_lines = [] - highlighted.split("\n").each_with_index do |line, i| - new_line = "#{offending_line + i - 2}#{line}" - new_line = "#{new_line}" if i == 2 - new_lines << new_line - end - new_lines.join("\n") - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb deleted file mode 100644 index 7c6fde8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/json_formatter.rb +++ /dev/null @@ -1,103 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/base_formatter" -require 'json' - -module RSpec - module Core - module Formatters - # @private - class JsonFormatter < BaseFormatter - Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :seed, :close - - attr_reader :output_hash - - def initialize(output) - super - @output_hash = { - :version => RSpec::Core::Version::STRING - } - end - - def message(notification) - (@output_hash[:messages] ||= []) << notification.message - end - - def dump_summary(summary) - @output_hash[:summary] = { - :duration => summary.duration, - :example_count => summary.example_count, - :failure_count => summary.failure_count, - :pending_count => summary.pending_count, - :errors_outside_of_examples_count => summary.errors_outside_of_examples_count - } - @output_hash[:summary_line] = summary.totals_line - end - - def stop(group_notification) - @output_hash[:examples] = group_notification.notifications.map do |notification| - format_example(notification.example).tap do |hash| - e = notification.example.exception - - if e - hash[:exception] = { - :class => e.class.name, - :message => e.message, - :backtrace => notification.formatted_backtrace, - } - end - end - end - end - - def seed(notification) - return unless notification.seed_used? - @output_hash[:seed] = notification.seed - end - - def close(_notification) - output.write @output_hash.to_json - end - - def dump_profile(profile) - @output_hash[:profile] = {} - dump_profile_slowest_examples(profile) - dump_profile_slowest_example_groups(profile) - end - - # @api private - def dump_profile_slowest_examples(profile) - @output_hash[:profile] = {} - @output_hash[:profile][:examples] = profile.slowest_examples.map do |example| - format_example(example).tap do |hash| - hash[:run_time] = example.execution_result.run_time - end - end - @output_hash[:profile][:slowest] = profile.slow_duration - @output_hash[:profile][:total] = profile.duration - end - - # @api private - def dump_profile_slowest_example_groups(profile) - @output_hash[:profile] ||= {} - @output_hash[:profile][:groups] = profile.slowest_groups.map do |loc, hash| - hash.update(:location => loc) - end - end - - private - - def format_example(example) - { - :id => example.id, - :description => example.description, - :full_description => example.full_description, - :status => example.execution_result.status.to_s, - :file_path => example.metadata[:file_path], - :line_number => example.metadata[:line_number], - :run_time => example.execution_result.run_time, - :pending_message => example.execution_result.pending_message, - } - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb deleted file mode 100644 index 4b95d93..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/profile_formatter.rb +++ /dev/null @@ -1,68 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/console_codes" - -module RSpec - module Core - module Formatters - # @api private - # Formatter for providing profile output. - class ProfileFormatter - Formatters.register self, :dump_profile - - def initialize(output) - @output = output - end - - # @private - attr_reader :output - - # @api public - # - # This method is invoked after the dumping the summary if profiling is - # enabled. - # - # @param profile [ProfileNotification] containing duration, - # slowest_examples and slowest_example_groups - def dump_profile(profile) - dump_profile_slowest_examples(profile) - dump_profile_slowest_example_groups(profile) - end - - private - - def dump_profile_slowest_examples(profile) - @output.puts "\nTop #{profile.slowest_examples.size} slowest " \ - "examples (#{Helpers.format_seconds(profile.slow_duration)} " \ - "seconds, #{profile.percentage}% of total time):\n" - - profile.slowest_examples.each do |example| - @output.puts " #{example.full_description}" - @output.puts " #{bold(Helpers.format_seconds(example.execution_result.run_time))} " \ - "#{bold("seconds")} #{format_caller(example.location)}" - end - end - - def dump_profile_slowest_example_groups(profile) - return if profile.slowest_groups.empty? - - @output.puts "\nTop #{profile.slowest_groups.size} slowest example groups:" - profile.slowest_groups.each do |loc, hash| - average = "#{bold(Helpers.format_seconds(hash[:average]))} #{bold("seconds")} average" - total = "#{Helpers.format_seconds(hash[:total_time])} seconds" - count = Helpers.pluralize(hash[:count], "example") - @output.puts " #{hash[:description]}" - @output.puts " #{average} (#{total} / #{count}) #{loc}" - end - end - - def format_caller(caller_info) - RSpec.configuration.backtrace_formatter.backtrace_line( - caller_info.to_s.split(':in `block').first) - end - - def bold(text) - ConsoleCodes.wrap(text, :bold) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb deleted file mode 100644 index 81e0beb..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/progress_formatter.rb +++ /dev/null @@ -1,29 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/base_text_formatter" -RSpec::Support.require_rspec_core "formatters/console_codes" - -module RSpec - module Core - module Formatters - # @private - class ProgressFormatter < BaseTextFormatter - Formatters.register self, :example_passed, :example_pending, :example_failed, :start_dump - - def example_passed(_notification) - output.print ConsoleCodes.wrap('.', :success) - end - - def example_pending(_notification) - output.print ConsoleCodes.wrap('*', :pending) - end - - def example_failed(_notification) - output.print ConsoleCodes.wrap('F', :failure) - end - - def start_dump(_notification) - output.puts - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb deleted file mode 100644 index 12fc71f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/protocol.rb +++ /dev/null @@ -1,182 +0,0 @@ -module RSpec - module Core - module Formatters - # This class isn't loaded at runtime but serves to document all of the - # notifications implemented as part of the standard interface. The - # reporter will issue these during a normal test suite run, but a - # formatter will only receive those notifications it has registered - # itself to receive. To register a formatter call: - # - # `::RSpec::Core::Formatters.register class, :list, :of, :notifications` - # - # e.g. - # - # `::RSpec::Core::Formatters.register self, :start, :example_started` - # - # @see RSpec::Core::Formatters::BaseFormatter - # @see RSpec::Core::Formatters::BaseTextFormatter - # @see RSpec::Core::Reporter - class Protocol - # @method initialize(output) - # @api public - # - # @param output [IO] the formatter output - - # @method start(notification) - # @api public - # @group Suite Notifications - # - # This method is invoked before any examples are run, right after - # they have all been collected. This can be useful for special - # formatters that need to provide progress on feedback (graphical ones). - # - # This will only be invoked once, and the next one to be invoked - # is {#example_group_started}. - # - # @param notification [Notifications::StartNotification] - - # @method example_group_started(notification) - # @api public - # @group Group Notifications - # - # This method is invoked at the beginning of the execution of each - # example group. - # - # The next method to be invoked after this is {#example_passed}, - # {#example_pending}, or {#example_group_finished}. - # - # @param notification [Notifications::GroupNotification] containing example_group - # subclass of {ExampleGroup} - - # @method example_group_finished(notification) - # @api public - # @group Group Notifications - # - # Invoked at the end of the execution of each example group. - # - # @param notification [Notifications::GroupNotification] containing example_group - # subclass of {ExampleGroup} - - # @method example_started(notification) - # @api public - # @group Example Notifications - # - # Invoked at the beginning of the execution of each example. - # - # @param notification [Notifications::ExampleNotification] containing example subclass - # of {Example} - - # @method example_finished(notification) - # @api public - # @group Example Notifications - # - # Invoked at the end of the execution of each example. - # - # @param notification [Notifications::ExampleNotification] containing example subclass - # of {Example} - - # @method example_passed(notification) - # @api public - # @group Example Notifications - # - # Invoked when an example passes. - # - # @param notification [Notifications::ExampleNotification] containing example subclass - # of {Example} - - # @method example_pending(notification) - # @api public - # @group Example Notifications - # - # Invoked when an example is pending. - # - # @param notification [Notifications::ExampleNotification] containing example subclass - # of {Example} - - # @method example_failed(notification) - # @api public - # @group Example Notifications - # - # Invoked when an example fails. - # - # @param notification [Notifications::ExampleNotification] containing example subclass - # of {Example} - - # @method message(notification) - # @api public - # @group Suite Notifications - # - # Used by the reporter to send messages to the output stream. - # - # @param notification [Notifications::MessageNotification] containing message - - # @method stop(notification) - # @api public - # @group Suite Notifications - # - # Invoked after all examples have executed, before dumping post-run - # reports. - # - # @param notification [Notifications::NullNotification] - - # @method start_dump(notification) - # @api public - # @group Suite Notifications - # - # This method is invoked after all of the examples have executed. The - # next method to be invoked after this one is {#dump_failures} - # (BaseTextFormatter then calls {#dump_failures} once for each failed - # example). - # - # @param notification [Notifications::NullNotification] - - # @method dump_failures(notification) - # @api public - # @group Suite Notifications - # - # Dumps detailed information about each example failure. - # - # @param notification [Notifications::NullNotification] - - # @method dump_summary(summary) - # @api public - # @group Suite Notifications - # - # This method is invoked after the dumping of examples and failures. - # Each parameter is assigned to a corresponding attribute. - # - # @param summary [Notifications::SummaryNotification] containing duration, - # example_count, failure_count and pending_count - - # @method dump_profile(profile) - # @api public - # @group Suite Notifications - # - # This method is invoked after the dumping the summary if profiling is - # enabled. - # - # @param profile [Notifications::ProfileNotification] containing duration, - # slowest_examples and slowest_example_groups - - # @method dump_pending(notification) - # @api public - # @group Suite Notifications - # - # Outputs a report of pending examples. This gets invoked - # after the summary if option is set to do so. - # - # @param notification [Notifications::NullNotification] - - # @method close(notification) - # @api public - # @group Suite Notifications - # - # Invoked at the end of a suite run. Allows the formatter to do any - # tidying up, but be aware that formatter output streams may be used - # elsewhere so don't actually close them. - # - # @param notification [Notifications::NullNotification] - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb deleted file mode 100644 index c585db4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/snippet_extractor.rb +++ /dev/null @@ -1,134 +0,0 @@ -module RSpec - module Core - module Formatters - # @private - class SnippetExtractor - NoSuchFileError = Class.new(StandardError) - NoSuchLineError = Class.new(StandardError) - - def self.extract_line_at(file_path, line_number) - source = source_from_file(file_path) - line = source.lines[line_number - 1] - raise NoSuchLineError unless line - line - end - - def self.source_from_file(path) - raise NoSuchFileError unless File.exist?(path) - RSpec.world.source_from_file(path) - end - - if RSpec::Support::RubyFeatures.ripper_supported? - NoExpressionAtLineError = Class.new(StandardError) - - attr_reader :source, :beginning_line_number, :max_line_count - - def self.extract_expression_lines_at(file_path, beginning_line_number, max_line_count=nil) - if max_line_count == 1 - [extract_line_at(file_path, beginning_line_number)] - else - source = source_from_file(file_path) - new(source, beginning_line_number, max_line_count).expression_lines - end - end - - def initialize(source, beginning_line_number, max_line_count=nil) - @source = source - @beginning_line_number = beginning_line_number - @max_line_count = max_line_count - end - - def expression_lines - line_range = line_range_of_expression - - if max_line_count && line_range.count > max_line_count - line_range = (line_range.begin)..(line_range.begin + max_line_count - 1) - end - - source.lines[(line_range.begin - 1)..(line_range.end - 1)] - rescue SyntaxError, NoExpressionAtLineError - [self.class.extract_line_at(source.path, beginning_line_number)] - end - - private - - def line_range_of_expression - @line_range_of_expression ||= begin - line_range = line_range_of_location_nodes_in_expression - initial_unclosed_tokens = unclosed_tokens_in_line_range(line_range) - unclosed_tokens = initial_unclosed_tokens - - until (initial_unclosed_tokens & unclosed_tokens).empty? - line_range = (line_range.begin)..(line_range.end + 1) - unclosed_tokens = unclosed_tokens_in_line_range(line_range) - end - - line_range - end - end - - def unclosed_tokens_in_line_range(line_range) - tokens = FlatMap.flat_map(line_range) do |line_number| - source.tokens_by_line_number[line_number] - end - - tokens.each_with_object([]) do |token, unclosed_tokens| - if token.opening? - unclosed_tokens << token - else - index = unclosed_tokens.rindex do |unclosed_token| - unclosed_token.closed_by?(token) - end - unclosed_tokens.delete_at(index) if index - end - end - end - - def line_range_of_location_nodes_in_expression - line_numbers = expression_node.each_with_object(Set.new) do |node, set| - set << node.location.line if node.location - end - - line_numbers.min..line_numbers.max - end - - def expression_node - raise NoExpressionAtLineError if location_nodes_at_beginning_line.empty? - - @expression_node ||= begin - common_ancestor_nodes = location_nodes_at_beginning_line.map do |node| - node.each_ancestor.to_a - end.reduce(:&) - - common_ancestor_nodes.find { |node| expression_outmost_node?(node) } - end - end - - def expression_outmost_node?(node) - return true unless node.parent - return false if node.type.to_s.start_with?('@') - ![node, node.parent].all? do |n| - # See `Ripper::PARSER_EVENTS` for the complete list of sexp types. - type = n.type.to_s - type.end_with?('call') || type.start_with?('method_add_') - end - end - - def location_nodes_at_beginning_line - source.nodes_by_line_number[beginning_line_number] - end - else - # :nocov: - def self.extract_expression_lines_at(file_path, beginning_line_number, *) - [extract_line_at(file_path, beginning_line_number)] - end - # :nocov: - end - - def self.least_indentation_from(lines) - lines.map { |line| line[/^[ \t]*/] }.min - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb deleted file mode 100644 index e7766f6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/formatters/syntax_highlighter.rb +++ /dev/null @@ -1,91 +0,0 @@ -module RSpec - module Core - module Formatters - # @private - # Provides terminal syntax highlighting of code snippets - # when coderay is available. - class SyntaxHighlighter - def initialize(configuration) - @configuration = configuration - end - - def highlight(lines) - implementation.highlight_syntax(lines) - end - - # rubocop:disable Lint/RescueException - # rubocop:disable Lint/HandleExceptions - def self.attempt_to_add_rspec_terms_to_coderay_keywords - CodeRay::Scanners::Ruby::Patterns::IDENT_KIND.add(%w[ - describe context - it specify - before after around - let subject - expect allow - ], :keyword) - rescue Exception - # Mutating CodeRay's contants like this is not a public API - # and might not always work. If we cannot add our keywords - # to CodeRay it is not a big deal and not worth raising an - # error over, so we ignore it. - end - # rubocop:enable Lint/HandleExceptions - # rubocop:enable Lint/RescueException - - private - - if RSpec::Support::OS.windows? - # :nocov: - def implementation - WindowsImplementation - end - # :nocov: - else - def implementation - return color_enabled_implementation if @configuration.color_enabled? - NoSyntaxHighlightingImplementation - end - end - - def color_enabled_implementation - @color_enabled_implementation ||= begin - require 'coderay' - self.class.attempt_to_add_rspec_terms_to_coderay_keywords - CodeRayImplementation - rescue LoadError - NoSyntaxHighlightingImplementation - end - end - - # @private - module CodeRayImplementation - RESET_CODE = "\e[0m" - - def self.highlight_syntax(lines) - highlighted = begin - CodeRay.encode(lines.join("\n"), :ruby, :terminal) - rescue Support::AllExceptionsExceptOnesWeMustNotRescue - return lines - end - - highlighted.split("\n").map do |line| - line.sub(/\S/) { |char| char.insert(0, RESET_CODE) } - end - end - end - - # @private - module NoSyntaxHighlightingImplementation - def self.highlight_syntax(lines) - lines - end - end - - # @private - # Not sure why, but our code above (and/or coderay itself) does not work - # on Windows, so we disable the feature on Windows. - WindowsImplementation = NoSyntaxHighlightingImplementation - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb deleted file mode 100644 index 2935a73..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb +++ /dev/null @@ -1,646 +0,0 @@ -module RSpec - module Core - # Provides `before`, `after` and `around` hooks as a means of - # supporting common setup and teardown. This module is extended - # onto {ExampleGroup}, making the methods available from any `describe` - # or `context` block and included in {Configuration}, making them - # available off of the configuration object to define global setup - # or teardown logic. - module Hooks - # @api public - # - # @overload before(&block) - # @overload before(scope, &block) - # @param scope [Symbol] `:example`, `:context`, or `:suite` - # (defaults to `:example`) - # @overload before(scope, *conditions, &block) - # @param scope [Symbol] `:example`, `:context`, or `:suite` - # (defaults to `:example`) - # @param conditions [Array, Hash] constrains this hook to - # examples matching these conditions e.g. - # `before(:example, :ui => true) { ... }` will only run with examples - # or groups declared with `:ui => true`. Symbols will be transformed - # into hash entries with `true` values. - # @overload before(conditions, &block) - # @param conditions [Hash] - # constrains this hook to examples matching these conditions e.g. - # `before(:example, :ui => true) { ... }` will only run with examples - # or groups declared with `:ui => true`. - # - # @see #after - # @see #around - # @see ExampleGroup - # @see SharedContext - # @see SharedExampleGroup - # @see Configuration - # - # Declare a block of code to be run before each example (using `:example`) - # or once before any example (using `:context`). These are usually - # declared directly in the {ExampleGroup} to which they apply, but they - # can also be shared across multiple groups. - # - # You can also use `before(:suite)` to run a block of code before any - # example groups are run. This should be declared in {RSpec.configure}. - # - # Instance variables declared in `before(:example)` or `before(:context)` - # are accessible within each example. - # - # ### Order - # - # `before` hooks are stored in three scopes, which are run in order: - # `:suite`, `:context`, and `:example`. They can also be declared in - # several different places: `RSpec.configure`, a parent group, the current - # group. They are run in the following order: - # - # before(:suite) # Declared in RSpec.configure. - # before(:context) # Declared in RSpec.configure. - # before(:context) # Declared in a parent group. - # before(:context) # Declared in the current group. - # before(:example) # Declared in RSpec.configure. - # before(:example) # Declared in a parent group. - # before(:example) # Declared in the current group. - # - # If more than one `before` is declared within any one example group, they - # are run in the order in which they are declared. Any `around` hooks will - # execute after `before` context hooks but before any `before` example - # hook regardless of where they are declared. - # - # ### Conditions - # - # When you add a conditions hash to `before(:example)` or - # `before(:context)`, RSpec will only apply that hook to groups or - # examples that match the conditions. e.g. - # - # RSpec.configure do |config| - # config.before(:example, :authorized => true) do - # log_in_as :authorized_user - # end - # end - # - # RSpec.describe Something, :authorized => true do - # # The before hook will run in before each example in this group. - # end - # - # RSpec.describe SomethingElse do - # it "does something", :authorized => true do - # # The before hook will run before this example. - # end - # - # it "does something else" do - # # The hook will not run before this example. - # end - # end - # - # Note that filtered config `:context` hooks can still be applied - # to individual examples that have matching metadata. Just like - # Ruby's object model is that every object has a singleton class - # which has only a single instance, RSpec's model is that every - # example has a singleton example group containing just the one - # example. - # - # ### Warning: `before(:suite, :with => :conditions)` - # - # The conditions hash is used to match against specific examples. Since - # `before(:suite)` is not run in relation to any specific example or - # group, conditions passed along with `:suite` are effectively ignored. - # - # ### Exceptions - # - # When an exception is raised in a `before` block, RSpec skips any - # subsequent `before` blocks and the example, but runs all of the - # `after(:example)` and `after(:context)` hooks. - # - # ### Warning: implicit before blocks - # - # `before` hooks can also be declared in shared contexts which get - # included implicitly either by you or by extension libraries. Since - # RSpec runs these in the order in which they are declared within each - # scope, load order matters, and can lead to confusing results when one - # before block depends on state that is prepared in another before block - # that gets run later. - # - # ### Warning: `before(:context)` - # - # It is very tempting to use `before(:context)` to speed things up, but we - # recommend that you avoid this as there are a number of gotchas, as well - # as things that simply don't work. - # - # #### Context - # - # `before(:context)` is run in an example that is generated to provide - # group context for the block. - # - # #### Instance variables - # - # Instance variables declared in `before(:context)` are shared across all - # the examples in the group. This means that each example can change the - # state of a shared object, resulting in an ordering dependency that can - # make it difficult to reason about failures. - # - # #### Unsupported RSpec constructs - # - # RSpec has several constructs that reset state between each example - # automatically. These are not intended for use from within - # `before(:context)`: - # - # * `let` declarations - # * `subject` declarations - # * Any mocking, stubbing or test double declaration - # - # ### other frameworks - # - # Mock object frameworks and database transaction managers (like - # ActiveRecord) are typically designed around the idea of setting up - # before an example, running that one example, and then tearing down. This - # means that mocks and stubs can (sometimes) be declared in - # `before(:context)`, but get torn down before the first real example is - # ever run. - # - # You _can_ create database-backed model objects in a `before(:context)` - # in rspec-rails, but it will not be wrapped in a transaction for you, so - # you are on your own to clean up in an `after(:context)` block. - # - # @example before(:example) declared in an {ExampleGroup} - # - # RSpec.describe Thing do - # before(:example) do - # @thing = Thing.new - # end - # - # it "does something" do - # # Here you can access @thing. - # end - # end - # - # @example before(:context) declared in an {ExampleGroup} - # - # RSpec.describe Parser do - # before(:context) do - # File.open(file_to_parse, 'w') do |f| - # f.write <<-CONTENT - # stuff in the file - # CONTENT - # end - # end - # - # it "parses the file" do - # Parser.parse(file_to_parse) - # end - # - # after(:context) do - # File.delete(file_to_parse) - # end - # end - # - # @note The `:example` and `:context` scopes are also available as - # `:each` and `:all`, respectively. Use whichever you prefer. - # @note The `:suite` scope is only supported for hooks registered on - # `RSpec.configuration` since they exist independently of any - # example or example group. - def before(*args, &block) - hooks.register :append, :before, *args, &block - end - - alias_method :append_before, :before - - # Adds `block` to the front of the list of `before` blocks in the same - # scope (`:example`, `:context`, or `:suite`). - # - # See {#before} for scoping semantics. - def prepend_before(*args, &block) - hooks.register :prepend, :before, *args, &block - end - - # @api public - # @overload after(&block) - # @overload after(scope, &block) - # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to - # `:example`) - # @overload after(scope, *conditions, &block) - # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to - # `:example`) - # @param conditions [Array, Hash] constrains this hook to - # examples matching these conditions e.g. - # `after(:example, :ui => true) { ... }` will only run with examples - # or groups declared with `:ui => true`. Symbols will be transformed - # into hash entries with `true` values. - # @overload after(conditions, &block) - # @param conditions [Hash] - # constrains this hook to examples matching these conditions e.g. - # `after(:example, :ui => true) { ... }` will only run with examples - # or groups declared with `:ui => true`. - # - # @see #before - # @see #around - # @see ExampleGroup - # @see SharedContext - # @see SharedExampleGroup - # @see Configuration - # - # Declare a block of code to be run after each example (using `:example`) - # or once after all examples n the context (using `:context`). See - # {#before} for more information about ordering. - # - # ### Exceptions - # - # `after` hooks are guaranteed to run even when there are exceptions in - # `before` hooks or examples. When an exception is raised in an after - # block, the exception is captured for later reporting, and subsequent - # `after` blocks are run. - # - # ### Order - # - # `after` hooks are stored in three scopes, which are run in order: - # `:example`, `:context`, and `:suite`. They can also be declared in - # several different places: `RSpec.configure`, a parent group, the current - # group. They are run in the following order: - # - # after(:example) # Declared in the current group. - # after(:example) # Declared in a parent group. - # after(:example) # Declared in RSpec.configure. - # after(:context) # Declared in the current group. - # after(:context) # Declared in a parent group. - # after(:context) # Declared in RSpec.configure. - # after(:suite) # Declared in RSpec.configure. - # - # This is the reverse of the order in which `before` hooks are run. - # Similarly, if more than one `after` is declared within any example - # group, they are run in reverse order of that in which they are declared. - # Also `around` hooks will run after any `after` example hooks are - # invoked but before any `after` context hooks. - # - # @note The `:example` and `:context` scopes are also available as - # `:each` and `:all`, respectively. Use whichever you prefer. - # @note The `:suite` scope is only supported for hooks registered on - # `RSpec.configuration` since they exist independently of any - # example or example group. - def after(*args, &block) - hooks.register :prepend, :after, *args, &block - end - - alias_method :prepend_after, :after - - # Adds `block` to the back of the list of `after` blocks in the same - # scope (`:example`, `:context`, or `:suite`). - # - # See {#after} for scoping semantics. - def append_after(*args, &block) - hooks.register :append, :after, *args, &block - end - - # @api public - # @overload around(&block) - # @overload around(scope, &block) - # @param scope [Symbol] `:example` (defaults to `:example`) - # present for syntax parity with `before` and `after`, but - # `:example`/`:each` is the only supported value. - # @overload around(scope, *conditions, &block) - # @param scope [Symbol] `:example` (defaults to `:example`) - # present for syntax parity with `before` and `after`, but - # `:example`/`:each` is the only supported value. - # @param conditions [Array, Hash] constrains this hook to - # examples matching these conditions e.g. - # `around(:example, :ui => true) { ... }` will only run with examples - # or groups declared with `:ui => true`. Symbols will be transformed - # into hash entries with `true` values. - # @overload around(conditions, &block) - # @param conditions [Hash] constrains this hook to examples matching - # these conditions e.g. `around(:example, :ui => true) { ... }` will - # only run with examples or groups declared with `:ui => true`. - # - # @yield [Example] the example to run - # - # @note the syntax of `around` is similar to that of `before` and `after` - # but the semantics are quite different. `before` and `after` hooks are - # run in the context of the examples with which they are associated, - # whereas `around` hooks are actually responsible for running the - # examples. Consequently, `around` hooks do not have direct access to - # resources that are made available within the examples and their - # associated `before` and `after` hooks. - # - # @note `:example`/`:each` is the only supported scope. - # - # Declare a block of code, parts of which will be run before and parts - # after the example. It is your responsibility to run the example: - # - # around(:example) do |ex| - # # Do some stuff before. - # ex.run - # # Do some stuff after. - # end - # - # The yielded example aliases `run` with `call`, which lets you treat it - # like a `Proc`. This is especially handy when working with libraries - # that manage their own setup and teardown using a block or proc syntax, - # e.g. - # - # around(:example) {|ex| Database.transaction(&ex)} - # around(:example) {|ex| FakeFS(&ex)} - # - # ### Order - # - # The `around` hooks execute surrounding an example and its hooks. - # - # This means after any `before` context hooks, but before any `before` - # example hooks, and similarly after any `after` example hooks but before - # any `after` context hooks. - # - # They are not a synonym for `before`/`after`. - def around(*args, &block) - hooks.register :prepend, :around, *args, &block - end - - # @private - # Holds the various registered hooks. - def hooks - @hooks ||= HookCollections.new(self, FilterableItemRepository::UpdateOptimized) - end - - # @private - Hook = Struct.new(:block, :options) - - # @private - class BeforeHook < Hook - def run(example) - example.instance_exec(example, &block) - end - end - - # @private - class AfterHook < Hook - def run(example) - example.instance_exec(example, &block) - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex - example.set_exception(ex) - end - end - - # @private - class AfterContextHook < Hook - def run(example) - example.instance_exec(example, &block) - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e - RSpec.configuration.reporter.notify_non_example_exception(e, "An error occurred in an `after(:context)` hook.") - end - end - - # @private - class AroundHook < Hook - def execute_with(example, procsy) - example.instance_exec(procsy, &block) - return if procsy.executed? - Pending.mark_skipped!(example, - "#{hook_description} did not execute the example") - end - - if Proc.method_defined?(:source_location) - def hook_description - "around hook at #{Metadata.relative_path(block.source_location.join(':'))}" - end - else # for 1.8.7 - # :nocov: - def hook_description - "around hook" - end - # :nocov: - end - end - - # @private - # - # This provides the primary API used by other parts of rspec-core. By hiding all - # implementation details behind this facade, it's allowed us to heavily optimize - # this, so that, for example, hook collection objects are only instantiated when - # a hook is added. This allows us to avoid many object allocations for the common - # case of a group having no hooks. - # - # This is only possible because this interface provides a "tell, don't ask"-style - # API, so that callers _tell_ this class what to do with the hooks, rather than - # asking this class for a list of hooks, and then doing something with them. - class HookCollections - def initialize(owner, filterable_item_repo_class) - @owner = owner - @filterable_item_repo_class = filterable_item_repo_class - @before_example_hooks = nil - @after_example_hooks = nil - @before_context_hooks = nil - @after_context_hooks = nil - @around_example_hooks = nil - end - - def register_globals(host, globals) - parent_groups = host.parent_groups - - process(host, parent_groups, globals, :before, :example, &:options) - process(host, parent_groups, globals, :after, :example, &:options) - process(host, parent_groups, globals, :around, :example, &:options) - - process(host, parent_groups, globals, :before, :context, &:options) - process(host, parent_groups, globals, :after, :context, &:options) - end - - def register_global_singleton_context_hooks(example, globals) - parent_groups = example.example_group.parent_groups - - process(example, parent_groups, globals, :before, :context) { {} } - process(example, parent_groups, globals, :after, :context) { {} } - end - - def register(prepend_or_append, position, *args, &block) - scope, options = scope_and_options_from(*args) - - if scope == :suite - # TODO: consider making this an error in RSpec 4. For SemVer reasons, - # we are only warning in RSpec 3. - RSpec.warn_with "WARNING: `#{position}(:suite)` hooks are only supported on " \ - "the RSpec configuration object. This " \ - "`#{position}(:suite)` hook, registered on an example " \ - "group, will be ignored." - return - elsif scope == :context && position == :around - # TODO: consider making this an error in RSpec 4. For SemVer reasons, - # we are only warning in RSpec 3. - RSpec.warn_with "WARNING: `around(:context)` hooks are not supported and " \ - "behave like `around(:example)`." - end - - hook = HOOK_TYPES[position][scope].new(block, options) - ensure_hooks_initialized_for(position, scope).__send__(prepend_or_append, hook, options) - end - - # @private - # - # Runs all of the blocks stored with the hook in the context of the - # example. If no example is provided, just calls the hook directly. - def run(position, scope, example_or_group) - return if RSpec.configuration.dry_run? - - if scope == :context - unless example_or_group.class.metadata[:skip] - run_owned_hooks_for(position, :context, example_or_group) - end - else - case position - when :before then run_example_hooks_for(example_or_group, :before, :reverse_each) - when :after then run_example_hooks_for(example_or_group, :after, :each) - when :around then run_around_example_hooks_for(example_or_group) { yield } - end - end - end - - SCOPES = [:example, :context] - - SCOPE_ALIASES = { :each => :example, :all => :context } - - HOOK_TYPES = { - :before => Hash.new { BeforeHook }, - :after => Hash.new { AfterHook }, - :around => Hash.new { AroundHook } - } - - HOOK_TYPES[:after][:context] = AfterContextHook - - protected - - EMPTY_HOOK_ARRAY = [].freeze - - def matching_hooks_for(position, scope, example_or_group) - repository = hooks_for(position, scope) { return EMPTY_HOOK_ARRAY } - - # It would be nice to not have to switch on type here, but - # we don't want to define `ExampleGroup#metadata` because then - # `metadata` from within an individual example would return the - # group's metadata but the user would probably expect it to be - # the example's metadata. - metadata = case example_or_group - when ExampleGroup then example_or_group.class.metadata - else example_or_group.metadata - end - - repository.items_for(metadata) - end - - def all_hooks_for(position, scope) - hooks_for(position, scope) { return EMPTY_HOOK_ARRAY }.items_and_filters.map(&:first) - end - - def run_owned_hooks_for(position, scope, example_or_group) - matching_hooks_for(position, scope, example_or_group).each do |hook| - hook.run(example_or_group) - end - end - - def processable_hooks_for(position, scope, host) - if scope == :example - all_hooks_for(position, scope) - else - matching_hooks_for(position, scope, host) - end - end - - private - - def hooks_for(position, scope) - if position == :before - scope == :example ? @before_example_hooks : @before_context_hooks - elsif position == :after - scope == :example ? @after_example_hooks : @after_context_hooks - else # around - @around_example_hooks - end || yield - end - - def ensure_hooks_initialized_for(position, scope) - if position == :before - if scope == :example - @before_example_hooks ||= @filterable_item_repo_class.new(:all?) - else - @before_context_hooks ||= @filterable_item_repo_class.new(:all?) - end - elsif position == :after - if scope == :example - @after_example_hooks ||= @filterable_item_repo_class.new(:all?) - else - @after_context_hooks ||= @filterable_item_repo_class.new(:all?) - end - else # around - @around_example_hooks ||= @filterable_item_repo_class.new(:all?) - end - end - - def process(host, parent_groups, globals, position, scope) - hooks_to_process = globals.processable_hooks_for(position, scope, host) - return if hooks_to_process.empty? - - hooks_to_process -= FlatMap.flat_map(parent_groups) do |group| - group.hooks.all_hooks_for(position, scope) - end - return if hooks_to_process.empty? - - repository = ensure_hooks_initialized_for(position, scope) - hooks_to_process.each { |hook| repository.append hook, (yield hook) } - end - - def scope_and_options_from(*args) - return :suite if args.first == :suite - scope = extract_scope_from(args) - meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering) - return scope, meta - end - - def extract_scope_from(args) - if known_scope?(args.first) - normalized_scope_for(args.shift) - elsif args.any? { |a| a.is_a?(Symbol) } - error_message = "You must explicitly give a scope " \ - "(#{SCOPES.join(", ")}) or scope alias " \ - "(#{SCOPE_ALIASES.keys.join(", ")}) when using symbols as " \ - "metadata for a hook." - raise ArgumentError.new error_message - else - :example - end - end - - def known_scope?(scope) - SCOPES.include?(scope) || SCOPE_ALIASES.keys.include?(scope) - end - - def normalized_scope_for(scope) - SCOPE_ALIASES[scope] || scope - end - - def run_example_hooks_for(example, position, each_method) - owner_parent_groups.__send__(each_method) do |group| - group.hooks.run_owned_hooks_for(position, :example, example) - end - end - - def run_around_example_hooks_for(example) - hooks = FlatMap.flat_map(owner_parent_groups) do |group| - group.hooks.matching_hooks_for(:around, :example, example) - end - - return yield if hooks.empty? # exit early to avoid the extra allocation cost of `Example::Procsy` - - initial_procsy = Example::Procsy.new(example) { yield } - hooks.inject(initial_procsy) do |procsy, around_hook| - procsy.wrap { around_hook.execute_with(example, procsy) } - end.call - end - - if respond_to?(:singleton_class) && singleton_class.ancestors.include?(singleton_class) - def owner_parent_groups - @owner.parent_groups - end - else # Ruby < 2.1 (see https://bugs.ruby-lang.org/issues/8035) - # :nocov: - def owner_parent_groups - @owner_parent_groups ||= [@owner] + @owner.parent_groups - end - # :nocov: - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb deleted file mode 100644 index 4719085..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/invocations.rb +++ /dev/null @@ -1,87 +0,0 @@ -module RSpec - module Core - # @private - module Invocations - # @private - class InitializeProject - def call(*_args) - RSpec::Support.require_rspec_core "project_initializer" - ProjectInitializer.new.run - 0 - end - end - - # @private - class DRbWithFallback - def call(options, err, out) - require 'rspec/core/drb' - begin - return DRbRunner.new(options).run(err, out) - rescue DRb::DRbConnError - err.puts "No DRb server is running. Running in local process instead ..." - end - RSpec::Core::Runner.new(options).run(err, out) - end - end - - # @private - class Bisect - def call(options, err, out) - RSpec::Support.require_rspec_core "bisect/coordinator" - runner = Runner.new(options).tap { |r| r.configure(err, out) } - formatter = bisect_formatter_klass_for(options.options[:bisect]).new( - out, runner.configuration.bisect_runner - ) - - success = RSpec::Core::Bisect::Coordinator.bisect_with( - runner, options.args, formatter - ) - - runner.exit_code(success) - end - - private - - def bisect_formatter_klass_for(argument) - return Formatters::BisectDebugFormatter if argument == "verbose" - Formatters::BisectProgressFormatter - end - end - - # @private - class PrintVersion - def call(_options, _err, out) - overall_version = RSpec::Core::Version::STRING - unless overall_version =~ /[a-zA-Z]+/ - overall_version = overall_version.split('.').first(2).join('.') - end - - out.puts "RSpec #{overall_version}" - - [:Core, :Expectations, :Mocks, :Rails, :Support].each do |const_name| - lib_name = const_name.to_s.downcase - begin - require "rspec/#{lib_name}/version" - rescue LoadError - # Not worth mentioning libs that are not installed - nil - else - out.puts " - rspec-#{lib_name} #{RSpec.const_get(const_name)::Version::STRING}" - end - end - - 0 - end - end - - # @private - PrintHelp = Struct.new(:parser, :hidden_options) do - def call(_options, _err, out) - # Removing the hidden options from the output. - out.puts parser.to_s.gsub(/^\s+(#{hidden_options.join('|')})\b.*$\n/, '') - 0 - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb deleted file mode 100644 index adcfce7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/memoized_helpers.rb +++ /dev/null @@ -1,580 +0,0 @@ -RSpec::Support.require_rspec_support 'reentrant_mutex' - -module RSpec - module Core - # This module is included in {ExampleGroup}, making the methods - # available to be called from within example blocks. - # - # @see ClassMethods - module MemoizedHelpers - # @note `subject` was contributed by Joe Ferris to support the one-liner - # syntax embraced by shoulda matchers: - # - # RSpec.describe Widget do - # it { is_expected.to validate_presence_of(:name) } - # # or - # it { should validate_presence_of(:name) } - # end - # - # While the examples below demonstrate how to use `subject` - # explicitly in examples, we recommend that you define a method with - # an intention revealing name instead. - # - # @example - # - # # Explicit declaration of subject. - # RSpec.describe Person do - # subject { Person.new(:birthdate => 19.years.ago) } - # it "should be eligible to vote" do - # subject.should be_eligible_to_vote - # # ^ ^ explicit reference to subject not recommended - # end - # end - # - # # Implicit subject => { Person.new }. - # RSpec.describe Person do - # it "should be eligible to vote" do - # subject.should be_eligible_to_vote - # # ^ ^ explicit reference to subject not recommended - # end - # end - # - # # One-liner syntax - expectation is set on the subject. - # RSpec.describe Person do - # it { is_expected.to be_eligible_to_vote } - # # or - # it { should be_eligible_to_vote } - # end - # - # @note Because `subject` is designed to create state that is reset - # between each example, and `before(:context)` is designed to setup - # state that is shared across _all_ examples in an example group, - # `subject` is _not_ intended to be used in a `before(:context)` hook. - # - # @see #should - # @see #should_not - # @see #is_expected - def subject - __memoized.fetch_or_store(:subject) do - described = described_class || self.class.metadata.fetch(:description_args).first - Class === described ? described.new : described - end - end - - # When `should` is called with no explicit receiver, the call is - # delegated to the object returned by `subject`. Combined with an - # implicit subject this supports very concise expressions. - # - # @example - # - # RSpec.describe Person do - # it { should be_eligible_to_vote } - # end - # - # @see #subject - # @see #is_expected - # - # @note This only works if you are using rspec-expectations. - # @note If you are using RSpec's newer expect-based syntax you may - # want to use `is_expected.to` instead of `should`. - def should(matcher=nil, message=nil) - enforce_value_expectation(matcher, 'should') - RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message) - end - - # Just like `should`, `should_not` delegates to the subject (implicit or - # explicit) of the example group. - # - # @example - # - # RSpec.describe Person do - # it { should_not be_eligible_to_vote } - # end - # - # @see #subject - # @see #is_expected - # - # @note This only works if you are using rspec-expectations. - # @note If you are using RSpec's newer expect-based syntax you may - # want to use `is_expected.to_not` instead of `should_not`. - def should_not(matcher=nil, message=nil) - enforce_value_expectation(matcher, 'should_not') - RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message) - end - - # Wraps the `subject` in `expect` to make it the target of an expectation. - # Designed to read nicely for one-liners. - # - # @example - # - # describe [1, 2, 3] do - # it { is_expected.to be_an Array } - # it { is_expected.not_to include 4 } - # end - # - # @see #subject - # @see #should - # @see #should_not - # - # @note This only works if you are using rspec-expectations. - def is_expected - expect(subject) - end - - # @private - # should just be placed in private section, - # but Ruby issues warnings on private attributes. - # and expanding it to the equivalent method upsets Rubocop, - # b/c it should obviously be a reader - attr_reader :__memoized - private :__memoized - - private - - # @private - def initialize(*) - __init_memoized - super - end - - # @private - def __init_memoized - @__memoized = if RSpec.configuration.threadsafe? - ThreadsafeMemoized.new - else - NonThreadSafeMemoized.new - end - end - - # @private - def enforce_value_expectation(matcher, method_name) - return if matcher_supports_value_expectations?(matcher) - - RSpec.deprecate( - "#{method_name} #{RSpec::Support::ObjectFormatter.format(matcher)}", - :message => - "The implicit block expectation syntax is deprecated, you should pass " \ - "a block to `expect` to use the provided block expectation matcher " \ - "(#{RSpec::Support::ObjectFormatter.format(matcher)}), " \ - "or the matcher must implement `supports_value_expectations?`." - ) - end - - def matcher_supports_value_expectations?(matcher) - matcher.supports_value_expectations? - rescue - true - end - - # @private - class ThreadsafeMemoized - def initialize - @memoized = {} - @mutex = Support::ReentrantMutex.new - end - - def fetch_or_store(key) - @memoized.fetch(key) do # only first access pays for synchronization - @mutex.synchronize do - @memoized.fetch(key) { @memoized[key] = yield } - end - end - end - end - - # @private - class NonThreadSafeMemoized - def initialize - @memoized = {} - end - - def fetch_or_store(key) - @memoized.fetch(key) { @memoized[key] = yield } - end - end - - # Used internally to customize the behavior of the - # memoized hash when used in a `before(:context)` hook. - # - # @private - class ContextHookMemoized - def self.isolate_for_context_hook(example_group_instance) - exploding_memoized = self - - example_group_instance.instance_exec do - @__memoized = exploding_memoized - - begin - yield - ensure - # This is doing a reset instead of just isolating for context hook. - # Really, this should set the old @__memoized back into place. - # - # Caller is the before and after context hooks - # which are both called from self.run - # I didn't look at why it made tests fail, maybe an object was getting reused in RSpec tests, - # if so, then that probably already works, and its the tests that are wrong. - __init_memoized - end - end - end - - def self.fetch_or_store(key, &_block) - description = if key == :subject - "subject" - else - "let declaration `#{key}`" - end - - raise <<-EOS -#{description} accessed in #{article} #{hook_expression} hook at: - #{CallerFilter.first_non_rspec_line} - -`let` and `subject` declarations are not intended to be called -in #{article} #{hook_expression} hook, as they exist to define state that -is reset between each example, while #{hook_expression} exists to -#{hook_intention}. -EOS - end - - # @private - class Before < self - def self.hook_expression - "`before(:context)`" - end - - def self.article - "a" - end - - def self.hook_intention - "define state that is shared across examples in an example group" - end - end - - # @private - class After < self - def self.hook_expression - "`after(:context)`" - end - - def self.article - "an" - end - - def self.hook_intention - "cleanup state that is shared across examples in an example group" - end - end - end - - # This module is extended onto {ExampleGroup}, making the methods - # available to be called from within example group blocks. - # You can think of them as being analagous to class macros. - module ClassMethods - # Generates a method whose return value is memoized after the first - # call. Useful for reducing duplication between examples that assign - # values to the same local variable. - # - # @note `let` _can_ enhance readability when used sparingly (1,2, or - # maybe 3 declarations) in any given example group, but that can - # quickly degrade with overuse. YMMV. - # - # @note `let` can be configured to be threadsafe or not. - # If it is threadsafe, it will take longer to access the value. - # If it is not threadsafe, it may behave in surprising ways in examples - # that spawn separate threads. Specify this on `RSpec.configure` - # - # @note Because `let` is designed to create state that is reset between - # each example, and `before(:context)` is designed to setup state that - # is shared across _all_ examples in an example group, `let` is _not_ - # intended to be used in a `before(:context)` hook. - # - # @example - # - # RSpec.describe Thing do - # let(:thing) { Thing.new } - # - # it "does something" do - # # First invocation, executes block, memoizes and returns result. - # thing.do_something - # - # # Second invocation, returns the memoized value. - # thing.should be_something - # end - # end - def let(name, &block) - # We have to pass the block directly to `define_method` to - # allow it to use method constructs like `super` and `return`. - raise "#let or #subject called without a block" if block.nil? - - # A list of reserved words that can't be used as a name for a memoized helper - # Matches for both symbols and passed strings - if [:initialize, :to_s].include?(name.to_sym) - raise ArgumentError, "#let or #subject called with reserved name `#{name}`" - end - - our_module = MemoizedHelpers.module_for(self) - - # If we have a module clash in our helper module - # then we need to remove it to prevent a warning. - # - # Note we do not check ancestor modules (see: `instance_methods(false)`) - # as we can override them. - if our_module.instance_methods(false).include?(name) - our_module.__send__(:remove_method, name) - end - our_module.__send__(:define_method, name, &block) - - # If we have a module clash in the example module - # then we need to remove it to prevent a warning. - # - # Note we do not check ancestor modules (see: `instance_methods(false)`) - # as we can override them. - if instance_methods(false).include?(name) - remove_method(name) - end - - # Apply the memoization. The method has been defined in an ancestor - # module so we can use `super` here to get the value. - if block.arity == 1 - define_method(name) { __memoized.fetch_or_store(name) { super(RSpec.current_example, &nil) } } - else - define_method(name) { __memoized.fetch_or_store(name) { super(&nil) } } - end - end - - # Just like `let`, except the block is invoked by an implicit `before` - # hook. This serves a dual purpose of setting up state and providing a - # memoized reference to that state. - # - # @example - # - # class Thing - # def self.count - # @count ||= 0 - # end - # - # def self.count=(val) - # @count += val - # end - # - # def self.reset_count - # @count = 0 - # end - # - # def initialize - # self.class.count += 1 - # end - # end - # - # RSpec.describe Thing do - # after(:example) { Thing.reset_count } - # - # context "using let" do - # let(:thing) { Thing.new } - # - # it "is not invoked implicitly" do - # Thing.count.should eq(0) - # end - # - # it "can be invoked explicitly" do - # thing - # Thing.count.should eq(1) - # end - # end - # - # context "using let!" do - # let!(:thing) { Thing.new } - # - # it "is invoked implicitly" do - # Thing.count.should eq(1) - # end - # - # it "returns memoized version on first invocation" do - # thing - # Thing.count.should eq(1) - # end - # end - # end - def let!(name, &block) - let(name, &block) - before { __send__(name) } - end - - # Declares a `subject` for an example group which can then be wrapped - # with `expect` using `is_expected` to make it the target of an - # expectation in a concise, one-line example. - # - # Given a `name`, defines a method with that name which returns the - # `subject`. This lets you declare the subject once and access it - # implicitly in one-liners and explicitly using an intention revealing - # name. - # - # When given a `name`, calling `super` in the block is not supported. - # - # @note `subject` can be configured to be threadsafe or not. - # If it is threadsafe, it will take longer to access the value. - # If it is not threadsafe, it may behave in surprising ways in examples - # that spawn separate threads. Specify this on `RSpec.configure` - # - # @param name [String,Symbol] used to define an accessor with an - # intention revealing name - # @param block defines the value to be returned by `subject` in examples - # - # @example - # - # RSpec.describe CheckingAccount, "with $50" do - # subject { CheckingAccount.new(Money.new(50, :USD)) } - # it { is_expected.to have_a_balance_of(Money.new(50, :USD)) } - # it { is_expected.not_to be_overdrawn } - # end - # - # RSpec.describe CheckingAccount, "with a non-zero starting balance" do - # subject(:account) { CheckingAccount.new(Money.new(50, :USD)) } - # it { is_expected.not_to be_overdrawn } - # it "has a balance equal to the starting balance" do - # account.balance.should eq(Money.new(50, :USD)) - # end - # end - # - # @see MemoizedHelpers#should - # @see MemoizedHelpers#should_not - # @see MemoizedHelpers#is_expected - def subject(name=nil, &block) - if name - let(name, &block) - alias_method :subject, name - - self::NamedSubjectPreventSuper.__send__(:define_method, name) do - raise NotImplementedError, "`super` in named subjects is not supported" - end - else - let(:subject, &block) - end - end - - # Just like `subject`, except the block is invoked by an implicit - # `before` hook. This serves a dual purpose of setting up state and - # providing a memoized reference to that state. - # - # @example - # - # class Thing - # def self.count - # @count ||= 0 - # end - # - # def self.count=(val) - # @count += val - # end - # - # def self.reset_count - # @count = 0 - # end - # - # def initialize - # self.class.count += 1 - # end - # end - # - # RSpec.describe Thing do - # after(:example) { Thing.reset_count } - # - # context "using subject" do - # subject { Thing.new } - # - # it "is not invoked implicitly" do - # Thing.count.should eq(0) - # end - # - # it "can be invoked explicitly" do - # subject - # Thing.count.should eq(1) - # end - # end - # - # context "using subject!" do - # subject!(:thing) { Thing.new } - # - # it "is invoked implicitly" do - # Thing.count.should eq(1) - # end - # - # it "returns memoized version on first invocation" do - # subject - # Thing.count.should eq(1) - # end - # end - # end - def subject!(name=nil, &block) - subject(name, &block) - before { subject } - end - end - - # @private - # - # Gets the LetDefinitions module. The module is mixed into - # the example group and is used to hold all let definitions. - # This is done so that the block passed to `let` can be - # forwarded directly on to `define_method`, so that all method - # constructs (including `super` and `return`) can be used in - # a `let` block. - # - # The memoization is provided by a method definition on the - # example group that supers to the LetDefinitions definition - # in order to get the value to memoize. - def self.module_for(example_group) - get_constant_or_yield(example_group, :LetDefinitions) do - mod = Module.new do - include(Module.new { - example_group.const_set(:NamedSubjectPreventSuper, self) - }) - end - - example_group.const_set(:LetDefinitions, mod) - mod - end - end - - # @private - def self.define_helpers_on(example_group) - example_group.__send__(:include, module_for(example_group)) - end - - if Module.method(:const_defined?).arity == 1 # for 1.8 - # @private - # - # Gets the named constant or yields. - # On 1.8, const_defined? / const_get do not take into - # account the inheritance hierarchy. - # :nocov: - def self.get_constant_or_yield(example_group, name) - if example_group.const_defined?(name) - example_group.const_get(name) - else - yield - end - end - # :nocov: - else - # @private - # - # Gets the named constant or yields. - # On 1.9, const_defined? / const_get take into account the - # the inheritance by default, and accept an argument to - # disable this behavior. It's important that we don't - # consider inheritance here; each example group level that - # uses a `let` should get its own `LetDefinitions` module. - def self.get_constant_or_yield(example_group, name) - if example_group.const_defined?(name, (check_ancestors = false)) - example_group.const_get(name, check_ancestors) - else - yield - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb deleted file mode 100644 index 9034214..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata.rb +++ /dev/null @@ -1,498 +0,0 @@ -module RSpec - module Core - # Each ExampleGroup class and Example instance owns an instance of - # Metadata, which is Hash extended to support lazy evaluation of values - # associated with keys that may or may not be used by any example or group. - # - # In addition to metadata that is used internally, this also stores - # user-supplied metadata, e.g. - # - # RSpec.describe Something, :type => :ui do - # it "does something", :slow => true do - # # ... - # end - # end - # - # `:type => :ui` is stored in the Metadata owned by the example group, and - # `:slow => true` is stored in the Metadata owned by the example. These can - # then be used to select which examples are run using the `--tag` option on - # the command line, or several methods on `Configuration` used to filter a - # run (e.g. `filter_run_including`, `filter_run_excluding`, etc). - # - # @see Example#metadata - # @see ExampleGroup.metadata - # @see FilterManager - # @see Configuration#filter_run_including - # @see Configuration#filter_run_excluding - module Metadata - # Matches strings either at the beginning of the input or prefixed with a - # whitespace, containing the current path, either postfixed with the - # separator, or at the end of the string. Match groups are the character - # before and the character after the string if any. - # - # http://rubular.com/r/fT0gmX6VJX - # http://rubular.com/r/duOrD4i3wb - # http://rubular.com/r/sbAMHFrOx1 - def self.relative_path_regex - @relative_path_regex ||= /(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/ - end - - # @api private - # - # @param line [String] current code line - # @return [String] relative path to line - def self.relative_path(line) - line = line.sub(relative_path_regex, "\\1.\\2".freeze) - line = line.sub(/\A([^:]+:\d+)$/, '\\1'.freeze) - return nil if line == '-e:1'.freeze - line - rescue SecurityError - # :nocov: - SecurityError is no longer produced starting in ruby 2.7 - nil - # :nocov: - end - - # @private - # Iteratively walks up from the given metadata through all - # example group ancestors, yielding each metadata hash along the way. - def self.ascending(metadata) - yield metadata - return unless (group_metadata = metadata.fetch(:example_group) { metadata[:parent_example_group] }) - - loop do - yield group_metadata - break unless (group_metadata = group_metadata[:parent_example_group]) - end - end - - # @private - # Returns an enumerator that iteratively walks up the given metadata through all - # example group ancestors, yielding each metadata hash along the way. - def self.ascend(metadata) - enum_for(:ascending, metadata) - end - - # @private - # Used internally to build a hash from an args array. - # Symbols are converted into hash keys with a value of `true`. - # This is done to support simple tagging using a symbol, rather - # than needing to do `:symbol => true`. - def self.build_hash_from(args, warn_about_example_group_filtering=false) - hash = args.last.is_a?(Hash) ? args.pop : {} - - hash[args.pop] = true while args.last.is_a?(Symbol) - - if warn_about_example_group_filtering && hash.key?(:example_group) - RSpec.deprecate("Filtering by an `:example_group` subhash", - :replacement => "the subhash to filter directly") - end - - hash - end - - # @private - def self.deep_hash_dup(object) - return object.dup if Array === object - return object unless Hash === object - - object.inject(object.dup) do |duplicate, (key, value)| - duplicate[key] = deep_hash_dup(value) - duplicate - end - end - - # @private - def self.id_from(metadata) - "#{metadata[:rerun_file_path]}[#{metadata[:scoped_id]}]" - end - - # @private - def self.location_tuple_from(metadata) - [metadata[:absolute_file_path], metadata[:line_number]] - end - - # @private - # Used internally to populate metadata hashes with computed keys - # managed by RSpec. - class HashPopulator - attr_reader :metadata, :user_metadata, :description_args, :block - - def initialize(metadata, user_metadata, index_provider, description_args, block) - @metadata = metadata - @user_metadata = user_metadata - @index_provider = index_provider - @description_args = description_args - @block = block - end - - def populate - ensure_valid_user_keys - - metadata[:block] = block - metadata[:description_args] = description_args - metadata[:description] = build_description_from(*metadata[:description_args]) - metadata[:full_description] = full_description - metadata[:described_class] = described_class - - populate_location_attributes - metadata.update(user_metadata) - end - - private - - def populate_location_attributes - backtrace = user_metadata.delete(:caller) - - file_path, line_number = if backtrace - file_path_and_line_number_from(backtrace) - elsif block.respond_to?(:source_location) - block.source_location - else - file_path_and_line_number_from(caller) - end - - relative_file_path = Metadata.relative_path(file_path) - absolute_file_path = File.expand_path(relative_file_path) - metadata[:file_path] = relative_file_path - metadata[:line_number] = line_number.to_i - metadata[:location] = "#{relative_file_path}:#{line_number}" - metadata[:absolute_file_path] = absolute_file_path - metadata[:rerun_file_path] ||= relative_file_path - metadata[:scoped_id] = build_scoped_id_for(absolute_file_path) - end - - def file_path_and_line_number_from(backtrace) - first_caller_from_outside_rspec = backtrace.find { |l| l !~ CallerFilter::LIB_REGEX } - first_caller_from_outside_rspec ||= backtrace.first - /(.+?):(\d+)(?:|:\d+)/.match(first_caller_from_outside_rspec).captures - end - - def description_separator(parent_part, child_part) - if parent_part.is_a?(Module) && /^(?:#|::|\.)/.match(child_part.to_s) - ''.freeze - else - ' '.freeze - end - end - - def build_description_from(parent_description=nil, my_description=nil) - return parent_description.to_s unless my_description - return my_description.to_s if parent_description.to_s == '' - separator = description_separator(parent_description, my_description) - (parent_description.to_s + separator) << my_description.to_s - end - - def build_scoped_id_for(file_path) - index = @index_provider.call(file_path).to_s - parent_scoped_id = metadata.fetch(:scoped_id) { return index } - "#{parent_scoped_id}:#{index}" - end - - def ensure_valid_user_keys - RESERVED_KEYS.each do |key| - next unless user_metadata.key?(key) - raise <<-EOM.gsub(/^\s+\|/, '') - |#{"*" * 50} - |:#{key} is not allowed - | - |RSpec reserves some hash keys for its own internal use, - |including :#{key}, which is used on: - | - | #{CallerFilter.first_non_rspec_line}. - | - |Here are all of RSpec's reserved hash keys: - | - | #{RESERVED_KEYS.join("\n ")} - |#{"*" * 50} - EOM - end - end - end - - # @private - class ExampleHash < HashPopulator - def self.create(group_metadata, user_metadata, index_provider, description, block) - example_metadata = group_metadata.dup - group_metadata = Hash.new(&ExampleGroupHash.backwards_compatibility_default_proc do |hash| - hash[:parent_example_group] - end) - group_metadata.update(example_metadata) - - example_metadata[:execution_result] = Example::ExecutionResult.new - example_metadata[:example_group] = group_metadata - example_metadata[:shared_group_inclusion_backtrace] = SharedExampleGroupInclusionStackFrame.current_backtrace - example_metadata.delete(:parent_example_group) - - description_args = description.nil? ? [] : [description] - hash = new(example_metadata, user_metadata, index_provider, description_args, block) - hash.populate - hash.metadata - end - - private - - def described_class - metadata[:example_group][:described_class] - end - - def full_description - build_description_from( - metadata[:example_group][:full_description], - metadata[:description] - ) - end - end - - # @private - class ExampleGroupHash < HashPopulator - def self.create(parent_group_metadata, user_metadata, example_group_index, *args, &block) - group_metadata = hash_with_backwards_compatibility_default_proc - - if parent_group_metadata - group_metadata.update(parent_group_metadata) - group_metadata[:parent_example_group] = parent_group_metadata - end - - hash = new(group_metadata, user_metadata, example_group_index, args, block) - hash.populate - hash.metadata - end - - def self.hash_with_backwards_compatibility_default_proc - Hash.new(&backwards_compatibility_default_proc { |hash| hash }) - end - - def self.backwards_compatibility_default_proc(&example_group_selector) - Proc.new do |hash, key| - case key - when :example_group - # We commonly get here when rspec-core is applying a previously - # configured filter rule, such as when a gem configures: - # - # RSpec.configure do |c| - # c.include MyGemHelpers, :example_group => { :file_path => /spec\/my_gem_specs/ } - # end - # - # It's confusing for a user to get a deprecation at this point in - # the code, so instead we issue a deprecation from the config APIs - # that take a metadata hash, and MetadataFilter sets this thread - # local to silence the warning here since it would be so - # confusing. - unless RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] - RSpec.deprecate("The `:example_group` key in an example group's metadata hash", - :replacement => "the example group's hash directly for the " \ - "computed keys and `:parent_example_group` to access the parent " \ - "example group metadata") - end - - group_hash = example_group_selector.call(hash) - LegacyExampleGroupHash.new(group_hash) if group_hash - when :example_group_block - RSpec.deprecate("`metadata[:example_group_block]`", - :replacement => "`metadata[:block]`") - hash[:block] - when :describes - RSpec.deprecate("`metadata[:describes]`", - :replacement => "`metadata[:described_class]`") - hash[:described_class] - end - end - end - - private - - def described_class - candidate = metadata[:description_args].first - return candidate unless NilClass === candidate || String === candidate - parent_group = metadata[:parent_example_group] - parent_group && parent_group[:described_class] - end - - def full_description - description = metadata[:description] - parent_example_group = metadata[:parent_example_group] - return description unless parent_example_group - - parent_description = parent_example_group[:full_description] - separator = description_separator(parent_example_group[:description_args].last, - metadata[:description_args].first) - - parent_description + separator + description - end - end - - # @private - RESERVED_KEYS = [ - :description, - :description_args, - :described_class, - :example_group, - :parent_example_group, - :execution_result, - :last_run_status, - :file_path, - :absolute_file_path, - :rerun_file_path, - :full_description, - :line_number, - :location, - :scoped_id, - :block, - :shared_group_inclusion_backtrace - ] - end - - # Mixin that makes the including class imitate a hash for backwards - # compatibility. The including class should use `attr_accessor` to - # declare attributes. - # @private - module HashImitatable - def self.included(klass) - klass.extend ClassMethods - end - - def to_h - hash = extra_hash_attributes.dup - - self.class.hash_attribute_names.each do |name| - hash[name] = __send__(name) - end - - hash - end - - (Hash.public_instance_methods - Object.public_instance_methods).each do |method_name| - next if [:[], :[]=, :to_h].include?(method_name.to_sym) - - define_method(method_name) do |*args, &block| - issue_deprecation(method_name, *args) - - hash = hash_for_delegation - self.class.hash_attribute_names.each do |name| - hash.delete(name) unless instance_variable_defined?(:"@#{name}") - end - - hash.__send__(method_name, *args, &block).tap do - # apply mutations back to the object - hash.each do |name, value| - if directly_supports_attribute?(name) - set_value(name, value) - else - extra_hash_attributes[name] = value - end - end - end - end - end - - def [](key) - issue_deprecation(:[], key) - - if directly_supports_attribute?(key) - get_value(key) - else - extra_hash_attributes[key] - end - end - - def []=(key, value) - issue_deprecation(:[]=, key, value) - - if directly_supports_attribute?(key) - set_value(key, value) - else - extra_hash_attributes[key] = value - end - end - - private - - def extra_hash_attributes - @extra_hash_attributes ||= {} - end - - def directly_supports_attribute?(name) - self.class.hash_attribute_names.include?(name) - end - - def get_value(name) - __send__(name) - end - - def set_value(name, value) - __send__(:"#{name}=", value) - end - - def hash_for_delegation - to_h - end - - def issue_deprecation(_method_name, *_args) - # no-op by default: subclasses can override - end - - # @private - module ClassMethods - def hash_attribute_names - @hash_attribute_names ||= [] - end - - def attr_accessor(*names) - hash_attribute_names.concat(names) - super - end - end - end - - # @private - # Together with the example group metadata hash default block, - # provides backwards compatibility for the old `:example_group` - # key. In RSpec 2.x, the computed keys of a group's metadata - # were exposed from a nested subhash keyed by `[:example_group]`, and - # then the parent group's metadata was exposed by sub-subhash - # keyed by `[:example_group][:example_group]`. - # - # In RSpec 3, we reorganized this to that the computed keys are - # exposed directly of the group metadata hash (no nesting), and - # `:parent_example_group` returns the parent group's metadata. - # - # Maintaining backwards compatibility was difficult: we wanted - # `:example_group` to return an object that: - # - # * Exposes the top-level metadata keys that used to be nested - # under `:example_group`. - # * Supports mutation (rspec-rails, for example, assigns - # `metadata[:example_group][:described_class]` when you use - # anonymous controller specs) such that changes are written - # back to the top-level metadata hash. - # * Exposes the parent group metadata as - # `[:example_group][:example_group]`. - class LegacyExampleGroupHash - include HashImitatable - - def initialize(metadata) - @metadata = metadata - parent_group_metadata = metadata.fetch(:parent_example_group) { {} }[:example_group] - self[:example_group] = parent_group_metadata if parent_group_metadata - end - - def to_h - super.merge(@metadata) - end - - private - - def directly_supports_attribute?(name) - name != :example_group - end - - def get_value(name) - @metadata[name] - end - - def set_value(name, value) - @metadata[name] = value - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb deleted file mode 100644 index 2e63baf..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/metadata_filter.rb +++ /dev/null @@ -1,255 +0,0 @@ -module RSpec - module Core - # Contains metadata filtering logic. This has been extracted from - # the metadata classes because it operates ON a metadata hash but - # does not manage any of the state in the hash. We're moving towards - # having metadata be a raw hash (not a custom subclass), so externalizing - # this filtering logic helps us move in that direction. - module MetadataFilter - class << self - # @private - def apply?(predicate, filters, metadata) - filters.__send__(predicate) { |k, v| filter_applies?(k, v, metadata) } - end - - # @private - def filter_applies?(key, filter_value, metadata) - silence_metadata_example_group_deprecations do - return location_filter_applies?(filter_value, metadata) if key == :locations - return id_filter_applies?(filter_value, metadata) if key == :ids - return filters_apply?(key, filter_value, metadata) if Hash === filter_value - - meta_value = metadata.fetch(key) { return false } - - return true if TrueClass === filter_value && meta_value - return proc_filter_applies?(key, filter_value, metadata) if Proc === filter_value - return filter_applies_to_any_value?(key, filter_value, metadata) if Array === meta_value - - filter_value === meta_value || filter_value.to_s == meta_value.to_s - end - end - - # @private - def silence_metadata_example_group_deprecations - RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] = true - yield - ensure - RSpec::Support.thread_local_data.delete(:silence_metadata_example_group_deprecations) - end - - private - - def filter_applies_to_any_value?(key, value, metadata) - metadata[key].any? { |v| filter_applies?(key, v, key => value) } - end - - def id_filter_applies?(rerun_paths_to_scoped_ids, metadata) - scoped_ids = rerun_paths_to_scoped_ids.fetch(metadata[:rerun_file_path]) { return false } - - Metadata.ascend(metadata).any? do |meta| - scoped_ids.include?(meta[:scoped_id]) - end - end - - def location_filter_applies?(locations, metadata) - Metadata.ascend(metadata).any? do |meta| - file_path = meta[:absolute_file_path] - line_num = meta[:line_number] - - locations[file_path].any? do |filter_line_num| - line_num == RSpec.world.preceding_declaration_line(file_path, filter_line_num) - end - end - end - - def proc_filter_applies?(key, proc, metadata) - case proc.arity - when 0 then proc.call - when 2 then proc.call(metadata[key], metadata) - else proc.call(metadata[key]) - end - end - - def filters_apply?(key, value, metadata) - subhash = metadata[key] - return false unless Hash === subhash || HashImitatable === subhash - value.all? { |k, v| filter_applies?(k, v, subhash) } - end - end - end - - # Tracks a collection of filterable items (e.g. modules, hooks, etc) - # and provides an optimized API to get the applicable items for the - # metadata of an example or example group. - # - # There are two implementations, optimized for different uses. - # @private - module FilterableItemRepository - # This implementation is simple, and is optimized for frequent - # updates but rare queries. `append` and `prepend` do no extra - # processing, and no internal memoization is done, since this - # is not optimized for queries. - # - # This is ideal for use by a example or example group, which may - # be updated multiple times with globally configured hooks, etc, - # but will not be queried frequently by other examples or example - # groups. - # @private - class UpdateOptimized - attr_reader :items_and_filters - - def initialize(applies_predicate) - @applies_predicate = applies_predicate - @items_and_filters = [] - end - - def append(item, metadata) - @items_and_filters << [item, metadata] - end - - def prepend(item, metadata) - @items_and_filters.unshift [item, metadata] - end - - def delete(item, metadata) - @items_and_filters.delete [item, metadata] - end - - def items_for(request_meta) - @items_and_filters.each_with_object([]) do |(item, item_meta), to_return| - to_return << item if item_meta.empty? || - MetadataFilter.apply?(@applies_predicate, item_meta, request_meta) - end - end - - unless [].respond_to?(:each_with_object) # For 1.8.7 - # :nocov: - undef items_for - def items_for(request_meta) - @items_and_filters.inject([]) do |to_return, (item, item_meta)| - to_return << item if item_meta.empty? || - MetadataFilter.apply?(@applies_predicate, item_meta, request_meta) - to_return - end - end - # :nocov: - end - end - - # This implementation is much more complex, and is optimized for - # rare (or hopefully no) updates once the queries start. Updates - # incur a cost as it has to clear the memoization and keep track - # of applicable keys. Queries will be O(N) the first time an item - # is provided with a given set of applicable metadata; subsequent - # queries with items with the same set of applicable metadata will - # be O(1) due to internal memoization. - # - # This is ideal for use by config, where filterable items (e.g. hooks) - # are typically added at the start of the process (e.g. in `spec_helper`) - # and then repeatedly queried as example groups and examples are defined. - # @private - class QueryOptimized < UpdateOptimized - alias find_items_for items_for - private :find_items_for - - def initialize(applies_predicate) - super - @applicable_keys = Set.new - @proc_keys = Set.new - @memoized_lookups = Hash.new do |hash, applicable_metadata| - hash[applicable_metadata] = find_items_for(applicable_metadata) - end - end - - def append(item, metadata) - super - handle_mutation(metadata) - end - - def prepend(item, metadata) - super - handle_mutation(metadata) - end - - def delete(item, metadata) - super - reconstruct_caches - end - - def items_for(metadata) - # The filtering of `metadata` to `applicable_metadata` is the key thing - # that makes the memoization actually useful in practice, since each - # example and example group have different metadata (e.g. location and - # description). By filtering to the metadata keys our items care about, - # we can ignore extra metadata keys that differ for each example/group. - # For example, given `config.include DBHelpers, :db`, example groups - # can be split into these two sets: those that are tagged with `:db` and those - # that are not. For each set, this method for the first group in the set is - # still an `O(N)` calculation, but all subsequent groups in the set will be - # constant time lookups when they call this method. - applicable_metadata = applicable_metadata_from(metadata) - - if applicable_metadata.any? { |k, _| @proc_keys.include?(k) } - # It's unsafe to memoize lookups involving procs (since they can - # be non-deterministic), so we skip the memoization in this case. - find_items_for(applicable_metadata) - else - @memoized_lookups[applicable_metadata] - end - end - - private - - def reconstruct_caches - @applicable_keys.clear - @proc_keys.clear - @items_and_filters.each do |_item, metadata| - handle_mutation(metadata) - end - end - - def handle_mutation(metadata) - @applicable_keys.merge(metadata.keys) - @proc_keys.merge(proc_keys_from metadata) - @memoized_lookups.clear - end - - def applicable_metadata_from(metadata) - MetadataFilter.silence_metadata_example_group_deprecations do - @applicable_keys.inject({}) do |hash, key| - # :example_group is treated special here because... - # - In RSpec 2, example groups had an `:example_group` key - # - In RSpec 3, that key is deprecated (it was confusing!). - # - The key is not technically present in an example group metadata hash - # (and thus would fail the `metadata.key?(key)` check) but a value - # is provided when accessed via the hash's `default_proc` - # - Thus, for backwards compatibility, we have to explicitly check - # for `:example_group` here if it is one of the keys being used to - # filter. - hash[key] = metadata[key] if metadata.key?(key) || key == :example_group - hash - end - end - end - - def proc_keys_from(metadata) - metadata.each_with_object([]) do |(key, value), to_return| - to_return << key if Proc === value - end - end - - unless [].respond_to?(:each_with_object) # For 1.8.7 - # :nocov: - undef proc_keys_from - def proc_keys_from(metadata) - metadata.inject([]) do |to_return, (key, value)| - to_return << key if Proc === value - to_return - end - end - # :nocov: - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb deleted file mode 100644 index 25db751..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/minitest_assertions_adapter.rb +++ /dev/null @@ -1,31 +0,0 @@ -begin - # Only the minitest 5.x gem includes the minitest.rb and assertions.rb files. - require 'minitest' - require 'minitest/assertions' -rescue LoadError - # We must be using Ruby Core's MiniTest or the Minitest gem 4.x. - require 'minitest/unit' - Minitest = MiniTest -end - -module RSpec - module Core - # @private - module MinitestAssertionsAdapter - include ::Minitest::Assertions - # Need to forcefully include Pending after Minitest::Assertions - # to make sure our own #skip method beats Minitest's. - include ::RSpec::Core::Pending - - # Minitest 5.x requires this accessor to be available. See - # https://github.com/seattlerb/minitest/blob/38f0a5fcbd9c37c3f80a3eaad4ba84d3fc9947a0/lib/minitest/assertions.rb#L8 - # - # It is not required for other extension libraries, and RSpec does not - # report or make this information available to formatters. - attr_writer :assertions - def assertions - @assertions ||= 0 - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb deleted file mode 100644 index 91475ae..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/flexmock.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Created by Jim Weirich on 2007-04-10. -# Copyright (c) 2007. All rights reserved. - -require 'flexmock/rspec' - -module RSpec - module Core - module MockingAdapters - # @private - module Flexmock - include ::FlexMock::MockContainer - - def self.framework_name - :flexmock - end - - def setup_mocks_for_rspec - # No setup required. - end - - def verify_mocks_for_rspec - flexmock_verify - end - - def teardown_mocks_for_rspec - flexmock_close - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb deleted file mode 100644 index 8caf7b6..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/mocha.rb +++ /dev/null @@ -1,57 +0,0 @@ -# In order to support all versions of mocha, we have to jump through some -# hoops here. -# -# mocha >= '0.13.0': -# require 'mocha/api' is required. -# require 'mocha/object' raises a LoadError b/c the file no longer exists. -# mocha < '0.13.0', >= '0.9.7' -# require 'mocha/api' is required. -# require 'mocha/object' is required. -# mocha < '0.9.7': -# require 'mocha/api' raises a LoadError b/c the file does not yet exist. -# require 'mocha/standalone' is required. -# require 'mocha/object' is required. -begin - require 'mocha/api' - - begin - require 'mocha/object' - rescue LoadError - # Mocha >= 0.13.0 no longer contains this file nor needs it to be loaded. - end -rescue LoadError - require 'mocha/standalone' - require 'mocha/object' -end - -module RSpec - module Core - module MockingAdapters - # @private - module Mocha - def self.framework_name - :mocha - end - - # Mocha::Standalone was deprecated as of Mocha 0.9.7. - begin - include ::Mocha::API - rescue NameError - include ::Mocha::Standalone - end - - def setup_mocks_for_rspec - mocha_setup - end - - def verify_mocks_for_rspec - mocha_verify - end - - def teardown_mocks_for_rspec - mocha_teardown - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb deleted file mode 100644 index 442de9a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/null.rb +++ /dev/null @@ -1,14 +0,0 @@ -module RSpec - module Core - module MockingAdapters - # @private - module Null - def setup_mocks_for_rspec; end - - def verify_mocks_for_rspec; end - - def teardown_mocks_for_rspec; end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb deleted file mode 100644 index d72651a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rr.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'rr' - -RSpec.configuration.backtrace_exclusion_patterns.push(RR::Errors::BACKTRACE_IDENTIFIER) - -module RSpec - module Core - # @private - module MockingAdapters - # @private - module RR - def self.framework_name - :rr - end - - include ::RR::Extensions::InstanceMethods - - def setup_mocks_for_rspec - ::RR::Space.instance.reset - end - - def verify_mocks_for_rspec - ::RR::Space.instance.verify_doubles - end - - def teardown_mocks_for_rspec - ::RR::Space.instance.reset - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb deleted file mode 100644 index bb3f0ae..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/mocking_adapters/rspec.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'rspec/mocks' - -module RSpec - module Core - module MockingAdapters - # @private - module RSpec - include ::RSpec::Mocks::ExampleMethods - - def self.framework_name - :rspec - end - - def self.configuration - ::RSpec::Mocks.configuration - end - - def setup_mocks_for_rspec - ::RSpec::Mocks.setup - end - - def verify_mocks_for_rspec - ::RSpec::Mocks.verify - end - - def teardown_mocks_for_rspec - ::RSpec::Mocks.teardown - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb deleted file mode 100644 index 72768ef..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/notifications.rb +++ /dev/null @@ -1,523 +0,0 @@ -RSpec::Support.require_rspec_core "formatters/console_codes" -RSpec::Support.require_rspec_core "formatters/exception_presenter" -RSpec::Support.require_rspec_core "formatters/helpers" -RSpec::Support.require_rspec_core "shell_escape" - -module RSpec::Core - # Notifications are value objects passed to formatters to provide them - # with information about a particular event of interest. - module Notifications - # @private - module NullColorizer - module_function - - def wrap(line, _code_or_symbol) - line - end - end - - # The `StartNotification` represents a notification sent by the reporter - # when the suite is started. It contains the expected amount of examples - # to be executed, and the load time of RSpec. - # - # @attr count [Fixnum] the number counted - # @attr load_time [Float] the number of seconds taken to boot RSpec - # and load the spec files - StartNotification = Struct.new(:count, :load_time) - - # The `ExampleNotification` represents notifications sent by the reporter - # which contain information about the current (or soon to be) example. - # It is used by formatters to access information about that example. - # - # @example - # def example_started(notification) - # puts "Hey I started #{notification.example.description}" - # end - # - # @attr example [RSpec::Core::Example] the current example - ExampleNotification = Struct.new(:example) - class ExampleNotification - # @private - def self.for(example) - execution_result = example.execution_result - - return SkippedExampleNotification.new(example) if execution_result.example_skipped? - return new(example) unless execution_result.status == :pending || execution_result.status == :failed - - klass = if execution_result.pending_fixed? - PendingExampleFixedNotification - elsif execution_result.status == :pending - PendingExampleFailedAsExpectedNotification - else - FailedExampleNotification - end - - klass.new(example) - end - - private_class_method :new - end - - # The `ExamplesNotification` represents notifications sent by the reporter - # which contain information about the suites examples. - # - # @example - # def stop(notification) - # puts "Hey I ran #{notification.examples.size}" - # end - # - class ExamplesNotification - def initialize(reporter) - @reporter = reporter - end - - # @return [Array] list of examples - def examples - @reporter.examples - end - - # @return [Array] list of failed examples - def failed_examples - @reporter.failed_examples - end - - # @return [Array] list of pending examples - def pending_examples - @reporter.pending_examples - end - - # @return [Array] - # returns examples as notifications - def notifications - @notifications ||= format_examples(examples) - end - - # @return [Array] - # returns failed examples as notifications - def failure_notifications - @failed_notifications ||= format_examples(failed_examples) - end - - # @return [Array] - # returns pending examples as notifications - def pending_notifications - @pending_notifications ||= format_examples(pending_examples) - end - - # @return [String] The list of failed examples, fully formatted in the way - # that RSpec's built-in formatters emit. - def fully_formatted_failed_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - formatted = "\nFailures:\n" - - failure_notifications.each_with_index do |failure, index| - formatted += failure.fully_formatted(index.next, colorizer) - end - - formatted - end - - # @return [String] The list of pending examples, fully formatted in the - # way that RSpec's built-in formatters emit. - def fully_formatted_pending_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - return if RSpec.configuration.pending_failure_output == :skip - - formatted = "\nPending: (Failures listed here are expected and do not affect your suite's status)\n".dup - - pending_notifications.each_with_index do |notification, index| - formatted << notification.fully_formatted(index.next, colorizer) - end - - formatted - end - - private - - def format_examples(examples) - examples.map do |example| - ExampleNotification.for(example) - end - end - end - - # The `FailedExampleNotification` extends `ExampleNotification` with - # things useful for examples that have failure info -- typically a - # failed or pending spec. - # - # @example - # def example_failed(notification) - # puts "Hey I failed :(" - # puts "Here's my stack trace" - # puts notification.exception.backtrace.join("\n") - # end - # - # @attr [RSpec::Core::Example] example the current example - # @see ExampleNotification - class FailedExampleNotification < ExampleNotification - public_class_method :new - - # @return [Exception] The example failure - def exception - @exception_presenter.exception - end - - # @return [String] The example description - def description - @exception_presenter.description - end - - # Returns the message generated for this failure line by line. - # - # @return [Array] The example failure message - def message_lines - @exception_presenter.message_lines - end - - # Returns the message generated for this failure colorized line by line. - # - # @param colorizer [#wrap] An object to colorize the message_lines by - # @return [Array] The example failure message colorized - def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - @exception_presenter.colorized_message_lines(colorizer) - end - - # Returns the failures formatted backtrace. - # - # @return [Array] the examples backtrace lines - def formatted_backtrace - @exception_presenter.formatted_backtrace - end - - # Returns the failures colorized formatted backtrace. - # - # @param colorizer [#wrap] An object to colorize the message_lines by - # @return [Array] the examples colorized backtrace lines - def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - @exception_presenter.colorized_formatted_backtrace(colorizer) - end - - # @return [String] The failure information fully formatted in the way that - # RSpec's built-in formatters emit. - def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) - @exception_presenter.fully_formatted(failure_number, colorizer) - end - - # @return [Array] The failure information fully formatted in the way that - # RSpec's built-in formatters emit, split by line. - def fully_formatted_lines(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) - @exception_presenter.fully_formatted_lines(failure_number, colorizer) - end - - private - - def initialize(example, exception_presenter=Formatters::ExceptionPresenter::Factory.new(example).build) - @exception_presenter = exception_presenter - super(example) - end - end - - # @deprecated Use {FailedExampleNotification} instead. - class PendingExampleFixedNotification < FailedExampleNotification; end - - # @deprecated Use {FailedExampleNotification} instead. - class PendingExampleFailedAsExpectedNotification < FailedExampleNotification; end - - # The `SkippedExampleNotification` extends `ExampleNotification` with - # things useful for specs that are skipped. - # - # @attr [RSpec::Core::Example] example the current example - # @see ExampleNotification - class SkippedExampleNotification < ExampleNotification - public_class_method :new - - # @return [String] The pending detail fully formatted in the way that - # RSpec's built-in formatters emit. - def fully_formatted(pending_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) - formatted_caller = RSpec.configuration.backtrace_formatter.backtrace_line(example.location) - - [ - colorizer.wrap("\n #{pending_number}) #{example.full_description}", :pending), - "\n ", - Formatters::ExceptionPresenter::PENDING_DETAIL_FORMATTER.call(example, colorizer), - "\n", - colorizer.wrap(" # #{formatted_caller}\n", :detail) - ].join("") - end - end - - # The `GroupNotification` represents notifications sent by the reporter - # which contain information about the currently running (or soon to be) - # example group. It is used by formatters to access information about that - # group. - # - # @example - # def example_group_started(notification) - # puts "Hey I started #{notification.group.description}" - # end - # @attr group [RSpec::Core::ExampleGroup] the current group - GroupNotification = Struct.new(:group) - - # The `MessageNotification` encapsulates generic messages that the reporter - # sends to formatters. - # - # @attr message [String] the message - MessageNotification = Struct.new(:message) - - # The `SeedNotification` holds the seed used to randomize examples and - # whether that seed has been used or not. - # - # @attr seed [Fixnum] the seed used to randomize ordering - # @attr used [Boolean] whether the seed has been used or not - SeedNotification = Struct.new(:seed, :used) - class SeedNotification - # @api - # @return [Boolean] has the seed been used? - def seed_used? - !!used - end - private :used - - # @return [String] The seed information fully formatted in the way that - # RSpec's built-in formatters emit. - def fully_formatted - "\nRandomized with seed #{seed}\n" - end - end - - # The `SummaryNotification` holds information about the results of running - # a test suite. It is used by formatters to provide information at the end - # of the test run. - # - # @attr duration [Float] the time taken (in seconds) to run the suite - # @attr examples [Array] the examples run - # @attr failed_examples [Array] the failed examples - # @attr pending_examples [Array] the pending examples - # @attr load_time [Float] the number of seconds taken to boot RSpec - # and load the spec files - # @attr errors_outside_of_examples_count [Integer] the number of errors that - # have occurred processing - # the spec suite - SummaryNotification = Struct.new(:duration, :examples, :failed_examples, - :pending_examples, :load_time, - :errors_outside_of_examples_count) - class SummaryNotification - # @api - # @return [Fixnum] the number of examples run - def example_count - @example_count ||= examples.size - end - - # @api - # @return [Fixnum] the number of failed examples - def failure_count - @failure_count ||= failed_examples.size - end - - # @api - # @return [Fixnum] the number of pending examples - def pending_count - @pending_count ||= pending_examples.size - end - - # @api - # @return [String] A line summarising the result totals of the spec run. - def totals_line - summary = Formatters::Helpers.pluralize(example_count, "example") + - ", " + Formatters::Helpers.pluralize(failure_count, "failure") - summary += ", #{pending_count} pending" if pending_count > 0 - if errors_outside_of_examples_count > 0 - summary += ( - ", " + - Formatters::Helpers.pluralize(errors_outside_of_examples_count, "error") + - " occurred outside of examples" - ) - end - summary - end - - # @api public - # - # Wraps the results line with colors based on the configured - # colors for failure, pending, and success. Defaults to red, - # yellow, green accordingly. - # - # @param colorizer [#wrap] An object which supports wrapping text with - # specific colors. - # @return [String] A colorized results line. - def colorized_totals_line(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - if failure_count > 0 || errors_outside_of_examples_count > 0 - colorizer.wrap(totals_line, RSpec.configuration.failure_color) - elsif pending_count > 0 - colorizer.wrap(totals_line, RSpec.configuration.pending_color) - else - colorizer.wrap(totals_line, RSpec.configuration.success_color) - end - end - - # @api public - # - # Formats failures into a rerunable command format. - # - # @param colorizer [#wrap] An object which supports wrapping text with - # specific colors. - # @return [String] A colorized summary line. - def colorized_rerun_commands(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - "\nFailed examples:\n\n" + - failed_examples.map do |example| - colorizer.wrap("rspec #{rerun_argument_for(example)}", RSpec.configuration.failure_color) + " " + - colorizer.wrap("# #{example.full_description}", RSpec.configuration.detail_color) - end.join("\n") - end - - # @return [String] a formatted version of the time it took to run the - # suite - def formatted_duration - Formatters::Helpers.format_duration(duration) - end - - # @return [String] a formatted version of the time it took to boot RSpec - # and load the spec files - def formatted_load_time - Formatters::Helpers.format_duration(load_time) - end - - # @return [String] The summary information fully formatted in the way that - # RSpec's built-in formatters emit. - def fully_formatted(colorizer=::RSpec::Core::Formatters::ConsoleCodes) - formatted = "\nFinished in #{formatted_duration} " \ - "(files took #{formatted_load_time} to load)\n" \ - "#{colorized_totals_line(colorizer)}\n" - - unless failed_examples.empty? - formatted += (colorized_rerun_commands(colorizer) + "\n") - end - - formatted - end - - private - - include RSpec::Core::ShellEscape - - def rerun_argument_for(example) - location = example.location_rerun_argument - return location unless duplicate_rerun_locations.include?(location) - conditionally_quote(example.id) - end - - def duplicate_rerun_locations - @duplicate_rerun_locations ||= begin - locations = RSpec.world.all_examples.map(&:location_rerun_argument) - - Set.new.tap do |s| - locations.group_by { |l| l }.each do |l, ls| - s << l if ls.count > 1 - end - end - end - end - end - - # The `ProfileNotification` holds information about the results of running a - # test suite when profiling is enabled. It is used by formatters to provide - # information at the end of the test run for profiling information. - # - # @attr duration [Float] the time taken (in seconds) to run the suite - # @attr examples [Array] the examples run - # @attr number_of_examples [Fixnum] the number of examples to profile - # @attr example_groups [Array] example groups run - class ProfileNotification - def initialize(duration, examples, number_of_examples, example_groups) - @duration = duration - @examples = examples - @number_of_examples = number_of_examples - @example_groups = example_groups - end - attr_reader :duration, :examples, :number_of_examples - - # @return [Array] the slowest examples - def slowest_examples - @slowest_examples ||= - examples.sort_by do |example| - -example.execution_result.run_time - end.first(number_of_examples) - end - - # @return [Float] the time taken (in seconds) to run the slowest examples - def slow_duration - @slow_duration ||= - slowest_examples.inject(0.0) do |i, e| - i + e.execution_result.run_time - end - end - - # @return [String] the percentage of total time taken - def percentage - @percentage ||= - begin - time_taken = slow_duration / duration - '%.1f' % ((time_taken.nan? ? 0.0 : time_taken) * 100) - end - end - - # @return [Array] the slowest example groups - def slowest_groups - @slowest_groups ||= calculate_slowest_groups - end - - private - - def calculate_slowest_groups - # stop if we've only one example group - return {} if @example_groups.keys.length <= 1 - - @example_groups.each_value do |hash| - hash[:average] = hash[:total_time].to_f / hash[:count] - end - - groups = @example_groups.sort_by { |_, hash| -hash[:average] }.first(number_of_examples) - groups.map { |group, data| [group.location, data] } - end - end - - # The `DeprecationNotification` is issued by the reporter when a deprecated - # part of RSpec is encountered. It represents information about the - # deprecated call site. - # - # @attr message [String] A custom message about the deprecation - # @attr deprecated [String] A custom message about the deprecation (alias of - # message) - # @attr replacement [String] An optional replacement for the deprecation - # @attr call_site [String] An optional call site from which the deprecation - # was issued - DeprecationNotification = Struct.new(:deprecated, :message, :replacement, :call_site) - class DeprecationNotification - private_class_method :new - - # @api - # Convenience way to initialize the notification - def self.from_hash(data) - new data[:deprecated], data[:message], data[:replacement], data[:call_site] - end - end - - # `NullNotification` represents a placeholder value for notifications that - # currently require no information, but we may wish to extend in future. - class NullNotification - end - - # `CustomNotification` is used when sending custom events to formatters / - # other registered listeners, it creates attributes based on supplied hash - # of options. - class CustomNotification < Struct - # @param options [Hash] A hash of method / value pairs to create on this notification - # @return [CustomNotification] - # - # Build a custom notification based on the supplied option key / values. - def self.for(options={}) - return NullNotification if options.keys.empty? - new(*options.keys).new(*options.values) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb deleted file mode 100644 index e239e87..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/option_parser.rb +++ /dev/null @@ -1,325 +0,0 @@ -# http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html -require 'optparse' - -module RSpec::Core - # @private - class Parser - def self.parse(args, source=nil) - new(args).parse(source) - end - - attr_reader :original_args - - def initialize(original_args) - @original_args = original_args - end - - def parse(source=nil) - return { :files_or_directories_to_run => [] } if original_args.empty? - args = original_args.dup - - options = args.delete('--tty') ? { :tty => true } : {} - begin - parser(options).parse!(args) - rescue OptionParser::InvalidOption => e - abort "#{e.message}#{" (defined in #{source})" if source}\n\n" \ - "Please use --help for a listing of valid options" - end - - options[:files_or_directories_to_run] = args - options - end - - private - - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/PerceivedComplexity - def parser(options) - OptionParser.new do |parser| - parser.summary_width = 34 - - parser.banner = "Usage: rspec [options] [files or directories]\n\n" - - parser.on('-I PATH', 'Specify PATH to add to $LOAD_PATH (may be used more than once).') do |dirs| - options[:libs] ||= [] - options[:libs].concat(dirs.split(File::PATH_SEPARATOR)) - end - - parser.on('-r', '--require PATH', 'Require a file.') do |path| - options[:requires] ||= [] - options[:requires] << path - end - - parser.on('-O', '--options PATH', 'Specify the path to a custom options file.') do |path| - options[:custom_options_file] = path - end - - parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.', - ' [defined] examples and groups are run in the order they are defined', - ' [rand] randomize the order of groups and examples', - ' [random] alias for rand', - ' [random:SEED] e.g. --order random:123', - ' [recently-modified] run the most recently modified files first') do |o| - options[:order] = o - end - - parser.on('--seed SEED', Integer, 'Equivalent of --order rand:SEED.') do |seed| - options[:order] = "rand:#{seed}" - end - - parser.on('--bisect[=verbose]', 'Repeatedly runs the suite in order to isolate the failures to the ', - ' smallest reproducible case.') do |argument| - options[:bisect] = argument || true - options[:runner] = RSpec::Core::Invocations::Bisect.new - end - - parser.on('--[no-]fail-fast[=COUNT]', 'Abort the run after a certain number of failures (1 by default).') do |argument| - if argument == true - value = 1 - elsif argument == false || argument == 0 - value = false - else - begin - value = Integer(argument) - rescue ArgumentError - RSpec.warning "Expected an integer value for `--fail-fast`, got: #{argument.inspect}", :call_site => nil - end - end - set_fail_fast(options, value) - end - - parser.on('--failure-exit-code CODE', Integer, - 'Override the exit code used when there are failing specs.') do |code| - options[:failure_exit_code] = code - end - - parser.on('--error-exit-code CODE', Integer, - 'Override the exit code used when there are errors loading or running specs outside of examples.') do |code| - options[:error_exit_code] = code - end - - parser.on('-X', '--[no-]drb', 'Run examples via DRb.') do |use_drb| - options[:drb] = use_drb - options[:runner] = RSpec::Core::Invocations::DRbWithFallback.new if use_drb - end - - parser.on('--drb-port PORT', 'Port to connect to the DRb server.') do |o| - options[:drb_port] = o.to_i - end - - parser.separator("\n **** Output ****\n\n") - - parser.on('-f', '--format FORMATTER', 'Choose a formatter.', - ' [p]rogress (default - dots)', - ' [d]ocumentation (group and example names)', - ' [h]tml', - ' [j]son', - ' [f]ailures ("file:line:reason", suitable for editors integration)', - ' custom formatter class name') do |o| - options[:formatters] ||= [] - options[:formatters] << [o] - end - - parser.on('-o', '--out FILE', - 'Write output to a file instead of $stdout. This option applies', - ' to the previously specified --format, or the default format', - ' if no format is specified.' - ) do |o| - options[:formatters] ||= [['progress']] - options[:formatters].last << o - end - - parser.on('--deprecation-out FILE', 'Write deprecation warnings to a file instead of $stderr.') do |file| - options[:deprecation_stream] = file - end - - parser.on('-b', '--backtrace', 'Enable full backtrace.') do |_o| - options[:full_backtrace] = true - end - - parser.on('-c', '--color', '--colour', '') do |_o| - # flag will be excluded from `--help` output because it is deprecated - options[:color] = true - options[:color_mode] = :automatic - end - - parser.on('--force-color', '--force-colour', 'Force the output to be in color, even if the output is not a TTY') do |_o| - if options[:color_mode] == :off - abort "Please only use one of `--force-color` and `--no-color`" - end - options[:color_mode] = :on - end - - parser.on('--no-color', '--no-colour', 'Force the output to not be in color, even if the output is a TTY') do |_o| - if options[:color_mode] == :on - abort "Please only use one of --force-color and --no-color" - end - options[:color_mode] = :off - end - - parser.on('-p', '--[no-]profile [COUNT]', - 'Enable profiling of examples and list the slowest examples (default: 10).') do |argument| - options[:profile_examples] = if argument.nil? - true - elsif argument == false - false - else - begin - Integer(argument) - rescue ArgumentError - RSpec.warning "Non integer specified as profile count, separate " \ - "your path from options with -- e.g. " \ - "`rspec --profile -- #{argument}`", - :call_site => nil - true - end - end - end - - parser.on('--dry-run', 'Print the formatter output of your suite without', - ' running any examples or hooks') do |_o| - options[:dry_run] = true - end - - parser.on('-w', '--warnings', 'Enable ruby warnings') do - if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=) - # :nocov: on older Ruby without Warning - Warning[:deprecated] = true - # :nocov: - end - $VERBOSE = true - end - - parser.separator <<-FILTERING - - **** Filtering/tags **** - - In addition to the following options for selecting specific files, groups, or - examples, you can select individual examples by appending the line number(s) to - the filename: - - rspec path/to/a_spec.rb:37:87 - - You can also pass example ids enclosed in square brackets: - - rspec path/to/a_spec.rb[1:5,1:6] # run the 5th and 6th examples/groups defined in the 1st group - -FILTERING - - parser.on('--only-failures', "Filter to just the examples that failed the last time they ran.") do - configure_only_failures(options) - end - - parser.on("-n", "--next-failure", "Apply `--only-failures` and abort after one failure.", - " (Equivalent to `--only-failures --fail-fast --order defined`)") do - configure_only_failures(options) - set_fail_fast(options, 1) - options[:order] ||= 'defined' - end - - parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb").') do |o| - if options[:pattern] - options[:pattern] += ',' + o - else - options[:pattern] = o - end - end - - parser.on('--exclude-pattern PATTERN', - 'Load files except those matching pattern. Opposite effect of --pattern.') do |o| - options[:exclude_pattern] = o - end - - parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING (may be", - " used more than once)") do |o| - (options[:full_description] ||= []) << Regexp.compile(Regexp.escape(o)) - end - - parser.on('-E', '--example-matches REGEX', "Run examples whose full nested names match REGEX (may be", - " used more than once)") do |o| - (options[:full_description] ||= []) << Regexp.compile(o) - end - - parser.on('-t', '--tag TAG[:VALUE]', - 'Run examples with the specified tag, or exclude examples', - 'by adding ~ before the tag.', - ' - e.g. ~slow', - ' - TAG is always converted to a symbol') do |tag| - filter_type = tag =~ /^~/ ? :exclusion_filter : :inclusion_filter - - name, value = tag.gsub(/^(~@|~|@)/, '').split(':', 2) - name = name.to_sym - - parsed_value = case value - when nil then true # The default value for tags is true - when 'true' then true - when 'false' then false - when 'nil' then nil - when /^:/ then value[1..-1].to_sym - when /^\d+$/ then Integer(value) - when /^\d+.\d+$/ then Float(value) - else - value - end - - add_tag_filter(options, filter_type, name, parsed_value) - end - - parser.on('--default-path PATH', 'Set the default path where RSpec looks for examples (can', - ' be a path to a file or a directory).') do |path| - options[:default_path] = path - end - - parser.separator("\n **** Utility ****\n\n") - - parser.on('--init', 'Initialize your project with RSpec.') do |_cmd| - options[:runner] = RSpec::Core::Invocations::InitializeProject.new - end - - parser.on('-v', '--version', 'Display the version.') do - options[:runner] = RSpec::Core::Invocations::PrintVersion.new - end - - # These options would otherwise be confusing to users, so we forcibly - # prevent them from executing. - # - # * --I is too similar to -I. - # * -d was a shorthand for --debugger, which is removed, but now would - # trigger --default-path. - invalid_options = %w[-d --I] - - hidden_options = invalid_options + %w[-c] - - parser.on_tail('-h', '--help', "You're looking at it.") do - options[:runner] = RSpec::Core::Invocations::PrintHelp.new(parser, hidden_options) - end - - # This prevents usage of the invalid_options. - invalid_options.each do |option| - parser.on(option) do - raise OptionParser::InvalidOption.new - end - end - end - end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/PerceivedComplexity - - def add_tag_filter(options, filter_type, tag_name, value=true) - (options[filter_type] ||= {})[tag_name] = value - end - - def set_fail_fast(options, value) - options[:fail_fast] = value - end - - def configure_only_failures(options) - options[:only_failures] = true - add_tag_filter(options, :inclusion_filter, :last_run_status, 'failed') - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb deleted file mode 100644 index 6058a2f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ordering.rb +++ /dev/null @@ -1,208 +0,0 @@ -module RSpec - module Core - # @private - module Ordering - # @private - # The default global ordering (defined order). - class Identity - def order(items) - items - end - end - - # @private - # Orders items randomly. - class Random - def initialize(configuration) - @configuration = configuration - @used = false - end - - def used? - @used - end - - def order(items) - @used = true - - seed = @configuration.seed.to_s - items.sort_by { |item| jenkins_hash_digest(seed + item.id) } - end - - private - - # http://en.wikipedia.org/wiki/Jenkins_hash_function - # Jenkins provides a good distribution and is simpler than MD5. - # It's a bit slower than MD5 (primarily because `Digest::MD5` is - # implemented in C) but has the advantage of not requiring us - # to load another part of stdlib, which we try to minimize. - def jenkins_hash_digest(string) - hash = 0 - - string.each_byte do |byte| - hash += byte - hash &= MAX_32_BIT - hash += ((hash << 10) & MAX_32_BIT) - hash &= MAX_32_BIT - hash ^= hash >> 6 - end - - hash += ((hash << 3) & MAX_32_BIT) - hash &= MAX_32_BIT - hash ^= hash >> 11 - hash += ((hash << 15) & MAX_32_BIT) - hash &= MAX_32_BIT - hash - end - - MAX_32_BIT = 4_294_967_295 - end - - # @private - # Orders items by modification time (most recent modified first). - class RecentlyModified - def order(list) - list.sort_by { |item| -File.mtime(item.metadata[:absolute_file_path]).to_i } - end - end - - # @private - # Orders items based on a custom block. - class Custom - def initialize(callable) - @callable = callable - end - - def order(list) - @callable.call(list) - end - end - - # @private - # A strategy which delays looking up the ordering until needed - class Delayed - def initialize(registry, name) - @registry = registry - @name = name - end - - def order(list) - strategy.order(list) - end - - private - - def strategy - @strategy ||= lookup_strategy - end - - def lookup_strategy - raise "Undefined ordering strategy #{@name.inspect}" unless @registry.has_strategy?(@name) - @registry.fetch(@name) - end - end - - # @private - # Stores the different ordering strategies. - class Registry - def initialize(configuration) - @configuration = configuration - @strategies = {} - - register(:random, Random.new(configuration)) - register(:recently_modified, RecentlyModified.new) - - identity = Identity.new - register(:defined, identity) - - # The default global ordering is --defined. - register(:global, identity) - end - - def fetch(name, &fallback) - @strategies.fetch(name, &fallback) - end - - def has_strategy?(name) - @strategies.key?(name) - end - - def register(sym, strategy) - @strategies[sym] = strategy - end - - def used_random_seed? - @strategies[:random].used? - end - end - - # @private - # Manages ordering configuration. - # - # @note This is not intended to be used externally. Use - # the APIs provided by `RSpec::Core::Configuration` instead. - class ConfigurationManager - attr_reader :seed, :ordering_registry - - def initialize - @ordering_registry = Registry.new(self) - @seed = rand(0xFFFF) - @seed_forced = false - @order_forced = false - end - - def seed_used? - ordering_registry.used_random_seed? - end - - def seed=(seed) - return if @seed_forced - register_ordering(:global, ordering_registry.fetch(:random)) - @seed = seed.to_i - end - - def order=(type) - order, seed = type.to_s.split(':') - @seed = seed.to_i if seed - - ordering_name = if order.include?('rand') - :random - elsif order == 'defined' - :defined - elsif order == 'recently-modified' - :recently_modified - else - order.to_sym - end - - if ordering_name - strategy = - if ordering_registry.has_strategy?(ordering_name) - ordering_registry.fetch(ordering_name) - else - Delayed.new(ordering_registry, ordering_name) - end - - register_ordering(:global, strategy) - end - end - - def force(hash) - if hash.key?(:seed) - self.seed = hash[:seed] - @seed_forced = true - @order_forced = true - elsif hash.key?(:order) - self.order = hash[:order] - @order_forced = true - end - end - - def register_ordering(name, strategy=Custom.new(Proc.new { |l| yield l })) - return if @order_forced && name == :global - ordering_registry.register(name, strategy) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb deleted file mode 100644 index 8e07aa8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/output_wrapper.rb +++ /dev/null @@ -1,29 +0,0 @@ -module RSpec - module Core - # @private - class OutputWrapper - # @private - attr_accessor :output - - # @private - def initialize(output) - @output = output - end - - def respond_to?(name, priv=false) - output.respond_to?(name, priv) - end - - def method_missing(name, *args, &block) - output.__send__(name, *args, &block) - end - - # Redirect calls for IO interface methods - IO.instance_methods(false).each do |method| - define_method(method) do |*args, &block| - output.__send__(method, *args, &block) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb deleted file mode 100644 index c6c59c1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/pending.rb +++ /dev/null @@ -1,157 +0,0 @@ -module RSpec - module Core - # Provides methods to mark examples as pending. These methods are available - # to be called from within any example or hook. - module Pending - # Raised in the middle of an example to indicate that it should be marked - # as skipped. - class SkipDeclaredInExample < StandardError - attr_reader :argument - - def initialize(argument) - @argument = argument - end - end - - # If Test::Unit is loaded, we'll use its error as baseclass, so that - # Test::Unit will report unmet RSpec expectations as failures rather than - # errors. - begin - class PendingExampleFixedError < Test::Unit::AssertionFailedError; end - rescue - class PendingExampleFixedError < StandardError; end - end - - # @private - NO_REASON_GIVEN = 'No reason given' - - # @private - NOT_YET_IMPLEMENTED = 'Not yet implemented' - - # @overload pending() - # @overload pending(message) - # - # Marks an example as pending. The rest of the example will still be - # executed, and if it passes the example will fail to indicate that the - # pending can be removed. - # - # @param message [String] optional message to add to the summary report. - # - # @example - # describe "some behaviour" do - # # reported as "Pending: no reason given" - # it "is pending with no message" do - # pending - # raise "broken" - # end - # - # # reported as "Pending: something else getting finished" - # it "is pending with a custom message" do - # pending("something else getting finished") - # raise "broken" - # end - # end - # - # @note When using `pending` inside an example body using this method - # hooks, such as `before(:example)`, have already be run. This means that - # a failure from the code in the `before` hook will prevent the example - # from being considered pending, as the example body would not be - # executed. If you need to consider hooks as pending as well you can use - # the pending metadata as an alternative, e.g. - # `it "does something", pending: "message"`. - def pending(message=nil, &_block) - current_example = RSpec.current_example - - if block_given? - raise ArgumentError, <<-EOS.gsub(/^\s+\|/, '') - |The semantics of `RSpec::Core::Pending#pending` have changed in - |RSpec 3. In RSpec 2.x, it caused the example to be skipped. In - |RSpec 3, the rest of the example is still run but is expected to - |fail, and will be marked as a failure (rather than as pending) if - |the example passes. - | - |Passing a block within an example is now deprecated. Marking the - |example as pending provides the same behavior in RSpec 3 which was - |provided only by the block in RSpec 2.x. - | - |Move the code in the block provided to `pending` into the rest of - |the example body. - | - |Called from #{CallerFilter.first_non_rspec_line}. - | - EOS - elsif current_example - Pending.mark_pending! current_example, message - else - raise "`pending` may not be used outside of examples, such as in " \ - "before(:context). Maybe you want `skip`?" - end - end - - # @overload skip() - # @overload skip(message) - # - # Marks an example as pending and skips execution. - # - # @param message [String] optional message to add to the summary report. - # - # @example - # describe "an example" do - # # reported as "Pending: no reason given" - # it "is skipped with no message" do - # skip - # end - # - # # reported as "Pending: something else getting finished" - # it "is skipped with a custom message" do - # skip "something else getting finished" - # end - # end - def skip(message=nil) - current_example = RSpec.current_example - - Pending.mark_skipped!(current_example, message) if current_example - - raise SkipDeclaredInExample.new(message) - end - - # @private - # - # Mark example as skipped. - # - # @param example [RSpec::Core::Example] the example to mark as skipped - # @param message_or_bool [Boolean, String] the message to use, or true - def self.mark_skipped!(example, message_or_bool) - Pending.mark_pending! example, message_or_bool - example.metadata[:skip] = true - end - - # @private - # - # Mark example as pending. - # - # @param example [RSpec::Core::Example] the example to mark as pending - # @param message_or_bool [Boolean, String] the message to use, or true - def self.mark_pending!(example, message_or_bool) - message = if !message_or_bool || !(String === message_or_bool) - NO_REASON_GIVEN - else - message_or_bool - end - - example.metadata[:pending] = true - example.execution_result.pending_message = message - example.execution_result.pending_fixed = false - end - - # @private - # - # Mark example as fixed. - # - # @param example [RSpec::Core::Example] the example to mark as fixed - def self.mark_fixed!(example) - example.execution_result.pending_fixed = true - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb deleted file mode 100644 index 5e65279..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/profiler.rb +++ /dev/null @@ -1,34 +0,0 @@ -module RSpec - module Core - # @private - class Profiler - NOTIFICATIONS = [:example_group_started, :example_group_finished, :example_started] - - def initialize - @example_groups = Hash.new { |h, k| h[k] = { :count => 0 } } - end - - attr_reader :example_groups - - def example_group_started(notification) - return unless notification.group.top_level? - - @example_groups[notification.group][:start] = Time.now - @example_groups[notification.group][:description] = notification.group.top_level_description - end - - def example_group_finished(notification) - return unless notification.group.top_level? - - group = @example_groups[notification.group] - return unless group.key?(:start) - group[:total_time] = Time.now - group[:start] - end - - def example_started(notification) - group = notification.example.example_group.parent_groups.last - @example_groups[group][:count] += 1 - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb deleted file mode 100644 index ca707e0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer.rb +++ /dev/null @@ -1,48 +0,0 @@ -RSpec::Support.require_rspec_support "directory_maker" - -module RSpec - module Core - # @private - # Generates conventional files for an RSpec project. - class ProjectInitializer - attr_reader :destination, :stream, :template_path - - DOT_RSPEC_FILE = '.rspec' - SPEC_HELPER_FILE = 'spec/spec_helper.rb' - - def initialize(opts={}) - @destination = opts.fetch(:destination, Dir.getwd) - @stream = opts.fetch(:report_stream, $stdout) - @template_path = opts.fetch(:template_path) do - File.expand_path("../project_initializer", __FILE__) - end - end - - def run - copy_template DOT_RSPEC_FILE - copy_template SPEC_HELPER_FILE - end - - private - - def copy_template(file) - destination_file = File.join(destination, file) - return report_exists(file) if File.exist?(destination_file) - - report_creating(file) - RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(destination_file)) - File.open(destination_file, 'w') do |f| - f.write File.read(File.join(template_path, file)) - end - end - - def report_exists(file) - stream.puts " exist #{file}" - end - - def report_creating(file) - stream.puts " create #{file}" - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec deleted file mode 100644 index c99d2e7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/.rspec +++ /dev/null @@ -1 +0,0 @@ ---require spec_helper diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb deleted file mode 100644 index c80d44b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/project_initializer/spec/spec_helper.rb +++ /dev/null @@ -1,98 +0,0 @@ -# This file was generated by the `rspec --init` command. Conventionally, all -# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. -# The generated `.rspec` file contains `--require spec_helper` which will cause -# this file to always be loaded, without a need to explicitly require it in any -# files. -# -# Given that it is always loaded, you are encouraged to keep this file as -# light-weight as possible. Requiring heavyweight dependencies from this file -# will add to the boot time of your test suite on EVERY test run, even for an -# individual file that may not need all of that loaded. Instead, consider making -# a separate helper file that requires the additional dependencies and performs -# the additional setup, and require it from the spec files that actually need -# it. -# -# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration -RSpec.configure do |config| - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # This option will default to `true` in RSpec 4. It makes the `description` - # and `failure_message` of custom matchers include text for helper methods - # defined using `chain`, e.g.: - # be_bigger_than(2).and_smaller_than(4).description - # # => "be bigger than 2 and smaller than 4" - # ...rather than: - # # => "be bigger than 2" - expectations.include_chain_clauses_in_custom_matcher_descriptions = true - end - - # rspec-mocks config goes here. You can use an alternate test double - # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| - # Prevents you from mocking or stubbing a method that does not exist on - # a real object. This is generally recommended, and will default to - # `true` in RSpec 4. - mocks.verify_partial_doubles = true - end - - # This option will default to `:apply_to_host_groups` in RSpec 4 (and will - # have no way to turn it off -- the option exists only for backwards - # compatibility in RSpec 3). It causes shared context metadata to be - # inherited by the metadata hash of host groups and examples, rather than - # triggering implicit auto-inclusion in groups with matching metadata. - config.shared_context_metadata_behavior = :apply_to_host_groups - -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # This allows you to limit a spec run to individual examples or groups - # you care about by tagging them with `:focus` metadata. When nothing - # is tagged with `:focus`, all examples get run. RSpec also provides - # aliases for `it`, `describe`, and `context` that include `:focus` - # metadata: `fit`, `fdescribe` and `fcontext`, respectively. - config.filter_run_when_matching :focus - - # Allows RSpec to persist some state between runs in order to support - # the `--only-failures` and `--next-failure` CLI options. We recommend - # you configure your source control system to ignore this file. - config.example_status_persistence_file_path = "spec/examples.txt" - - # Limits the available syntax to the non-monkey patched syntax that is - # recommended. For more details, see: - # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ - config.disable_monkey_patching! - - # This setting enables warnings. It's recommended, but in some cases may - # be too noisy due to issues in dependencies. - config.warnings = true - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = "doc" - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed -=end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb deleted file mode 100644 index 1b60db0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/rake_task.rb +++ /dev/null @@ -1,190 +0,0 @@ -require 'rake' -require 'rake/tasklib' -require 'rspec/support' - -RSpec::Support.require_rspec_support "ruby_features" - -# :nocov: -unless RSpec::Support.respond_to?(:require_rspec_core) - RSpec::Support.define_optimized_require_for_rspec(:core) { |f| require_relative "../#{f}" } -end -# :nocov: - -RSpec::Support.require_rspec_core "shell_escape" - -module RSpec - module Core - # RSpec rake task - # - # @see Rakefile - class RakeTask < ::Rake::TaskLib - include ::Rake::DSL if defined?(::Rake::DSL) - include RSpec::Core::ShellEscape - - # Default path to the RSpec executable. - DEFAULT_RSPEC_PATH = File.expand_path('../../../../exe/rspec', __FILE__) - - # Default pattern for spec files. - DEFAULT_PATTERN = 'spec/**{,/*/**}/*_spec.rb' - - # Name of task. Defaults to `:spec`. - attr_accessor :name - - # Files matching this pattern will be loaded. - # Defaults to `'spec/**{,/*/**}/*_spec.rb'`. - attr_accessor :pattern - - # Files matching this pattern will be excluded. - # Defaults to `nil`. - attr_accessor :exclude_pattern - - # Whether or not to fail Rake when an error occurs (typically when - # examples fail). Defaults to `true`. - attr_accessor :fail_on_error - - # A message to print to stderr when there are failures. - attr_accessor :failure_message - - if RUBY_VERSION < "1.9.0" || Support::Ruby.jruby? - # Run RSpec with a clean (empty) environment is not supported - # :nocov: - def with_clean_environment=(_value) - raise ArgumentError, "Running in a clean environment is not supported on Ruby versions before 1.9.0" - end - - # Run RSpec with a clean (empty) environment is not supported - def with_clean_environment - false - end - # :nocov: - else - # Run RSpec with a clean (empty) environment. - attr_accessor :with_clean_environment - end - - # Use verbose output. If this is set to true, the task will print the - # executed spec command to stdout. Defaults to `true`. - attr_accessor :verbose - - # Command line options to pass to ruby. Defaults to `nil`. - attr_accessor :ruby_opts - - # Path to RSpec. Defaults to the absolute path to the - # rspec binary from the loaded rspec-core gem. - attr_accessor :rspec_path - - # Command line options to pass to RSpec. Defaults to `nil`. - attr_accessor :rspec_opts - - def initialize(*args, &task_block) - @name = args.shift || :spec - @ruby_opts = nil - @rspec_opts = nil - @verbose = true - @fail_on_error = true - @rspec_path = DEFAULT_RSPEC_PATH - @pattern = DEFAULT_PATTERN - - define(args, &task_block) - end - - # @private - def run_task(verbose) - command = spec_command - puts command if verbose - - if with_clean_environment - return if system({}, command, :unsetenv_others => true) - else - return if system(command) - end - - puts failure_message if failure_message - - return unless fail_on_error - $stderr.puts "#{command} failed" if verbose - exit $?.exitstatus || 1 - end - - private - - # @private - def define(args, &task_block) - desc "Run RSpec code examples" unless ::Rake.application.last_description - - task name, *args do |_, task_args| - RakeFileUtils.__send__(:verbose, verbose) do - task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block - run_task verbose - end - end - end - - def file_inclusion_specification - if ENV['SPEC'] - FileList[ENV['SPEC']].sort - elsif String === pattern && !File.exist?(pattern) - return if [*rspec_opts].any? { |opt| opt =~ /--pattern/ } - "--pattern #{escape pattern}" - else - # Before RSpec 3.1, we used `FileList` to get the list of matched - # files, and then pass that along to the `rspec` command. Starting - # with 3.1, we prefer to pass along the pattern as-is to the `rspec` - # command, for 3 reasons: - # - # * It's *much* less verbose to pass one `--pattern` option than a - # long list of files. - # * It ensures `task.pattern` and `--pattern` have the same - # behavior. - # * It fixes a bug, where - # `task.pattern = pattern_that_matches_no_files` would run *all* - # files because it would cause no pattern or file args to get - # passed to `rspec`, which causes all files to get run. - # - # However, `FileList` is *far* more flexible than the `--pattern` - # option. Specifically, it supports individual files and directories, - # as well as arrays of files, directories and globs, as well as other - # `FileList` objects. - # - # For backwards compatibility, we have to fall back to using FileList - # if the user has passed a `pattern` option that will not work with - # `--pattern`. - # - # TODO: consider deprecating support for this and removing it in - # RSpec 4. - FileList[pattern].sort.map { |file| escape file } - end - end - - def file_exclusion_specification - " --exclude-pattern #{escape exclude_pattern}" if exclude_pattern - end - - def spec_command - cmd_parts = [] - cmd_parts << RUBY - cmd_parts << ruby_opts - cmd_parts << rspec_load_path - cmd_parts << escape(rspec_path) - cmd_parts << file_inclusion_specification - cmd_parts << file_exclusion_specification - cmd_parts << rspec_opts - cmd_parts.flatten.reject(&blank).join(" ") - end - - def blank - lambda { |s| s.nil? || s == "" } - end - - def rspec_load_path - @rspec_load_path ||= begin - core_and_support = $LOAD_PATH.grep( - /#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib/ - ).uniq - - "-I#{core_and_support.map { |file| escape file }.join(File::PATH_SEPARATOR)}" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb deleted file mode 100644 index d513f3f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb +++ /dev/null @@ -1,266 +0,0 @@ -module RSpec::Core - # A reporter will send notifications to listeners, usually formatters for the - # spec suite run. - class Reporter - # @private - RSPEC_NOTIFICATIONS = Set.new( - [ - :close, :deprecation, :deprecation_summary, :dump_failures, :dump_pending, - :dump_profile, :dump_summary, :example_failed, :example_group_finished, - :example_group_started, :example_passed, :example_pending, :example_started, - :message, :seed, :start, :start_dump, :stop, :example_finished - ]) - - def initialize(configuration) - @configuration = configuration - @listeners = Hash.new { |h, k| h[k] = Set.new } - @examples = [] - @failed_examples = [] - @pending_examples = [] - @duration = @start = @load_time = nil - @non_example_exception_count = 0 - @setup_default = lambda {} - @setup = false - @profiler = nil - end - - # @private - attr_reader :examples, :failed_examples, :pending_examples - - # Registers a listener to a list of notifications. The reporter will send - # notification of events to all registered listeners. - # - # @param listener [Object] An object that wishes to be notified of reporter - # events - # @param notifications [Array] Array of symbols represents the events a - # listener wishes to subscribe too - def register_listener(listener, *notifications) - notifications.each do |notification| - @listeners[notification.to_sym] << listener - end - true - end - - # @private - def prepare_default(loader, output_stream, deprecation_stream) - @setup_default = lambda do - loader.setup_default output_stream, deprecation_stream - end - end - - # @private - def registered_listeners(notification) - @listeners[notification].to_a - end - - # @overload report(count, &block) - # @overload report(count, &block) - # @param expected_example_count [Integer] the number of examples being run - # @yield [Block] block yields itself for further reporting. - # - # Initializes the report run and yields itself for further reporting. The - # block is required, so that the reporter can manage cleaning up after the - # run. - # - # @example - # - # reporter.report(group.examples.size) do |r| - # example_groups.map {|g| g.run(r) } - # end - # - def report(expected_example_count) - start(expected_example_count) - begin - yield self - ensure - finish - end - end - - # @param exit_code [Integer] the exit_code to be return by the reporter - # - # Reports a run that exited early without having run any examples. - # - def exit_early(exit_code) - report(0) { exit_code } - end - - # @private - def start(expected_example_count, time=RSpec::Core::Time.now) - @start = time - @load_time = (@start - @configuration.start_time).to_f - notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?) - notify :start, Notifications::StartNotification.new(expected_example_count, @load_time) - end - - # @param message [#to_s] A message object to send to formatters - # - # Send a custom message to supporting formatters. - def message(message) - notify :message, Notifications::MessageNotification.new(message) - end - - # @param event [Symbol] Name of the custom event to trigger on formatters - # @param options [Hash] Hash of arguments to provide via `CustomNotification` - # - # Publish a custom event to supporting registered formatters. - # @see RSpec::Core::Notifications::CustomNotification - def publish(event, options={}) - if RSPEC_NOTIFICATIONS.include? event - raise "RSpec::Core::Reporter#publish is intended for sending custom " \ - "events not internal RSpec ones, please rename your custom event." - end - notify event, Notifications::CustomNotification.for(options) - end - - # @private - def example_group_started(group) - notify :example_group_started, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty? - end - - # @private - def example_group_finished(group) - notify :example_group_finished, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty? - end - - # @private - def example_started(example) - @examples << example - notify :example_started, Notifications::ExampleNotification.for(example) - end - - # @private - def example_finished(example) - notify :example_finished, Notifications::ExampleNotification.for(example) - end - - # @private - def example_passed(example) - notify :example_passed, Notifications::ExampleNotification.for(example) - end - - # @private - def example_failed(example) - @failed_examples << example - notify :example_failed, Notifications::ExampleNotification.for(example) - end - - # @private - def example_pending(example) - @pending_examples << example - notify :example_pending, Notifications::ExampleNotification.for(example) - end - - # @private - def deprecation(hash) - notify :deprecation, Notifications::DeprecationNotification.from_hash(hash) - end - - # @private - # Provides a way to notify of an exception that is not tied to any - # particular example (such as an exception encountered in a :suite hook). - # Exceptions will be formatted the same way they normally are. - def notify_non_example_exception(exception, context_description) - @configuration.world.non_example_failure = true - @non_example_exception_count += 1 - - example = Example.new(AnonymousExampleGroup, context_description, {}) - presenter = Formatters::ExceptionPresenter.new(exception, example, :indentation => 0) - message presenter.fully_formatted(nil) - end - - # @private - def finish - close_after do - examples_notification = Notifications::ExamplesNotification.new(self) - stop(examples_notification) - notify :start_dump, Notifications::NullNotification - notify :dump_pending, examples_notification - notify :dump_failures, examples_notification - notify :deprecation_summary, Notifications::NullNotification - unless mute_profile_output? - notify :dump_profile, Notifications::ProfileNotification.new(@duration, @examples, - @configuration.profile_examples, - @profiler.example_groups) - end - notify :dump_summary, Notifications::SummaryNotification.new(@duration, @examples, @failed_examples, - @pending_examples, @load_time, - @non_example_exception_count) - notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?) - end - end - - # @private - def close_after - yield - ensure - close - end - - # @private - def stop(notification) - @duration = (RSpec::Core::Time.now - @start).to_f if @start - notify :stop, notification - end - - # @private - def notify(event, notification) - ensure_listeners_ready - registered_listeners(event).each do |formatter| - formatter.__send__(event, notification) - end - end - - # @private - def abort_with(msg, exit_status) - message(msg) - close - exit!(exit_status) - end - - # @private - def fail_fast_limit_met? - return false unless (fail_fast = @configuration.fail_fast) - - if fail_fast == true - @failed_examples.any? - else - fail_fast <= @failed_examples.size - end - end - - private - - def ensure_listeners_ready - return if @setup - - @setup_default.call - @profiler = Profiler.new - register_listener @profiler, *Profiler::NOTIFICATIONS - @setup = true - end - - def close - notify :close, Notifications::NullNotification - end - - def mute_profile_output? - # Don't print out profiled info if there are failures and `--fail-fast` is - # used, it just clutters the output. - !@configuration.profile_examples? || fail_fast_limit_met? - end - - def seed_used? - @configuration.seed && @configuration.seed_used? - end - end - - # @private - # # Used in place of a {Reporter} for situations where we don't want reporting output. - class NullReporter - def self.method_missing(*) - # ignore - end - private_class_method :method_missing - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb deleted file mode 100644 index 156f89b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/ruby_project.rb +++ /dev/null @@ -1,53 +0,0 @@ -# This is borrowed (slightly modified) from Scott Taylor's -# project_path project: -# http://github.com/smtlaissezfaire/project_path -module RSpec - module Core - # @private - module RubyProject - def add_to_load_path(*dirs) - dirs.each { |dir| add_dir_to_load_path(File.join(root, dir)) } - end - - def add_dir_to_load_path(dir) - $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) - end - - def root - @project_root ||= determine_root - end - - def determine_root - find_first_parent_containing('spec') || '.' - end - - def find_first_parent_containing(dir) - ascend_until { |path| File.exist?(File.join(path, dir)) } - end - - def ascend_until - fs = File::SEPARATOR - escaped_slash = "\\#{fs}" - special = "_RSPEC_ESCAPED_SLASH_" - project_path = File.expand_path(".") - parts = project_path.gsub(escaped_slash, special).squeeze(fs).split(fs).map do |x| - x.gsub(special, escaped_slash) - end - - until parts.empty? - path = parts.join(fs) - path = fs if path == "" - return path if yield(path) - parts.pop - end - end - - module_function :add_to_load_path - module_function :add_dir_to_load_path - module_function :root - module_function :determine_root - module_function :find_first_parent_containing - module_function :ascend_until - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb deleted file mode 100644 index 16d07ef..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb +++ /dev/null @@ -1,216 +0,0 @@ -module RSpec - module Core - # Provides the main entry point to run a suite of RSpec examples. - class Runner - # @attr_reader - # @private - attr_reader :options, :configuration, :world - - # Register an `at_exit` hook that runs the suite when the process exits. - # - # @note This is not generally needed. The `rspec` command takes care - # of running examples for you without involving an `at_exit` - # hook. This is only needed if you are running specs using - # the `ruby` command, and even then, the normal way to invoke - # this is by requiring `rspec/autorun`. - def self.autorun - if autorun_disabled? - RSpec.deprecate("Requiring `rspec/autorun` when running RSpec via the `rspec` command") - return - elsif installed_at_exit? || running_in_drb? - return - end - - at_exit { perform_at_exit } - @installed_at_exit = true - end - - # @private - def self.perform_at_exit - # Don't bother running any specs and just let the program terminate - # if we got here due to an unrescued exception (anything other than - # SystemExit, which is raised when somebody calls Kernel#exit). - return unless $!.nil? || $!.is_a?(SystemExit) - - # We got here because either the end of the program was reached or - # somebody called Kernel#exit. Run the specs and then override any - # existing exit status with RSpec's exit status if any specs failed. - invoke - end - - # Runs the suite of specs and exits the process with an appropriate exit - # code. - def self.invoke - disable_autorun! - status = run(ARGV, $stderr, $stdout).to_i - exit(status) if status != 0 - end - - # Run a suite of RSpec examples. Does not exit. - # - # This is used internally by RSpec to run a suite, but is available - # for use by any other automation tool. - # - # If you want to run this multiple times in the same process, and you - # want files like `spec_helper.rb` to be reloaded, be sure to load `load` - # instead of `require`. - # - # @param args [Array] command-line-supported arguments - # @param err [IO] error stream - # @param out [IO] output stream - # @return [Fixnum] exit status code. 0 if all specs passed, - # or the configured failure exit code (1 by default) if specs - # failed. - def self.run(args, err=$stderr, out=$stdout) - trap_interrupt - options = ConfigurationOptions.new(args) - - if options.options[:runner] - options.options[:runner].call(options, err, out) - else - new(options).run(err, out) - end - end - - def initialize(options, configuration=RSpec.configuration, world=RSpec.world) - @options = options - @configuration = configuration - @world = world - end - - # Configures and runs a spec suite. - # - # @param err [IO] error stream - # @param out [IO] output stream - def run(err, out) - setup(err, out) - return @configuration.reporter.exit_early(exit_code) if RSpec.world.wants_to_quit - - run_specs(@world.ordered_example_groups).tap do - persist_example_statuses - end - end - - # Wires together the various configuration objects and state holders. - # - # @param err [IO] error stream - # @param out [IO] output stream - def setup(err, out) - configure(err, out) - return if RSpec.world.wants_to_quit - - @configuration.load_spec_files - ensure - @world.announce_filters - end - - # Runs the provided example groups. - # - # @param example_groups [Array] groups to run - # @return [Fixnum] exit status code. 0 if all specs passed, - # or the configured failure exit code (1 by default) if specs - # failed. - def run_specs(example_groups) - examples_count = @world.example_count(example_groups) - examples_passed = @configuration.reporter.report(examples_count) do |reporter| - @configuration.with_suite_hooks do - if examples_count == 0 && @configuration.fail_if_no_examples - return @configuration.failure_exit_code - end - - example_groups.map { |g| g.run(reporter) }.all? - end - end - - exit_code(examples_passed) - end - - # @private - def configure(err, out) - @configuration.error_stream = err - @configuration.output_stream = out if @configuration.output_stream == $stdout - @options.configure(@configuration) - end - - # @private - def self.disable_autorun! - @autorun_disabled = true - end - - # @private - def self.autorun_disabled? - @autorun_disabled ||= false - end - - # @private - def self.installed_at_exit? - @installed_at_exit ||= false - end - - # @private - def self.running_in_drb? - return false unless defined?(DRb) - - server = begin - DRb.current_server - rescue DRb::DRbServerNotFound - return false - end - - return false unless server && server.alive? - - require 'socket' - require 'uri' - - local_ipv4 = begin - IPSocket.getaddress(Socket.gethostname) - rescue SocketError - return false - end - - ["127.0.0.1", "localhost", local_ipv4].any? { |addr| addr == URI(DRb.current_server.uri).host } - end - - # @private - def self.trap_interrupt - trap('INT') { handle_interrupt } - end - - # @private - def self.handle_interrupt - if RSpec.world.wants_to_quit - exit!(1) - else - RSpec.world.wants_to_quit = true - - $stderr.puts( - "\nRSpec is shutting down and will print the summary report... Interrupt again to force quit " \ - "(warning: at_exit hooks will be skipped if you force quit)." - ) - end - end - - # @private - def exit_code(examples_passed=false) - return @configuration.error_exit_code || @configuration.failure_exit_code if @world.non_example_failure - return @configuration.failure_exit_code unless examples_passed - - 0 - end - - private - - def persist_example_statuses - return if @configuration.dry_run - return unless (path = @configuration.example_status_persistence_file_path) - - ExampleStatusPersister.persist(@world.all_examples, path) - rescue SystemCallError => e - RSpec.warning "Could not write example statuses to #{path} (configured as " \ - "`config.example_status_persistence_file_path`) due to a " \ - "system error: #{e.inspect}. Please check that the config " \ - "option is set to an accessible, valid file path", :call_site => nil - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb deleted file mode 100644 index e7d518c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/sandbox.rb +++ /dev/null @@ -1,37 +0,0 @@ -module RSpec - module Core - # A sandbox isolates the enclosed code into an environment that looks 'new' - # meaning globally accessed objects are reset for the duration of the - # sandbox. - # - # @note This module is not normally available. You must require - # `rspec/core/sandbox` to load it. - module Sandbox - # Execute a provided block with RSpec global objects (configuration, - # world) reset. This is used to test RSpec with RSpec. - # - # When calling this the configuration is passed into the provided block. - # Use this to set custom configs for your sandboxed examples. - # - # ``` - # Sandbox.sandboxed do |config| - # config.before(:context) { RSpec.current_example = nil } - # end - # ``` - def self.sandboxed - orig_config = RSpec.configuration - orig_world = RSpec.world - orig_example = RSpec.current_example - - RSpec.configuration = RSpec::Core::Configuration.new - RSpec.world = RSpec::Core::World.new(RSpec.configuration) - - yield RSpec.configuration - ensure - RSpec.configuration = orig_config - RSpec.world = orig_world - RSpec.current_example = orig_example - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb deleted file mode 100644 index ae97810..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/set.rb +++ /dev/null @@ -1,54 +0,0 @@ -module RSpec - module Core - # @private - # - # We use this to replace `::Set` so we can have the advantage of - # constant time key lookups for unique arrays but without the - # potential to pollute a developers environment with an extra - # piece of the stdlib. This helps to prevent false positive - # builds. - # - class Set - include Enumerable - - def initialize(array=[]) - @values = {} - merge(array) - end - - def empty? - @values.empty? - end - - def <<(key) - @values[key] = true - self - end - - def delete(key) - @values.delete(key) - end - - def each(&block) - @values.keys.each(&block) - self - end - - def include?(key) - @values.key?(key) - end - - def merge(values) - values.each do |key| - @values[key] = true - end - self - end - - def clear - @values.clear - self - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb deleted file mode 100644 index 6de7f64..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_context.rb +++ /dev/null @@ -1,55 +0,0 @@ -module RSpec - module Core - # Exposes {ExampleGroup}-level methods to a module, so you can include that - # module in an {ExampleGroup}. - # - # @example - # - # module LoggedInAsAdmin - # extend RSpec::Core::SharedContext - # before(:example) do - # log_in_as :admin - # end - # end - # - # describe "admin section" do - # include LoggedInAsAdmin - # # ... - # end - module SharedContext - # @private - def included(group) - __shared_context_recordings.each do |recording| - recording.playback_onto(group) - end - end - - # @private - def __shared_context_recordings - @__shared_context_recordings ||= [] - end - - # @private - Recording = Struct.new(:method_name, :args, :block) do - def playback_onto(group) - group.__send__(method_name, *args, &block) - end - end - - # @private - def self.record(methods) - methods.each do |meth| - define_method(meth) do |*args, &block| - __shared_context_recordings << Recording.new(meth, args, block) - end - end - end - - # @private - record [:describe, :context] + Hooks.instance_methods(false) + - MemoizedHelpers::ClassMethods.instance_methods(false) - end - end - # @private - SharedContext = Core::SharedContext -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb deleted file mode 100644 index 3d9efce..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shared_example_group.rb +++ /dev/null @@ -1,271 +0,0 @@ -RSpec::Support.require_rspec_support "with_keywords_when_needed" - -module RSpec - module Core - # Represents some functionality that is shared with multiple example groups. - # The functionality is defined by the provided block, which is lazily - # eval'd when the `SharedExampleGroupModule` instance is included in an example - # group. - class SharedExampleGroupModule < Module - # @private - attr_reader :definition - - def initialize(description, definition, metadata) - @description = description - @definition = definition - @metadata = metadata - end - - # Provides a human-readable representation of this module. - def inspect - "#<#{self.class.name} #{@description.inspect}>" - end - alias to_s inspect - - # Ruby callback for when a module is included in another module is class. - # Our definition evaluates the shared group block in the context of the - # including example group. - def included(klass) - inclusion_line = klass.metadata[:location] - include_in klass, inclusion_line, [], nil - end - - # @private - def include_in(klass, inclusion_line, args, customization_block) - klass.update_inherited_metadata(@metadata) unless @metadata.empty? - - SharedExampleGroupInclusionStackFrame.with_frame(@description, inclusion_line) do - RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *args, &@definition) - klass.class_exec(&customization_block) if customization_block - end - end - end - - # Shared example groups let you define common context and/or common - # examples that you wish to use in multiple example groups. - # - # When defined, the shared group block is stored for later evaluation. - # It can later be included in an example group either explicitly - # (using `include_examples`, `include_context` or `it_behaves_like`) - # or implicitly (via matching metadata). - # - # Named shared example groups are scoped based on where they are - # defined. Shared groups defined in an example group are available - # for inclusion in that example group or any child example groups, - # but not in any parent or sibling example groups. Shared example - # groups defined at the top level can be included from any example group. - module SharedExampleGroup - # @overload shared_examples(name, &block) - # @param name [String, Symbol, Module] identifer to use when looking up - # this shared group - # @param block The block to be eval'd - # @overload shared_examples(name, metadata, &block) - # @param name [String, Symbol, Module] identifer to use when looking up - # this shared group - # @param metadata [Array, Hash] metadata to attach to this - # group; any example group or example with matching metadata will - # automatically include this shared example group. - # @param block The block to be eval'd - # - # Stores the block for later use. The block will be evaluated - # in the context of an example group via `include_examples`, - # `include_context`, or `it_behaves_like`. - # - # @example - # shared_examples "auditable" do - # it "stores an audit record on save!" do - # expect { auditable.save! }.to change(Audit, :count).by(1) - # end - # end - # - # RSpec.describe Account do - # it_behaves_like "auditable" do - # let(:auditable) { Account.new } - # end - # end - # - # @see ExampleGroup.it_behaves_like - # @see ExampleGroup.include_examples - # @see ExampleGroup.include_context - def shared_examples(name, *args, &block) - top_level = self == ExampleGroup - if top_level && RSpec::Support.thread_local_data[:in_example_group] - raise "Creating isolated shared examples from within a context is " \ - "not allowed. Remove `RSpec.` prefix or move this to a " \ - "top-level scope." - end - - RSpec.world.shared_example_group_registry.add(self, name, *args, &block) - end - alias shared_context shared_examples - alias shared_examples_for shared_examples - - # @api private - # - # Shared examples top level DSL. - module TopLevelDSL - # @private - def self.definitions - proc do - def shared_examples(name, *args, &block) - RSpec.world.shared_example_group_registry.add(:main, name, *args, &block) - end - alias shared_context shared_examples - alias shared_examples_for shared_examples - end - end - - # @private - def self.exposed_globally? - @exposed_globally ||= false - end - - # @api private - # - # Adds the top level DSL methods to Module and the top level binding. - def self.expose_globally! - return if exposed_globally? - Core::DSL.change_global_dsl(&definitions) - @exposed_globally = true - end - - # @api private - # - # Removes the top level DSL methods to Module and the top level binding. - def self.remove_globally! - return unless exposed_globally? - - Core::DSL.change_global_dsl do - undef shared_examples - undef shared_context - undef shared_examples_for - end - - @exposed_globally = false - end - end - - # @private - class Registry - def add(context, name, *metadata_args, &block) - unless block - RSpec.warning "Shared example group #{name} was defined without a "\ - "block and will have no effect. Please define a "\ - "block or remove the definition." - end - - if RSpec.configuration.shared_context_metadata_behavior == :trigger_inclusion - return legacy_add(context, name, *metadata_args, &block) - end - - unless valid_name?(name) - raise ArgumentError, "Shared example group names can only be a string, " \ - "symbol or module but got: #{name.inspect}" - end - - ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line } - warn_if_key_taken context, name, block - - metadata = Metadata.build_hash_from(metadata_args) - shared_module = SharedExampleGroupModule.new(name, block, metadata) - shared_example_groups[context][name] = shared_module - end - - def find(lookup_contexts, name) - lookup_contexts.each do |context| - found = shared_example_groups[context][name] - return found if found - end - - shared_example_groups[:main][name] - end - - private - - # TODO: remove this in RSpec 4. This exists only to support - # `config.shared_context_metadata_behavior == :trigger_inclusion`, - # the legacy behavior of shared context metadata, which we do - # not want to support in RSpec 4. - def legacy_add(context, name, *metadata_args, &block) - ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line } - shared_module = SharedExampleGroupModule.new(name, block, {}) - - if valid_name?(name) - warn_if_key_taken context, name, block - shared_example_groups[context][name] = shared_module - else - metadata_args.unshift name - end - - return if metadata_args.empty? - RSpec.configuration.include shared_module, *metadata_args - end - - def shared_example_groups - @shared_example_groups ||= Hash.new { |hash, context| hash[context] = {} } - end - - def valid_name?(candidate) - case candidate - when String, Symbol, Module then true - else false - end - end - - def warn_if_key_taken(context, key, new_block) - existing_module = shared_example_groups[context][key] - return unless existing_module - - old_definition_location = formatted_location existing_module.definition - new_definition_location = formatted_location new_block - loaded_spec_files = RSpec.configuration.loaded_spec_files - - if loaded_spec_files.include?(new_definition_location) && old_definition_location == new_definition_location - RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil - |WARNING: Your shared example group, '#{key}', defined at: - | #{old_definition_location} - |was automatically loaded by RSpec because the file name - |matches the configured autoloading pattern (#{RSpec.configuration.pattern}), - |and is also being required from somewhere else. To fix this - |warning, either rename the file to not match the pattern, or - |do not explicitly require the file. - WARNING - else - RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil - |WARNING: Shared example group '#{key}' has been previously defined at: - | #{old_definition_location} - |...and you are now defining it at: - | #{new_definition_location} - |The new definition will overwrite the original one. - WARNING - end - end - - if RUBY_VERSION.to_f >= 1.9 - def formatted_location(block) - block.source_location.join(":") - end - else # 1.8.7 - # :nocov: - def formatted_location(block) - block.source_location.join(":").gsub(/:in.*$/, '') - end - # :nocov: - end - - if Proc.method_defined?(:source_location) - def ensure_block_has_source_location(_block); end - else # for 1.8.7 - # :nocov: - def ensure_block_has_source_location(block) - source_location = yield.split(':') - block.extend(Module.new { define_method(:source_location) { source_location } }) - end - # :nocov: - end - end - end - end - - instance_exec(&Core::SharedExampleGroup::TopLevelDSL.definitions) -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb deleted file mode 100644 index a92feae..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/shell_escape.rb +++ /dev/null @@ -1,49 +0,0 @@ -module RSpec - module Core - # @private - # Deals with the fact that `shellwords` only works on POSIX systems. - module ShellEscape - module_function - - def quote(argument) - "'#{argument.to_s.gsub("'", "\\\\'")}'" - end - - if RSpec::Support::OS.windows? - # :nocov: - alias escape quote - # :nocov: - else - require 'shellwords' - - def escape(shell_command) - Shellwords.escape(shell_command.to_s) - end - end - - # Known shells that require quoting: zsh, csh, tcsh. - # - # Feel free to add other shells to this list that are known to - # allow `rspec ./some_spec.rb[1:1]` syntax without quoting the id. - # - # @private - SHELLS_ALLOWING_UNQUOTED_IDS = %w[ bash ksh fish ] - - def conditionally_quote(id) - return id if shell_allows_unquoted_ids? - quote(id) - end - - def shell_allows_unquoted_ids? - # Note: ENV['SHELL'] isn't necessarily the shell the user is currently running. - # According to http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html: - # "This variable shall represent a pathname of the user's preferred command language interpreter." - # - # It's the best we can easily do, though. We err on the side of safety (quoting - # the id when not actually needed) so it's not a big deal if the user is actually - # using a different shell. - SHELLS_ALLOWING_UNQUOTED_IDS.include?(ENV['SHELL'].to_s.split('/').last) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb deleted file mode 100644 index d84ecb1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/test_unit_assertions_adapter.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'test/unit/assertions' - -module RSpec - module Core - # @private - module TestUnitAssertionsAdapter - include ::Test::Unit::Assertions - - # If using test/unit from Ruby core with Ruby 1.9+, it includes - # MiniTest::Assertions by default. Note the upcasing of 'Test'. - # - # If the test/unit gem is being loaded, it will not include any minitest - # assertions. - # - # Only if Minitest 5.x is included / loaded do we need to worry about - # adding a shim for the new updates. Thus instead of checking on the - # RUBY_VERSION we need to check ancestors. - begin - # MiniTest is 4.x. - # Minitest is 5.x. - if ancestors.include?(::Minitest::Assertions) - require 'rspec/core/minitest_assertions_adapter' - include ::RSpec::Core::MinitestAssertionsAdapter - end - rescue NameError - # No-op. Minitest 5.x was not loaded. - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb deleted file mode 100644 index ad4edc4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module RSpec - module Core - # Version information for RSpec Core. - module Version - # Current version of RSpec Core, in semantic versioning format. - STRING = '3.13.6' - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb deleted file mode 100644 index b880059..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/warnings.rb +++ /dev/null @@ -1,40 +0,0 @@ -require "rspec/support/warnings" - -module RSpec - module Core - # @private - module Warnings - # @private - # - # Used internally to print deprecation warnings. - def deprecate(deprecated, data={}) - RSpec.configuration.reporter.deprecation( - { - :deprecated => deprecated, - :call_site => CallerFilter.first_non_rspec_line - }.merge(data) - ) - end - - # @private - # - # Used internally to print deprecation warnings. - def warn_deprecation(message, opts={}) - RSpec.configuration.reporter.deprecation opts.merge(:message => message) - end - - # @private - def warn_with(message, options={}) - if options[:use_spec_location_as_call_site] - message += "." unless message.end_with?(".") - - if RSpec.current_example - message += " Warning generated from spec at `#{RSpec.current_example.location}`." - end - end - - super(message, options) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb deleted file mode 100644 index 20be84e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-core-3.13.6/lib/rspec/core/world.rb +++ /dev/null @@ -1,287 +0,0 @@ -module RSpec - module Core - # @api private - # - # Internal container for global non-configuration data. - class World - # @private - attr_reader :example_groups, :filtered_examples, :example_group_counts_by_spec_file - - # Used internally to determine what to do when a SIGINT is received. - attr_accessor :wants_to_quit - - # Used internally to signify that a SystemExit occurred in - # `Configuration#load_file_handling_errors`, and thus examples cannot - # be counted accurately. Specifically, we cannot accurately report - # "No examples found". - # @private - attr_accessor :rspec_is_quitting - - # Used internally to signal that a failure outside of an example - # has occurred, and that therefore the exit status should indicate - # the run failed. - # @private - attr_accessor :non_example_failure - - def initialize(configuration=RSpec.configuration) - @wants_to_quit = false - @rspec_is_quitting = false - @configuration = configuration - configuration.world = self - @example_groups = [] - @example_group_counts_by_spec_file = Hash.new(0) - prepare_example_filtering - end - - # @api public - # - # Prepares filters so that they apply to example groups when they run. - # - # This is a separate method so that filters can be modified/replaced and - # examples refiltered during a process's lifetime, which can be useful for - # a custom runner. - def prepare_example_filtering - @filtered_examples = Hash.new do |hash, group| - hash[group] = filter_manager.prune(group.examples) - end - end - - # @api private - # - # Apply ordering strategy from configuration to example groups. - def ordered_example_groups - ordering_strategy = @configuration.ordering_registry.fetch(:global) - ordering_strategy.order(@example_groups) - end - - # @api private - # - # Reset world to 'scratch' before running suite. - def reset - RSpec::ExampleGroups.remove_all_constants - example_groups.clear - @sources_by_path.clear if defined?(@sources_by_path) - @syntax_highlighter = nil - @example_group_counts_by_spec_file = Hash.new(0) - end - - # @private - def filter_manager - @configuration.filter_manager - end - - # @private - def registered_example_group_files - @example_group_counts_by_spec_file.keys - end - - # @api private - # - # Records an example group. - def record(example_group) - @configuration.on_example_group_definition_callbacks.each { |block| block.call(example_group) } - @example_group_counts_by_spec_file[example_group.metadata[:absolute_file_path]] += 1 - end - - # @private - def num_example_groups_defined_in(file) - @example_group_counts_by_spec_file[file] - end - - # @private - def shared_example_group_registry - @shared_example_group_registry ||= SharedExampleGroup::Registry.new - end - - # @private - def inclusion_filter - @configuration.inclusion_filter - end - - # @private - def exclusion_filter - @configuration.exclusion_filter - end - - # @api private - # - # Get count of examples to be run. - def example_count(groups=example_groups) - FlatMap.flat_map(groups) { |g| g.descendants }. - inject(0) { |a, e| a + e.filtered_examples.size } - end - - # @private - def all_example_groups - FlatMap.flat_map(example_groups) { |g| g.descendants } - end - - # @private - def all_examples - FlatMap.flat_map(all_example_groups) { |g| g.examples } - end - - # @private - # Traverses the tree of each top level group. - # For each it yields the group, then the children, recursively. - # Halts the traversal of a branch of the tree as soon as the passed block returns true. - # Note that siblings groups and their sub-trees will continue to be explored. - # This is intended to make it easy to find the top-most group that satisfies some - # condition. - def traverse_example_group_trees_until(&block) - example_groups.each do |group| - group.traverse_tree_until(&block) - end - end - - # @api private - # - # Find line number of previous declaration. - def preceding_declaration_line(absolute_file_name, filter_line) - line_numbers = descending_declaration_line_numbers_by_file.fetch(absolute_file_name) do - return nil - end - - line_numbers.find { |num| num <= filter_line } - end - - # @private - def reporter - @configuration.reporter - end - - # @private - def source_from_file(path) - unless defined?(@sources_by_path) - RSpec::Support.require_rspec_support 'source' - @sources_by_path = {} - end - - @sources_by_path[path] ||= Support::Source.from_file(path) - end - - # @private - def syntax_highlighter - @syntax_highlighter ||= Formatters::SyntaxHighlighter.new(@configuration) - end - - # @api private - # - # Notify reporter of filters. - def announce_filters - fail_if_config_and_cli_options_invalid - filter_announcements = [] - - announce_inclusion_filter filter_announcements - announce_exclusion_filter filter_announcements - - unless filter_manager.empty? - if filter_announcements.length == 1 - report_filter_message("Run options: #{filter_announcements[0]}") - else - report_filter_message("Run options:\n #{filter_announcements.join("\n ")}") - end - end - - if @configuration.run_all_when_everything_filtered? && example_count.zero? && !@configuration.only_failures? - report_filter_message("#{everything_filtered_message}; ignoring #{inclusion_filter.description}") - filtered_examples.clear - inclusion_filter.clear - end - - return unless example_count.zero? - - example_groups.clear - unless rspec_is_quitting - if filter_manager.empty? - report_filter_message("No examples found.") - elsif exclusion_filter.empty? || inclusion_filter.empty? - report_filter_message(everything_filtered_message) - end - end - end - - # @private - def report_filter_message(message) - reporter.message(message) unless @configuration.silence_filter_announcements? - end - - # @private - def everything_filtered_message - "\nAll examples were filtered out" - end - - # @api private - # - # Add inclusion filters to announcement message. - def announce_inclusion_filter(announcements) - return if inclusion_filter.empty? - - announcements << "include #{inclusion_filter.description}" - end - - # @api private - # - # Add exclusion filters to announcement message. - def announce_exclusion_filter(announcements) - return if exclusion_filter.empty? - - announcements << "exclude #{exclusion_filter.description}" - end - - private - - def descending_declaration_line_numbers_by_file - @descending_declaration_line_numbers_by_file ||= begin - declaration_locations = FlatMap.flat_map(example_groups, &:declaration_locations) - hash_of_arrays = Hash.new { |h, k| h[k] = [] } - - # TODO: change `inject` to `each_with_object` when we drop 1.8.7 support. - line_nums_by_file = declaration_locations.inject(hash_of_arrays) do |hash, (file_name, line_number)| - hash[file_name] << line_number - hash - end - - line_nums_by_file.each_value do |list| - list.sort! - list.reverse! - end - end - end - - def fail_if_config_and_cli_options_invalid - return unless @configuration.only_failures_but_not_configured? - - reporter.abort_with( - "\nTo use `--only-failures`, you must first set " \ - "`config.example_status_persistence_file_path`.", - 1 # exit code - ) - end - - # @private - # Provides a null implementation for initial use by configuration. - module Null - def self.non_example_failure; end - def self.non_example_failure=(_); end - - def self.registered_example_group_files - [] - end - - def self.traverse_example_group_trees_until(&_block) - end - - # :nocov: - def self.example_groups - [] - end - - def self.all_example_groups - [] - end - # :nocov: - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document deleted file mode 100644 index 52a564f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.document +++ /dev/null @@ -1,5 +0,0 @@ -lib/**/*.rb -- -README.md -LICENSE.md -Changelog.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts deleted file mode 100644 index 9555b8e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/.yardopts +++ /dev/null @@ -1,6 +0,0 @@ ---exclude features ---no-private ---markup markdown -- -Changelog.md -LICENSE.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md deleted file mode 100644 index fc7d5f0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/Changelog.md +++ /dev/null @@ -1,1366 +0,0 @@ -### Development -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.4...3-13-maintenance) - -### 3.13.5 / 2025-05-27 -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.4...rspec-expectations-v3.13.5) - -Bug Fixes: - -* Fix links in gemspec to point to the monorepo / homepage. - -### 3.13.4 / 2025-05-01 -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.3...rspec-expectations-v3.13.4) - -Bug Fixes: - -* Prevent `match` from trying to compare strings and arrays using `Array#match`. (Joseph Haig, rspec/rspec#183) - -### 3.13.3 / 2024-09-07 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.2...v3.13.3) - -Bug Fixes: - -* Fix passing a regular expression to the `include` matcher without a count constraint. - (Jon Rowe, rspec/rspec-expectations#1485) - -### 3.13.2 / 2024-08-20 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.1...v3.13.2) - -Bug Fixes: - -* When using null object doubles, prevent typos triggering dynamic matchers. - (Eric Mueller, rspec/rspec-expectations#1455) -* Use `RSpec.warning` for an expectation warning rather than `Kernel.warn`. (Jon Rowe, rspec/rspec-expectations#1472) -* Prevent mismatched use of block and value matchers in compound expectations. (Phil Pirozhkov, rspec/rspec-expectations#1476) -* Raise an error when passing no arguments to the `include` matcher. (Eric Mueller, rspec/rspec-expectations#1479) - -### 3.13.1 / 2024-06-13 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.0...v3.13.1) - -Bug Fixes: - -* Fix the "false positive" warning message when using a negated `raise_error` matcher - with a `RegExp` instance. (Eric Mueller, rspec/rspec-expectations#1456) - -### 3.13.0 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.4...v3.13.0) - -Enhancements: - -* Update `eq` and `eql` matchers to better highlight difference in string encoding. - (Alan Foster, rspec/rspec-expectations#1425) - -### 3.12.4 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.3...v3.12.4) - -Bug Fixes: - -* Fix the diff for redefined `actual` and reassigned `@actual` in compound - expectations failure messages. (Phil Pirozhkov, rspec/rspec-expectations#1440) - -### 3.12.3 / 2023-04-20 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.2...v3.12.3) - -Bug Fixes: - -* Fix `include` matcher when fuzzy matching on keys with a hash-like actual which - has a non standard `key?` method which may raise. - (Jon Rowe, rspec/rspec-expectations#1416) - -### 3.12.2 / 2023-01-07 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.1...v3.12.2) - -Bug Fixes: - -* Prevent deprecation warning when using the `exist` matcher with `Dir`. - (Steve Dierker, rspec/rspec-expectations#1398) - -### 3.12.1 / 2022-12-16 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.0...v3.12.1) - -Bug Fixes: - -* Pass keyword arguments through to aliased (and thus negated) matchers. (Jon Rowe, rspec/rspec-expectations#1394) -* When handling failures in an aggregated_failures block (or example) prevent - the failure list leaking out. (Maciek Rząsa, rspec/rspec-expectations#1392) - -### 3.12.0 / 2022-10-26 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.1...v3.12.0) - -Enhancements: - -* Add `an_array_matching` alias for `match_array` to improve readability as an argument - matcher. (Mark Schneider, rspec/rspec-expectations#1361) - -### 3.11.1 / 2022-09-12 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.0...v3.11.1) - -Bug Fixes: - -* Allow the `contain_exactly` matcher to be reused by resetting its - internals on `matches?` (@bclayman-sq, rspec/rspec-expectations#1326) -* Using the exist matcher on `FileTest` no longer produces a deprecation warning. - (Ryo Nakamura, rspec/rspec-expectations#1383) - -### 3.11.0 / 2022-02-09 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.2...v3.11.0) - -Enhancements: - -* Return `true` from `aggregate_failures` when no exception occurs. (Jon Rowe, rspec/rspec-expectations#1225) - -Deprecations: - -* Print a deprecation message when using the implicit block expectation syntax. - (Phil Pirozhkov, rspec/rspec-expectations#1139) - -### 3.10.2 / 2022-01-14 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.1...v3.10.2) - -Bug Fixes: - -* Fix support for dynamic matchers for expectation target checks (Phil Pirozhkov, rspec/rspec-expectations#1294) -* Fix `expect(array).to include(hash).times`, previously this would fail due to - matching the entire array as a single hash, rather than a member of the hash. - (Slava Kardakov, rspec/rspec-expectations#1322) -* Ensure `raise_error` matches works with the `error_highlight` option from Ruby 3.1. - (Peter Goldstein, rspec/rspec-expectations#1339) - -### 3.10.1 / 2020-12-27 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.0...v3.10.1) - -Bug Fixes: - -* Allow JRuby 9.2.x.x to generate backtraces normally rather than via our - backfill workaround. (rspec/rspec-expectations#1230, Jon Rowe) - -### 3.10.0 / 2020-10-30 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.10.0) - -Enhancements: - -* Allow `include` matcher to be chained with `once`, `at_least`, etc. for simple cases. - (Marc-André Lafortune, rspec/rspec-expectations#1168) -* Add an explicit warning when `nil` is passed to `raise_error`. (Phil Pirozhkov, rspec/rspec-expectations#1143) -* Improve `include` matcher's composability. (Phil Pirozhkov, rspec/rspec-expectations#1155) -* Mocks expectations can now set a custom failure message. - (Benoit Tigeot and Nicolas Zermati, rspec/rspec-expectations#1156) -* `aggregate_failures` now shows the backtrace line for each failure. (Fabricio Bedin, rspec/rspec-expectations#1163) -* Support multiple combinations of `yield_control` modifiers like `at_least`, `at_most`. - (Jon Rowe, rspec/rspec-expectations#1169) -* Dynamic `have_` matchers now have output consistent with other dynamic matchers. - (Marc-André Lafortune, rspec/rspec-expectations#1195) -* New config option `strict_predicate_matchers` allows predicate matcher to be strict - (i.e. match for `true` or `false`) instead of the default (match truthy vs `false` or `nil`). - (Marc-André Lafortune, rspec/rspec-expectations#1196) - -### 3.9.4 / 2020-10-29 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.9.4) - -Bug Fixes: - -* Fix regression with `be_` and `have_` matchers and arguments implementing `to_hash` - were they would act like keywords and be cast to a hash. (Jon Rowe, rspec/rspec-expectations#1222) - -### 3.9.3 / 2020-10-23 - -Bug Fixes: - -* Swap the comparison of the delta vs the expected for the `be_within` matcher allowing - more complicated oobjects to be compared providing they provide `abs` and other - comparison methods. (Kelly Stannard, rspec/rspec-expectations#1182) -* Properly format expected in the description of the `be_within` matcher. (Jon Rowe, rspec/rspec-expectations#1185) -* Remove warning when using keyword arguments with `be_` and `have_` matchers on 2.7.x - (Jon Rowe, rspec/rspec-expectations#1187) -* Prevent formatting a single hash as a list of key value pairs in default failure messages - for custom matches (fixes formatting in `EnglishPhrasing#list`). (Robert Eshleman, rspec/rspec-expectations#1193) -* Prevent errors from causing false positives when using `be ` comparison, e.g. - `expect(1).not_to be < 'a'` will now correctly fail rather than pass. (Jon Rowe, rspec/rspec-expectations#1208) - - -### 3.9.2 / 2020-05-08 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.1...v3.9.2) - -Bug Fixes: - -* Issue a proper `ArgumentError` when invalid arguments are given to `yield_control` - modifiers such as `at_least` et al. (Marc-André Lafortune, rspec/rspec-expectations#1167) -* Prevent Ruby 2.7 keyword arguments warning from being issued by custom - matcher definitions. (Jon Rowe, rspec/rspec-expectations#1176) - -### 3.9.1 / 2020-03-13 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.0...v3.9.1) - -Bug Fixes: - -* Issue an improved warning when using `respond_to(...).with(n).arguments` and ignore - the warning when using with `have_attributes(...)`. (Jon Rowe, rspec/rspec-expectations#1164) - -### 3.9.0 / 2019-10-08 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.6...v3.9.0) - -Enhancements: - -* The `respond_to` matcher now uses the signature from `initialize` to validate checks - for `new` (unless `new` is non standard). (Jon Rowe, rspec/rspec-expectations#1072) -* Generated descriptions for matchers now use `is expected to` rather than `should` in - line with our preferred DSL. (Pete Johns, rspec/rspec-expectations#1080, rspec/rspec-corerspec/rspec-expectations#2572) -* Add the ability to re-raise expectation errors when matching - with `match_when_negated` blocks. (Jon Rowe, rspec/rspec-expectations#1130) -* Add a warning when an empty diff is produce due to identical inspect output. - (Benoit Tigeot, rspec/rspec-expectations#1126) - -### 3.8.6 / 2019-10-07 - -Bug Fixes: - -* Revert rspec/rspec-expectations#1125 due to the change being incompatible with our semantic versioning - policy. - -### 3.8.5 / 2019-10-02 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.4...v3.8.5) - -Bug Fixes: - -* Prevent unsupported implicit block expectation syntax from being used. - (Phil Pirozhkov, rspec/rspec-expectations#1125) - -### 3.8.4 / 2019-06-10 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.3...v3.8.4) - -Bug Fixes: - -* Prevent false negatives when checking objects for the methods required to run the - the `be_an_instance_of` and `be_kind_of` matchers. (Nazar Matus, rspec/rspec-expectations#1112) - -### 3.8.3 / 2019-04-20 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.2...v3.8.3) - -Bug Fixes: - -* Prevent composed `all` matchers from leaking into their siblings leading to duplicate - failures. (Jamie English, rspec/rspec-expectations#1086) -* Prevent objects which change their hash on comparison from failing change checks. - (Phil Pirozhkov, rspec/rspec-expectations#1100) -* Issue an `ArgumentError` rather than a `NoMethodError` when `be_an_instance_of` and - `be_kind_of` matchers encounter objects not supporting those methods. - (Taichi Ishitani, rspec/rspec-expectations#1107) - -### 3.8.2 / 2018-10-09 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.1...v3.8.2) - -Bug Fixes: - -* Change `include` matcher to rely on a `respond_to?(:include?)` check rather than a direct - Hash comparison before calling `to_hash` to convert to a hash. (Jordan Owens, rspec/rspec-expectations#1073) -* Prevent unexpected call stack jumps from causing an obscure error (`IndexError`), and - replace that error with a proper informative message. (Jon Rowe, rspec/rspec-expectations#1076) - -### 3.8.1 / 2018-08-06 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.0...v3.8.1) - -Bug Fixes: - -* Fix regression in `include` matcher so stopped - `expect(hash.with_indifferent_access).to include(:symbol_key)` - from working. (Eito Katagiri, rspec/rspec-expectations#1069) - -### 3.8.0 / 2018-08-04 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.7.0...v3.8.0) - -Enhancements: - -* Improve failure message of `change(receiver, :message)` by including the - receiver as `SomeClass#some_message`. (Tomohiro Hashidate, rspec/rspec-expectations#1005) -* Improve `change` matcher so that it can correctly detect changes in - deeply nested mutable objects (such as arrays-of-hashes-of-arrays). - The improved logic uses the before/after `hash` value to see if the - object has been mutated, rather than shallow duping the object. - (Myron Marston, rspec/rspec-expectations#1034) -* Improve `include` matcher so that pseudo-hash objects (e.g. objects - that decorate a hash using a `SimpleDelegator` or similar) are treated - as a hash, as long as they implement `to_hash`. (Pablo Brasero, rspec/rspec-expectations#1012) -* Add `max_formatted_output_length=` to configuration, allowing changing - the length at which we truncate large output strings. - (Sam Phippen rspec/rspec-expectations#951, Benoit Tigeot rspec/rspec-expectations#1056) -* Improve error message when passing a matcher that doesn't support block - expectations to a block based `expect`. (@nicktime, rspec/rspec-expectations#1066) - -### 3.7.0 / 2017-10-17 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0...v3.7.0) - -Enhancements: - -* Improve compatibility with `--enable-frozen-string-literal` option - on Ruby 2.3+. (Pat Allan, rspec/rspec-expectations#997) - -### 3.6.0 / 2017-05-04 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0.beta2...v3.6.0) - -Enhancements: - -* Treat NoMethodError as a failure for comparison matchers. (Jon Rowe, rspec/rspec-expectations#972) -* Allow for scoped aliased and negated matchers--just call - `alias_matcher` or `define_negated_matcher` from within an example - group. (Markus Reiter, rspec/rspec-expectations#974) -* Improve failure message of `change` matcher with block and `satisfy` matcher - by including the block snippet instead of just describing it as `result` or - `block` when Ripper is available. (Yuji Nakayama, rspec/rspec-expectations#987) - -Bug Fixes: - -* Fix `yield_with_args` and `yield_successive_args` matchers so that - they compare expected to actual args at the time the args are yielded - instead of at the end, in case the method that is yielding mutates the - arguments after yielding. (Alyssa Ross, rspec/rspec-expectations#965) - -### 3.6.0.beta2 / 2016-12-12 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0.beta1...v3.6.0.beta2) - -Bug Fixes: - -* Using the exist matcher on `File` no longer produces a deprecation warning. - (Jon Rowe, rspec/rspec-expectations#954) - -### 3.6.0.beta1 / 2016-10-09 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0...v3.6.0.beta1) - -Bug Fixes: - -* Fix `contain_exactly` to work correctly with ranges. (Myron Marston, rspec/rspec-expectations#940) -* Fix `change` to work correctly with sets. (Marcin Gajewski, rspec/rspec-expectations#939) - -### 3.5.0 / 2016-07-01 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta4...v3.5.0) - -Enhancements: - -* Add support for keyword arguments to the `respond_to` matcher. (Rob Smith, rspec/rspec-expectations#915). - -### 3.5.0.beta4 / 2016-06-05 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta3...v3.5.0.beta4) - -Bug Fixes: - -* Fix `include` matcher so that it provides a valid diff for hashes. (Yuji Nakayama, rspec/rspec-expectations#916) - -### 3.5.0.beta3 / 2016-04-02 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta2...v3.5.0.beta3) - -Enhancements: - -* Make `rspec/expectations/minitest_integration` work on Minitest::Spec - 5.6+. (Myron Marston, rspec/rspec-expectations#904) -* Add an alias `having_attributes` for `have_attributes` matcher. - (Yuji Nakayama, rspec/rspec-expectations#905) -* Improve `change` matcher error message when block is mis-used. - (Alex Altair, rspec/rspec-expectations#908) - -### 3.5.0.beta2 / 2016-03-10 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta1...v3.5.0.beta2) - -Enhancements: - -* Add the ability to raise an error on encountering false positives via - `RSpec::Configuration#on_potential_false_positives = :raise`. (Jon Rowe, rspec/rspec-expectations#900) -* When using the custom matcher DSL, support new - `notify_expectation_failures: true` option for the `match` method to - allow expectation failures to be raised as normal instead of being - converted into a `false` return value for `matches?`. (Jon Rowe, rspec/rspec-expectations#892) - -Bug Fixes: - -* Allow `should` deprecation check to work on `BasicObject`s. (James Coleman, rspec/rspec-expectations#898) - -### 3.5.0.beta1 / 2016-02-06 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.4.0...v3.5.0.beta1) - -Enhancements: - -* Make `match_when_negated` in custom matcher DSL support use of - expectations within the match logic. (Chris Arcand, rspec/rspec-expectations#789) - -Bug Fixes: - -* Return `true` as expected from passing negated expectations - (such as `expect("foo").not_to eq "bar"`), so they work - properly when used within a `match` or `match_when_negated` - block. (Chris Arcand, rspec/rspec-expectations#789) - -### 3.4.0 / 2015-11-11 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.3.1...v3.4.0) - -Enhancements: - -* Warn when `RSpec::Matchers` is included in a superclass after it has - already been included in a subclass on MRI 1.9, since that situation - can cause uses of `super` to trigger infinite recursion. (Myron Marston, rspec/rspec-expectations#816) -* Stop rescuing `NoMemoryError`, `SignalExcepetion`, `Interrupt` and - `SystemExit`. It is dangerous to interfere with these. (Myron Marston, rspec/rspec-expectations#845) -* Add `#with_captures` to the match matcher which allows a user to specify expected - captures when matching a regex against a string. (Sam Phippen, rspec/rspec-expectations#848) -* Always print compound failure messages in the multi-line form. Trying - to print it all on a single line didn't read very well. (Myron Marston, rspec/rspec-expectations#859) - -Bug Fixes: - -* Fix failure message from dynamic predicate matchers when the object - does not respond to the predicate so that it is inspected rather - than relying upon its `to_s` -- that way for `nil`, `"nil"` is - printed rather than an empty string. (Myron Marston, rspec/rspec-expectations#841) -* Fix SystemStackError raised when diffing an Enumerable object - whose `#each` includes the object itself. (Yuji Nakayama, rspec/rspec-expectations#857) - -### 3.3.1 / 2015-07-15 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.3.0...v3.3.1) - -Bug Fixes: - -* Fix `be >`, `be <`, etc so that it fails rather than allowing an - argument error to be raised when compared against an object of the - wrong type. This allows it to be used in composed matcher expressions - against heterogeneous objects. (Dennis Günnewig, rspec/rspec-expectations#809) -* Fix `respond_to` to work properly on target objects - that redefine the `method` method. (unmanbearpig, rspec/rspec-expectations#821) - -### 3.3.0 / 2015-06-12 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.2.1...v3.3.0) - -Enhancements: - -* Expose `RSpec::Matchers::EnglishPhrasing` to make it easier to write - nice failure messages in custom matchers. (Jared Beck, rspec/rspec-expectations#736) -* Add `RSpec::Matchers::FailMatchers`, a mixin which provides - `fail`, `fail_with` and `fail_including` matchers for use in - specifying that an expectation fails for use by - extension/plugin authors. (Charlie Rudolph, rspec/rspec-expectations#729) -* Avoid loading `tempfile` (and its dependencies) unless - it is absolutely needed. (Myron Marston, rspec/rspec-expectations#735) -* Improve failure output when attempting to use `be_true` or `be_false`. - (Tim Wade, rspec/rspec-expectations#744) -* Define `RSpec::Matchers#respond_to_missing?` so that - `RSpec::Matchers#respond_to?` and `RSpec::Matchers#method` handle - dynamic predicate matchers. (Andrei Botalov, rspec/rspec-expectations#751) -* Use custom Time/DateTime/BigDecimal formatting for all matchers - so they are consistently represented in failure messages. - (Gavin Miller, rspec/rspec-expectations#740) -* Add configuration to turn off warnings about matcher combinations that - may cause false positives. (Jon Rowe, rspec/rspec-expectations#768) -* Warn when using a bare `raise_error` matcher that you may be subject to - false positives. (Jon Rowe, rspec/rspec-expectations#768) -* Warn rather than raise when using the`raise_error` matcher in negative - expectations that may be subject to false positives. (Jon Rowe, rspec/rspec-expectations#775) -* Improve failure message for `include(a, b, c)` so that if `a` and `b` - are included the failure message only mentions `c`. (Chris Arcand, rspec/rspec-expectations#780) -* Allow `satisfy` matcher to take an optional description argument - that will be used in the `description`, `failure_message` and - `failure_message_when_negated` in place of the undescriptive - "sastify block". (Chris Arcand, rspec/rspec-expectations#783) -* Add new `aggregate_failures` API that allows multiple independent - expectations to all fail and be listed in the failure output, rather - than the example aborting on the first failure. (Myron Marston, rspec/rspec-expectations#776) -* Improve `raise_error` matcher so that it can accept a matcher as a single argument - that matches the message. (Time Wade, rspec/rspec-expectations#782) - -Bug Fixes: - -* Make `contain_exactly` / `match_array` work with strict test doubles - that have not defined `<=>`. (Myron Marston, rspec/rspec-expectations#758) -* Fix `include` matcher so that it omits the diff when it would - confusingly highlight items that are actually included but are not - an exact match in a line-by-line diff. (Tim Wade, rspec/rspec-expectations#763) -* Fix `match` matcher so that it does not blow up when matching a string - or regex against another matcher (rather than a string or regex). - (Myron Marston, rspec/rspec-expectations#772) -* Silence whitespace-only diffs. (Myron Marston, rspec/rspec-expectations#801) - -### 3.2.1 / 2015-04-06 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.2.0...v3.2.1) - -Bug Fixes: - -* Prevent `Range`s from being enumerated when generating matcher - descriptions. (Jon Rowe, rspec/rspec-expectations#755) -* Ensure exception messages are compared as strings in the `raise_error` - matcher. (Jon Rowe, rspec/rspec-expectations#755) - -### 3.2.0 / 2015-02-03 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.2...v3.2.0) - -Enhancements: - -* Add `block_arg` method to custom matcher API, which allows you to - access the block passed to a custom matcher, if there is one. - (Mike Dalton, rspec/rspec-expectations#645) -* Provide more detail in failure message of `yield_control` matcher. - (Jon Rowe, rspec/rspec-expectations#650) -* Add a shorthand syntax for `chain` in the matcher DSL which assigns values - for use elsewhere, for example `chain :and_smaller_than, :small_value` - creates an `attr_reader` for `small_value` (Tom Stuart, rspec/rspec-expectations#644) -* Provide a more helpful deprecation message when using the `should` syntax. - (Elia Schito, rspec/rspec-expectations#663) -* Provide more detail in the `have_attributes` matcher failure message. - (Jon Rowe, rspec/rspec-expectations#668) -* Make the `have_attributes` matcher diffable. - (Jon Rowe, Alexey Fedorov, rspec/rspec-expectations#668) -* Add `output(...).to_std(out|err)_from_any_process` as alternatives - to `output(...).to_std(out|err)`. The latter doesn't work when a sub - process writes to the named stream but is much faster. - (Alex Genco, rspec/rspec-expectations#700) -* Improve compound matchers (created by `and` and `or`) so that diffs - are included in failures when one or more of their matchers - are diffable. (Alexey Fedorov, rspec/rspec-expectations#713) - -Bug Fixes: - -* Avoid calling `private_methods` from the `be` predicate matcher on - the target object if the object publicly responds to the predicate - method. This avoids a possible error that can occur if the object - raises errors from `private_methods` (which can happen with celluloid - objects). (@chapmajs, rspec/rspec-expectations#670) -* Make `yield_control` (with no modifier) default to - `at_least(:once)` rather than raising a confusing error - when multiple yields are encountered. - (Myron Marston, rspec/rspec-expectations#675) -* Fix "instance variable @color not initialized" warning when using - rspec-expectations outside of an rspec-core context. (Myron Marston, rspec/rspec-expectations#689) -* Fix `start_with` and `end_with` to work properly when checking a - string against an array of strings. (Myron Marston, rspec/rspec-expectations#690) -* Don't use internally delegated matchers when generating descriptions - for examples without doc strings. (Myron Marston, rspec/rspec-expectations#692) - -### 3.1.2 / 2014-09-26 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.1...v3.1.2) - -Bug Fixes: - -* Fix `define_negated_matcher` so that matchers that support fluent - interfaces continue to be negated after you use the chained method. - (Myron Marston, rspec/rspec-expectations#656) -* Fix `define_negated_matcher` so that the matchers fail with an - appropriate failure message. (Myron Marston, rspec/rspec-expectations#659) - -### 3.1.1 / 2014-09-15 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.0...v3.1.1) - -Bug Fixes: - -* Fix regression in `all` matcher in 3.1.0 that prevented it from - working on objects that are not `Enumerable` but do implement - `each_with_index` (such as an ActiveRecord proxy). (Jori Hardman, rspec/rspec-expectations#647) - -### 3.1.0 / 2014-09-04 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.4...v3.1.0) - -Enhancements: - -* Add `have_attributes` matcher, that passes if actual's attribute - values match the expected attributes hash: - `Person = Struct.new(:name, :age)` - `person = Person.new("Bob", 32)` - `expect(person).to have_attributes(:name => "Bob", :age => 32)`. - (Adam Farhi, rspec/rspec-expectations#571) -* Extended compound matcher support to block matchers, for cases like: - `expect { ... }.to change { x }.to(3).and change { y }.to(4)`. (Myron - Marston, rspec/rspec-expectations#567) -* Include chained methods in custom matcher description and failure message - when new `include_chain_clauses_in_custom_matcher_descriptions` config - option is enabled. (Dan Oved, rspec/rspec-expectations#600) -* Add `thrice` modifier to `yield_control` matcher as a synonym for - `exactly(3).times`. (Dennis Taylor, rspec/rspec-expectations#615) -* Add `RSpec::Matchers.define_negated_matcher`, which defines a negated - version of the named matcher. (Adam Farhi, Myron Marston, rspec/rspec-expectations#618) -* Document and support negation of `contain_exactly`/`match_array`. - (Jon Rowe, rspec/rspec-expectations#626). - -Bug Fixes: - -* Rename private `LegacyMacherAdapter` constant to `LegacyMatcherAdapter` - to fix typo. (Abdelkader Boudih, rspec/rspec-expectations#563) -* Fix `all` matcher so that it fails properly (rather than raising a - `NoMethodError`) when matched against a non-enumerable. (Hao Su, rspec/rspec-expectations#622) - -### 3.0.4 / 2014-08-14 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.3...v3.0.4) - -Bug Fixes: - -* Fix `start_with` and `end_with` so that they work properly with - structs. (Myron Marston, rspec/rspec-expectations#620) -* Fix failure message generation so that structs are printed properly - in failures. Previously failure messages would represent them as - an array. (Myron Marston, rspec/rspec-expectations#620) -* Fix composable matcher support so that it does not wrongly treat - structs as arrays. (Myron Marston, rspec/rspec-expectations#620) - -### 3.0.3 / 2014-07-21 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.2...v3.0.3) - -Bug Fixes: - -* Fix issue with detection of generic operator matchers so they work - correctly when undefined. (Myron Marston, rspec/rspec-expectations#597) -* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, rspec/rspec-expectations#603) -* Fix `include` matcher so that it fails gracefully when matched against - an object that does not respond to `include?`. (Myron Marston, rspec/rspec-expectations#607) - -### 3.0.2 / 2014-06-19 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.1...v3.0.2) - -Bug Fixes: - -* Fix regression in `contain_exactly` (AKA `match_array`) that caused it - to wrongly pass when the expected array was empty. (Myron Marston, rspec/rspec-expectations#581) -* Provide a better error message when you use the `change(obj, :msg)` - form of the change matcher but forget the message argument. (Alex - Sunderland, rspec/rspec-expectations#585) -* Make the `contain_exactly` matcher work with arrays that contain hashes in - arbitrary ordering. (Sam Phippen, rspec/rspec-expectations#578) - -### 3.0.1 / 2014-06-12 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0...v3.0.1) - -Bug Fixes: - -* Add a missing `require` that would cause the `respond_to` matcher to - fail when used in a project where the rest of RSpec (e.g. core and - expecatations) weren't being used. (Myron Marston, rspec/rspec-expectations#566) -* Structs are no longer treated as arrays when diffed. (Jon Rowe, rspec/rspec-expectations#576) - -### 3.0.0 / 2014-06-01 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.rc1...v3.0.0) - -No code changes. Just taking it out of pre-release. - -### 3.0.0.rc1 / 2014-05-18 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta2...v3.0.0.rc1) - -Breaking Changes for 3.0.0: - -* Remove `matcher_execution_context` attribute from DSL-defined - custom matchers. (Myron Marston) -* Remove `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston) -* Remove `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston) -* Rename `RSpec::Matchers::Configuration` constant to - `RSpec::Expectations::Configuration`. (Myron Marston) -* Prevent `have_xyz` predicate matchers using private methods. - (Adrian Gonzalez) -* Block matchers must now implement `supports_block_expectations?`. - (Myron Marston) -* Stop supporting `require 'rspec-expectations'`. - Use `require 'rspec/expectations'` instead. (Myron Marston) - -Bug Fixes: - -* Fix `NoMethodError` triggered by beta2 when `YARD` was loaded in - the test environment. (Myron Marston) -* Fix `be_xyz` matcher to accept a `do...end` block. (Myron Marston) -* Fix composable matcher failure message generation logic - so that it does not blow up when given `$stdout` or `$stderr`. - (Myron Marston) -* Fix `change` matcher to work properly with `IO` objects. - (Myron Marston) -* Fix `exist` matcher so that it can be used in composed matcher - expressions involving objects that do not implement `exist?` or - `exists?`. (Daniel Fone) -* Fix composable matcher match logic so that it clones matchers - before using them in order to work properly with matchers - that use internal memoization based on a given `actual` value. - (Myron Marston) -* Fix `be_xyz` and `has_xyz` predicate matchers so that they can - be used in composed matcher expressions involving objects that - do not implement the predicate method. (Daniel Fone) - -Enhancements: - -* Document the remaining public APIs. rspec-expectations now has 100% of - the public API documented and will remain that way (as new undocumented - methods will fail the build). (Myron Marston) -* Improve the formatting of BigDecimal objects in `eq` matcher failure - messages. (Daniel Fone) -* Improve the failure message for `be_xyz` predicate matchers so - that it includes the `inspect` output of the receiver. - (Erik Michaels-Ober, Sam Phippen) -* Add `all` matcher, to allow you to specify that a given matcher - matches all elements in a collection: - `expect([1, 3, 5]).to all( be_odd )`. (Adam Farhi) -* Add boolean aliases (`&`/`|`) for compound operators (`and`/`or`). (Adam Farhi) -* Give users a clear error when they wrongly use a value matcher - in a block expectation expression (e.g. `expect { 3 }.to eq(3)`) - or vice versa. (Myron Marston) - -### 3.0.0.beta2 / 2014-02-17 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta1...v3.0.0.beta2) - -Breaking Changes for 3.0.0: - -* Remove deprecated support for accessing the `RSpec` constant using - `Rspec` or `Spec`. (Myron Marston) -* Remove deprecated `RSpec::Expectations.differ=`. (Myron Marston) -* Remove support for deprecated `expect(...).should`. (Myron Marston) -* Explicitly disallow `expect { }.not_to change { }` with `by`, - `by_at_least`, `by_at_most` or `to`. These have never been supported - but did not raise explicit errors. (Myron Marston) -* Provide `===` rather than `==` as an alias of `matches?` for - all matchers. The semantics of `===` are closer to an RSpec - matcher than `==`. (Myron Marston) -* Remove deprecated `RSpec::Matchers::OperatorMatcher` constant. - (Myron Marston) -* Make `RSpec::Expectations::ExpectationNotMetError` subclass - `Exception` rather than `StandardError` so they can bypass - a bare `rescue` in end-user code (e.g. when an expectation is - set from within a rspec-mocks stub implementation). (Myron Marston) -* Remove Test::Unit and Minitest 4.x integration. (Myron Marston) - -Enhancements: - -* Simplify the failure message of the `be` matcher when matching against: - `true`, `false` and `nil`. (Sam Phippen) -* Update matcher protocol and custom matcher DSL to better align - with the newer `expect` syntax. If you want your matchers to - maintain compatibility with multiple versions of RSpec, you can - alias the new names to the old. (Myron Marston) - * `failure_message_for_should` => `failure_message` - * `failure_message_for_should_not` => `failure_message_when_negated` - * `match_for_should` => `match` - * `match_for_should_not` => `match_when_negated` -* Improve generated descriptions from `change` matcher. (Myron Marston) -* Add support for compound matcher expressions using `and` and `or`. - Simply chain them off of any existing matcher to create an expression - like `expect(alphabet).to start_with("a").and end_with("z")`. - (Eloy Espinaco) -* Add `contain_exactly` as a less ambiguous version of `match_array`. - Note that it expects the expected array to be splatted as - individual args: `expect(array).to contain_exactly(1, 2)` is - the same as `expect(array).to match_array([1, 2])`. (Myron Marston) -* Update `contain_exactly`/`match_array` so that it can match against - other non-array collections (such as a `Set`). (Myron Marston) -* Update built-in matchers so that they can accept matchers as arguments - to allow you to compose matchers in arbitrary ways. (Myron Marston) -* Add `RSpec::Matchers::Composable` mixin that can be used to make - a custom matcher composable as well. Note that custom matchers - defined via `RSpec::Matchers.define` already have this. (Myron - Marston) -* Define noun-phrase aliases for built-in matchers, which can be - used when creating composed matcher expressions that read better - and provide better failure messages. (Myron Marston) -* Add `RSpec::Matchers.alias_matcher` so users can define their own - matcher aliases. The `description` of the matcher will reflect the - alternate matcher name. (Myron Marston) -* Add explicit `be_between` matcher. `be_between` has worked for a - long time as a dynamic predicate matcher, but the failure message - was suboptimal. The new matcher provides a much better failure - message. (Erik Michaels-Ober) -* Enhance the `be_between` matcher to allow for `inclusive` or `exclusive` - comparison (e.g. inclusive of min/max or exclusive of min/max). - (Pedro Gimenez) -* Make failure message for `not_to be #{operator}` less confusing by - only saying it's confusing when comparison operators are used. - (Prathamesh Sonpatki) -* Improve failure message of `eq` matcher when `Time` or `DateTime` - objects are used so that the full sub-second precision is included. - (Thomas Holmes, Jeff Wallace) -* Add `output` matcher for expecting that a block outputs `to_stdout` - or `to_stderr`. (Luca Pette, Matthias Günther) -* Forward a provided block on to the `has_xyz?` method call when - the `have_xyz` matcher is used. (Damian Galarza) -* Provide integration with Minitest 5.x. Require - `rspec/expectations/minitest_integration` after loading minitest - to use rspec-expectations with minitest. (Myron Marston) - -Bug Fixes: - -* Fix wrong matcher descriptions with falsey expected value (yujinakayama) -* Fix `expect { }.not_to change { }.from(x)` so that the matcher only - passes if the starting value is `x`. (Tyler Rick, Myron Marston) -* Fix hash diffing, so that it colorizes properly and doesn't consider trailing - commas when performing the diff. (Jared Norman) -* Fix built-in matchers to fail normally rather than raising - `ArgumentError` when given an object of the wrong type to match - against, so that they work well in composite matcher expressions like - `expect([1.51, "foo"]).to include(a_string_matching(/foo/), a_value_within(0.1).of(1.5))`. - (Myron Marston) - -Deprecations: - -* Retain support for RSpec 2 matcher protocol (e.g. for matchers - in 3rd party extension gems like `shoulda`), but it will print - a deprecation warning. (Myron Marston) - -### 3.0.0.beta1 / 2013-11-07 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.2...v3.0.0.beta1) - -Breaking Changes for 3.0.0: - -* Remove explicit support for 1.8.6. (Jon Rowe) -* Remove the deprecated `be_close` matcher, preferring `be_within` instead. - (Sam Phippen) -* Remove the deprecated `have`, `have_at_least` and `have_at_most` matchers. - You can continue using those matchers through https://github.com/rspec/rspec-collection_matchers, - or you can rewrite your expectations with something like - `expect(your_object.size).to eq(num)`. (Hugo Baraúna) -* Rename `be_true` and `be_false` to `be_truthy` and `be_falsey`. (Sam Phippen) -* Make `expect { }.to_not raise_error(SomeSpecificClass, message)`, - `expect { }.to_not raise_error(SomeSpecificClass)` and - `expect { }.to_not raise_error(message)` invalid, since they are prone - to hiding failures. Instead, use `expect { }.to_not raise_error` (with no - args). (Sam Phippen) -* Within `RSpec::Matchers.define` blocks, helper methods made available - either via `def self.helper` or `extend HelperModule` are no longer - available to the `match` block (or any of the others). Instead - `include` your helper module and define the helper method as an - instance method. (Myron Marston) -* Force upgrading Diff::LCS for encoding compatability with diffs. (Jon Rowe) - -Enhancements: - -* Support `do..end` style block with `raise_error` matcher. (Yuji Nakayama) -* Rewrote custom matcher DSL to simplify its implementation and solve a - few issues. (Myron Marston) -* Allow early `return` from within custom matcher DSL blocks. (Myron - Marston) -* The custom matcher DSL's `chain` can now accept a block. (Myron - Marston) -* Support setting an expectation on a `raise_error` matcher via a chained - `with_message` method call. (Sam Phippen) - -Bug Fixes: - -* Allow `include` and `match` matchers to be used from within a - DSL-defined custom matcher's `match` block. (Myron Marston) -* Correct encoding error message on diff failure (Jon Rowe) - -Deprecations: - - * Using the old `:should` syntax without explicitly configuring it is deprecated. - It will continue to work but will emit a deprecation warning in RSpec 3 if - you do not explicitly enable it. (Sam Phippen) - -### 2.99.2 / 2014-07-21 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.1...v2.99.2) - -Bug Fixes: - -* Fix regression in `Expectations#method_handle_for` where proxy objects - with method delegated would wrongly not return a method handle. - (Jon Rowe, rspec/rspec-expectations#594) -* Fix issue with detection of generic operator matchers so they work - correctly when undefined. (Myron Marston, rspec/rspec-expectations#597) - -### 2.99.1 / 2014-06-19 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0...v2.99.1) - -Bug Fixes: - -* Fix typo in custom matcher `expected` deprecation warning -- it's - `expected_as_array`, not `expected_array`. (Frederick Cheung, rspec/rspec-expectations#562) - -### 2.99.0 / 2014-06-01 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.rc1...v2.99.0) - -Enhancements: - -* Special case deprecation message for `errors_on` with `rspec-rails` to be more useful. - (Aaron Kromer) - -### 2.99.0.rc1 / 2014-05-18 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta2...2.99.0.rc1) - -Deprecations: - -* Deprecate `matcher_execution_context` attribute on DSL-defined - custom matchers. (Myron Marston) -* Deprecate `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston) -* Deprecate `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston) -* Deprecate `RSpec::Matchers::Configuration` in favor of - `RSpec::Expectations::Configuration`. (Myron Marston) -* Deprecate `be_xyz` predicate matcher on an object that doesn't respond to - `xyz?` or `xyzs?`. (Daniel Fone) -* Deprecate `have_xyz` matcher on an object that doesn't respond to `has_xyz?`. - (Daniel Fone) -* Deprecate `have_xyz` matcher on an object that has a private method `has_xyz?`. - (Jon Rowe) -* Issue a deprecation warning when a block expectation expression is - used with a matcher that doesn't explicitly support block expectations - via `supports_block_expectations?`. (Myron Marston) -* Deprecate `require 'rspec-expectations'`. Use - `require 'rspec/expectations'` instead. (Myron Marston) - -### 2.99.0.beta2 / 2014-02-17 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta1...v2.99.0.beta2) - -Deprecations: - -* Deprecate chaining `by`, `by_at_least`, `by_at_most` or `to` off of - `expect { }.not_to change { }`. The docs have always said these are - not supported for the negative form but now they explicitly raise - errors in RSpec 3. (Myron Marston) -* Change the semantics of `expect { }.not_to change { x }.from(y)`. - In RSpec 2.x, this expectation would only fail if `x` started with - the value of `y` and changed. If it started with a different value - and changed, it would pass. In RSpec 3, it will pass only if the - value starts at `y` and it does not change. (Myron Marston) -* Deprecate `matcher == value` as an alias for `matcher.matches?(value)`, - in favor of `matcher === value`. (Myron Marston) -* Deprecate `RSpec::Matchers::OperatorMatcher` in favor of - `RSpec::Matchers::BuiltIn::OperatorMatcher`. (Myron Marston) -* Deprecate auto-integration with Test::Unit and minitest. - Instead, include `RSpec::Matchers` in the appropriate test case - base class yourself. (Myron Marston) -* Deprecate treating `#expected` on a DSL-generated custom matcher - as an array when only 1 argument is passed to the matcher method. - In RSpec 3 it will be the single value in order to make diffs - work properly. (Jon Rowe) - -### 2.99.0.beta1 / 2013-11-07 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.99.0.beta1) - -Deprecations - -* Deprecate `have`, `have_at_least` and `have_at_most`. You can continue using those - matchers through https://github.com/rspec/rspec-collection_matchers, or - you can rewrite your expectations with something like - `expect(your_object.size).to eq(num)`. (Hugo Baraúna) -* Deprecate `be_xyz` predicate matcher when `xyz?` is a private method. - (Jon Rowe) -* Deprecate `be_true`/`be_false` in favour of `be_truthy`/`be_falsey` - (for Ruby's conditional semantics) or `be true`/`be false` - (for exact equality). (Sam Phippen) -* Deprecate calling helper methods from a custom matcher with the wrong - scope. (Myron Marston) - * `def self.foo` / `extend Helper` can be used to add macro methods - (e.g. methods that call the custom matcher DSL methods), but should - not be used to define helper methods called from within the DSL - blocks. - * `def foo` / `include Helper` is the opposite: it's for helper methods - callable from within a DSL block, but not for defining macros. - * RSpec 2.x allowed helper methods defined either way to be used for - either purpose, but RSpec 3.0 will not. - -### 2.14.5 / 2014-02-01 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.14.5) - -Bug fixes - -* Fix wrong matcher descriptions with falsey expected value - (yujinakayama) - -### 2.14.4 / 2013-11-06 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.3...v2.14.4) - -Bug fixes - -* Make the `match` matcher produce a diff output. (Jon Rowe, Ben Moss) -* Choose encoding for diff's more intelligently, and when all else fails fall - back to default internal encoding with replacing characters. (Jon Rowe) - -### 2.14.3 / 2013-09-22 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.2...v2.14.3) - -Bug fixes - -* Fix operator matchers (`should` syntax) when `method` is redefined on target. - (Brandon Turner) -* Fix diffing of hashes with object based keys. (Jon Rowe) -* Fix operator matchers (`should` syntax) when operator is defined via - `method_missing` (Jon Rowe) - -### 2.14.2 / 2013-08-14 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.1...v2.14.2) - -Bug fixes - -* Fix `be_` matcher to not support operator chaining like the - `be` matcher does (e.g. `be == 5`). This led to some odd behaviors - since `be_ == anything` returned a `BeComparedTo` matcher - and was thus always truthy. This was a consequence of the implementation - (e.g. subclassing the basic `Be` matcher) and was not intended behavior. - (Myron Marston). -* Fix `change` matcher to compare using `==` in addition to `===`. This - is important for an expression like: - `expect {}.to change { a.class }.from(ClassA).to(ClassB)` because - `SomeClass === SomeClass` returns false. (Myron Marston) - -### 2.14.1 / 2013-08-08 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0...2.14.1) - -Bug fixes - -* Ensure diff output uses the same encoding as the encoding of - the string being diff'd to prevent `Encoding::UndefinedConversionError` - errors (Jon Rowe). - -### 2.14.0 / 2013-07-06 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0.rc1...v2.14.0) - -Bug fixes - -* Values that are not matchers use `#inspect`, rather than `#description` for - documentation output (Andy Lindeman, Sam Phippen). -* Make `expect(a).to be_within(x).percent_of(y)` work with negative y - (Katsuhiko Nishimra). -* Make the `be_predicate` matcher work as expected used with `expect{...}.to - change...` (Sam Phippen). - -### 2.14.0.rc1 / 2013-05-27 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.13.0...v2.14.0.rc1) - -Enhancements - -* Enhance `yield_control` so that you can specify an exact or relative - number of times: `expect { }.to yield_control.exactly(3).times`, - `expect { }.to yield_control.at_least(2).times`, etc (Bartek - Borkowski). -* Make the differ that is used when an expectation fails better handle arrays - by splitting each element of the array onto its own line. (Sam Phippen) -* Accept duck-typed strings that respond to `:to_str` as expectation messages. - (Toby Ovod-Everett) - -Bug fixes - -* Fix differ to not raise errors when dealing with differently-encoded - strings (Jon Rowe). -* Fix `expect(something).to be_within(x).percent_of(y)` where x and y are both - integers (Sam Phippen). -* Fix `have` matcher to handle the fact that on ruby 2.0, - `Enumerator#size` may return nil (Kenta Murata). -* Fix `expect { raise s }.to raise_error(s)` where s is an error instance - on ruby 2.0 (Sam Phippen). -* Fix `expect(object).to raise_error` passing. This now warns the user and - fails the spec (tomykaira). - -Deprecations - -* Deprecate `expect { }.not_to raise_error(SpecificErrorClass)` or - `expect { }.not_to raise_error("some specific message")`. Using - these was prone to hiding failures as they would allow _any other - error_ to pass. (Sam Phippen and David Chelimsky) - -### 2.13.0 / 2013-02-23 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.1...v2.13.0) - -Enhancements - -* Add support for percent deltas to `be_within` matcher: - `expect(value).to be_within(10).percent_of(expected)` - (Myron Marston). -* Add support to `include` matcher to allow it to be given a list - of matchers as the expecteds to match against (Luke Redpath). - -Bug fixes - -* Fix `change` matcher so that it dups strings in order to handle - mutated strings (Myron Marston). -* Fix `should be =~ /some regex/` / `expect(...).to be =~ /some regex/`. - Previously, these either failed with a confusing `undefined method - matches?' for false:FalseClass` error or were no-ops that didn't - actually verify anything (Myron Marston). -* Add compatibility for diff-lcs 1.2 and relax the version - constraint (Peter Goldstein). -* Fix DSL-generated matchers to allow multiple instances of the - same matcher in the same example to have different description - and failure messages based on the expected value (Myron Marston). -* Prevent `undefined method #split for Array` error when dumping - the diff of an array of multiline strings (Myron Marston). -* Don't blow up when comparing strings that are in an encoding - that is not ASCII compatible (Myron Marston). -* Remove confusing "Check the implementation of #==" message - printed for empty diffs (Myron Marston). - -### 2.12.1 / 2012-12-15 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.0...v2.12.1) - -Bug fixes - -* Improve the failure message for an expression like - `{}.should =~ {}`. (Myron Marston and Andy Lindeman) -* Provide a `match_regex` alias so that custom matchers - built using the matcher DSL can use it (since `match` - is a different method in that context). - (Steven Harman) - -### 2.12.0 / 2012-11-12 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.3...v2.12.0) - -Enhancements - -* Colorize diffs if the `--color` option is configured. (Alex Coplan) -* Include backtraces in unexpected errors handled by `raise_error` - matcher (Myron Marston) -* Print a warning when users accidentally pass a non-string argument - as an expectation message (Sam Phippen) -* `=~` and `match_array` matchers output a more useful error message when - the actual value is not an array (or an object that responds to `#to_ary`) - (Sam Phippen) - -Bug fixes - -* Fix `include` matcher so that `expect({}).to include(:a => nil)` - fails as it should (Sam Phippen). -* Fix `be_an_instance_of` matcher so that `Class#to_s` is used in the - description rather than `Class#inspect`, since some classes (like - `ActiveRecord::Base`) define a long, verbose `#inspect`. - (Tom Stuart) - -### 2.11.3 / 2012-09-04 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.2...v2.11.3) - -Bug fixes - -* Fix (and deprecate) `expect { }.should` syntax so that it works even - though it was never a documented or intended syntax. It worked as a - consequence of the implementation of `expect` in RSpec 2.10 and - earlier. (Myron Marston) -* Ensure #== is defined on built in matchers so that they can be composed. - For example: - - expect { - user.emailed! - }.to change { user.last_emailed_at }.to be_within(1.second).of(Time.zone.now) - -### 2.11.2 / 2012-07-25 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.1...v2.11.2) - -Bug fixes - -* Define `should` and `should_not` on `Object` rather than `BasicObject` - on MacRuby. On MacRuby, `BasicObject` is defined but is not the root - of the object hierarchy. (Gabriel Gilder) - -### 2.11.1 / 2012-07-08 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.0...v2.11.1) - -Bug fixes - -* Constrain `actual` in `be_within` matcher to values that respond to `-` instead - of requiring a specific type. - * `Time`, for example, is a legit alternative. - -### 2.11.0 / 2012-07-07 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.10.0...v2.11.0) - -Enhancements - -* Expand `expect` syntax so that it supports expections on bare values - in addition to blocks (Myron Marston). -* Add configuration options to control available expectation syntaxes - (Myron Marston): - * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :expect }` - * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :should }` - * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }` - * `RSpec.configuration.add_should_and_should_not_to Delegator` - -Bug fixes - -* Allow only `Numeric` values to be the "actual" in the `be_within` matcher. - This prevents confusing error messages. (Su Zhang @zhangsu) -* Define `should` and `should_not` on `BasicObject` rather than `Kernel` - on 1.9. This makes `should` and `should_not` work properly with - `BasicObject`-subclassed proxy objects like `Delegator`. (Myron - Marston) - -### 2.10.0 / 2012-05-03 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.1...v2.10.0) - -Enhancements - -* Add new `start_with` and `end_with` matchers (Jeremy Wadsack) -* Add new matchers for specifying yields (Myron Marston): - * `expect {...}.to yield_control` - * `expect {...}.to yield_with_args(1, 2, 3)` - * `expect {...}.to yield_with_no_args` - * `expect {...}.to yield_successive_args(1, 2, 3)` -* `match_unless_raises` takes multiple exception args - -Bug fixes - -* Fix `be_within` matcher to be inclusive of delta. -* Fix message-specific specs to pass on Rubinius (John Firebaugh) - -### 2.9.1 / 2012-04-03 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.0...v2.9.1) - -Bug fixes - -* Provide a helpful message if the diff between two objects is empty. -* Fix bug diffing single strings with multiline strings. -* Fix for error with using custom matchers inside other custom matchers - (mirasrael) -* Fix using execution context methods in nested DSL matchers (mirasrael) - -### 2.9.0 / 2012-03-17 -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0...v2.9.0) - -Enhancements - -* Move built-in matcher classes to RSpec::Matchers::BuiltIn to reduce pollution - of RSpec::Matchers (which is included in every example). -* Autoload files with matcher classes to improve load time. - -Bug fixes - -* Align `respond_to?` and `method_missing` in DSL-defined matchers. -* Clear out user-defined instance variables between invocations of DSL-defined - matchers. -* Dup the instance of a DSL generated matcher so its state is not changed by - subsequent invocations. -* Treat expected args consistently across positive and negative expectations - (thanks to Ralf Kistner for the heads up) - -### 2.8.0 / 2012-01-04 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc2...v2.8.0) - -Enhancements - -* Better diff output for Hash (Philippe Creux) -* Eliminate Ruby warnings (Olek Janiszewski) - -### 2.8.0.rc2 / 2011-12-19 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc1...v2.8.0.rc2) - -No changes for this release. Just releasing with the other rspec gems. - -### 2.8.0.rc1 / 2011-11-06 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.7.0...v2.8.0.rc1) - -Enhancements - -* Use classes for the built-in matchers (they're faster). -* Eliminate Ruby warnings (Matijs van Zuijlen) - -### 2.7.0 / 2011-10-16 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.6.0...v2.7.0) - -Enhancements - -* `HaveMatcher` converts argument using `to_i` (Alex Bepple & Pat Maddox) -* Improved failure message for the `have_xxx` matcher (Myron Marston) -* `HaveMatcher` supports `count` (Matthew Bellantoni) -* Change matcher dups `Enumerable` before the action, supporting custom - `Enumerable` types like `CollectionProxy` in Rails (David Chelimsky) - -Bug fixes - -* Fix typo in `have(n).xyz` documentation (Jean Boussier) -* fix `safe_sort` for ruby 1.9.2 (`Kernel` now defines `<=>` for Object) (Peter - van Hardenberg) - -### 2.6.0 / 2011-05-12 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.5.0...v2.6.0) - -Enhancements - -* `change` matcher accepts regexps (Robert Davis) -* better descriptions for `have_xxx` matchers (Magnus Bergmark) -* `range.should cover(*values)` (Anders Furseth) - -Bug fixes - -* Removed non-ascii characters that were choking rcov (Geoffrey Byers) -* change matcher dups arrays and hashes so their before/after states can be - compared correctly. -* Fix the order of inclusion of RSpec::Matchers in Test::Unit::TestCase and - MiniTest::Unit::TestCase to prevent a SystemStackError (Myron Marston) - -### 2.5.0 / 2011-02-05 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.4.0...v2.5.0) - -Enhancements - -* `should exist` works with `exist?` or `exists?` (Myron Marston) -* `expect { ... }.not_to do_something` (in addition to `to_not`) - -Documentation - -* improved docs for raise_error matcher (James Almond) - -### 2.4.0 / 2011-01-02 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.3.0...v2.4.0) - -No functional changes in this release, which was made to align with the -rspec-core-2.4.0 release. - -Enhancements - -* improved RDoc for change matcher (Jo Liss) - -### 2.3.0 / 2010-12-12 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.2.1...v2.3.0) - -Enhancements - -* diff strings when include matcher fails (Mike Sassak) - -### 2.2.0 / 2010-11-28 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.1.0...v2.2.0) - -### 2.1.0 / 2010-11-07 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.1...v2.1.0) - -Enhancements - -* `be_within(delta).of(expected)` matcher (Myron Marston) -* Lots of new Cucumber features (Myron Marston) -* Raise error if you try `should != expected` on Ruby-1.9 (Myron Marston) -* Improved failure messages from `throw_symbol` (Myron Marston) - -Bug fixes - -* Eliminate hard dependency on `RSpec::Core` (Myron Marston) -* `have_matcher` - use pluralize only when ActiveSupport inflections are indeed - defined (Josep M Bach) -* throw_symbol matcher no longer swallows exceptions (Myron Marston) -* fix matcher chaining to avoid name collisions (Myron Marston) - -### 2.0.0 / 2010-10-10 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.rc...v2.0.0) - -Enhancements - -* Add match_for_should_not method to matcher DSL (Myron Marston) - -Bug fixes - -* `respond_to` matcher works correctly with `should_not` with multiple methods - (Myron Marston) -* `include` matcher works correctly with `should_not` with multiple values - (Myron Marston) - -### 2.0.0.rc / 2010-10-05 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.22...v2.0.0.rc) - -Enhancements - -* `require 'rspec/expectations'` in a T::U or MiniUnit suite (Josep M. Bach) - -Bug fixes - -* change by 0 passes/fails correctly (Len Smith) -* Add description to satisfy matcher - -### 2.0.0.beta.22 / 2010-09-12 - -[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.20...v2.0.0.beta.22) - -Enhancements - -* diffing improvements - * diff multiline strings - * don't diff single line strings - * don't diff numbers (silly) - * diff regexp + multiline string - -Bug fixes - * `should[_not]` change now handles boolean values correctly diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md deleted file mode 100644 index dae02d8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/LICENSE.md +++ /dev/null @@ -1,25 +0,0 @@ -The MIT License (MIT) -===================== - -* Copyright © 2012 David Chelimsky, Myron Marston -* Copyright © 2006 David Chelimsky, The RSpec Development Team -* Copyright © 2005 Steven Baker - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md deleted file mode 100644 index a649542..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/README.md +++ /dev/null @@ -1,326 +0,0 @@ -# RSpec Expectations [![Build Status](https://github.com/rspec/rspec-expectations/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-expectations/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-expectations.svg)](https://codeclimate.com/github/rspec/rspec-expectations) - -RSpec::Expectations lets you express expected outcomes on an object in an -example. - -```ruby -expect(account.balance).to eq(Money.new(37.42, :USD)) -``` - -## Install - -If you want to use rspec-expectations with rspec, just install the rspec gem -and RubyGems will also install rspec-expectations for you (along with -rspec-core and rspec-mocks): - -```shell -gem install rspec -``` - -Want to run against the `main` branch? You'll need to include the dependent -RSpec repos as well. Add the following to your `Gemfile`: - -```ruby -%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| - gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' -end -``` - -If you want to use rspec-expectations with another tool, like Test::Unit, -Minitest, or Cucumber, you can install it directly: - -```shell -gem install rspec-expectations -``` - -## Contributing - -Once you've set up the environment, you'll need to cd into the working -directory of whichever repo you want to work in. From there you can run the -specs and cucumber features, and make patches. - -NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You -can treat each RSpec repo as an independent project. - -- [Build details](BUILD_DETAIL.md) -- [Code of Conduct](CODE_OF_CONDUCT.md) -- [Detailed contributing guide](CONTRIBUTING.md) -- [Development setup guide](DEVELOPMENT.md) - -## Basic usage - -Here's an example using rspec-core: - -```ruby -RSpec.describe Order do - it "sums the prices of the items in its line items" do - order = Order.new - order.add_entry(LineItem.new(:item => Item.new( - :price => Money.new(1.11, :USD) - ))) - order.add_entry(LineItem.new(:item => Item.new( - :price => Money.new(2.22, :USD), - :quantity => 2 - ))) - expect(order.total).to eq(Money.new(5.55, :USD)) - end -end -``` - -The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`, `Item` and `Money` classes would be from _your_ code. The last line of the example -expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then -the example passes. If not, it fails with a message like: - -``` - expected: # - got: # -``` - -## Built-in matchers - -### Equivalence - -```ruby -expect(actual).to eq(expected) # passes if actual == expected -expect(actual).to eql(expected) # passes if actual.eql?(expected) -expect(actual).not_to eql(not_expected) # passes if not(actual.eql?(expected)) -``` - -Note: The new `expect` syntax no longer supports the `==` matcher. - -### Identity - -```ruby -expect(actual).to be(expected) # passes if actual.equal?(expected) -expect(actual).to equal(expected) # passes if actual.equal?(expected) -``` - -### Comparisons - -```ruby -expect(actual).to be > expected -expect(actual).to be >= expected -expect(actual).to be <= expected -expect(actual).to be < expected -expect(actual).to be_within(delta).of(expected) -``` - -### Regular expressions - -```ruby -expect(actual).to match(/expression/) -``` - -Note: The new `expect` syntax no longer supports the `=~` matcher. - -### Types/classes - -```ruby -expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected -expect(actual).to be_a(expected) # passes if actual.kind_of?(expected) -expect(actual).to be_an(expected) # an alias for be_a -expect(actual).to be_a_kind_of(expected) # another alias -``` - -### Truthiness - -```ruby -expect(actual).to be_truthy # passes if actual is truthy (not nil or false) -expect(actual).to be true # passes if actual == true -expect(actual).to be_falsy # passes if actual is falsy (nil or false) -expect(actual).to be false # passes if actual == false -expect(actual).to be_nil # passes if actual is nil -expect(actual).to_not be_nil # passes if actual is not nil -``` - -### Expecting errors - -```ruby -expect { ... }.to raise_error -expect { ... }.to raise_error(ErrorClass) -expect { ... }.to raise_error("message") -expect { ... }.to raise_error(ErrorClass, "message") -``` - -### Expecting throws - -```ruby -expect { ... }.to throw_symbol -expect { ... }.to throw_symbol(:symbol) -expect { ... }.to throw_symbol(:symbol, 'value') -``` - -### Yielding - -```ruby -expect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args - -expect { |b| yield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yielded - -expect { |b| 5.tap(&b) }.to yield_with_args(5) -expect { |b| 5.tap(&b) }.to yield_with_args(Integer) -expect { |b| "a string".tap(&b) }.to yield_with_args(/str/) - -expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) -expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2]) -``` - -### Predicate matchers - -```ruby -expect(actual).to be_xxx # passes if actual.xxx? -expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg) -``` - -### Ranges (Ruby >= 1.9 only) - -```ruby -expect(1..10).to cover(3) -``` - -### Collection membership - -```ruby -# exact order, entire collection -expect(actual).to eq(expected) - -# exact order, partial collection (based on an exact position) -expect(actual).to start_with(expected) -expect(actual).to end_with(expected) - -# any order, entire collection -expect(actual).to match_array(expected) - -# You can also express this by passing the expected elements -# as individual arguments -expect(actual).to contain_exactly(expected_element1, expected_element2) - - # any order, partial collection -expect(actual).to include(expected) -``` - -#### Examples - -```ruby -expect([1, 2, 3]).to eq([1, 2, 3]) # Order dependent equality check -expect([1, 2, 3]).to include(1) # Exact ordering, partial collection matches -expect([1, 2, 3]).to include(2, 3) # -expect([1, 2, 3]).to start_with(1) # As above, but from the start of the collection -expect([1, 2, 3]).to start_with(1, 2) # -expect([1, 2, 3]).to end_with(3) # As above but from the end of the collection -expect([1, 2, 3]).to end_with(2, 3) # -expect({:a => 'b'}).to include(:a => 'b') # Matching within hashes -expect("this string").to include("is str") # Matching within strings -expect("this string").to start_with("this") # -expect("this string").to end_with("ring") # -expect([1, 2, 3]).to contain_exactly(2, 3, 1) # Order independent matches -expect([1, 2, 3]).to match_array([3, 2, 1]) # - -# Order dependent compound matchers -expect( - [{:a => 'hash'},{:a => 'another'}] -).to match([a_hash_including(:a => 'hash'), a_hash_including(:a => 'another')]) -``` - -## `should` syntax - -In addition to the `expect` syntax, rspec-expectations continues to support the -`should` syntax: - -```ruby -actual.should eq expected -actual.should be > 3 -[1, 2, 3].should_not include 4 -``` - -See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/main/Should.md) - -## Compound Matcher Expressions - -You can also create compound matcher expressions using `and` or `or`: - -``` ruby -expect(alphabet).to start_with("a").and end_with("z") -expect(stoplight.color).to eq("red").or eq("green").or eq("yellow") -``` - -## Composing Matchers - -Many of the built-in matchers are designed to take matchers as -arguments, to allow you to flexibly specify only the essential -aspects of an object or data structure. In addition, all of the -built-in matchers have one or more aliases that provide better -phrasing for when they are used as arguments to another matcher. - -### Examples - -```ruby -expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) ) - -expect { s = "barn" }.to change { s } - .from( a_string_matching(/foo/) ) - .to( a_string_matching(/bar/) ) - -expect(["barn", 2.45]).to contain_exactly( - a_value_within(0.1).of(2.5), - a_string_starting_with("bar") -) - -expect(["barn", "food", 2.45]).to end_with( - a_string_matching("foo"), - a_value > 2 -) - -expect(["barn", 2.45]).to include( a_string_starting_with("bar") ) - -expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/)) - -hash = { - :a => { - :b => ["foo", 5], - :c => { :d => 2.05 } - } -} - -expect(hash).to match( - :a => { - :b => a_collection_containing_exactly( - a_string_starting_with("f"), - an_instance_of(Integer) - ), - :c => { :d => (a_value < 3) } - } -) - -expect { |probe| - [1, 2, 3].each(&probe) -}.to yield_successive_args( a_value < 2, 2, a_value > 2 ) -``` - -## Usage outside rspec-core - -You always need to load `rspec/expectations` even if you only want to use one part of the library: - -```ruby -require 'rspec/expectations' -``` - -Then simply include `RSpec::Matchers` in any class: - -```ruby -class MyClass - include RSpec::Matchers - - def do_something(arg) - expect(arg).to be > 0 - # do other stuff - end -end -``` - -## Also see - -* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) -* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) -* [https://github.com/rspec/rspec-mocks](https://github.com/rspec/rspec-mocks) -* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb deleted file mode 100644 index 9e11ea0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'rspec/support' -RSpec::Support.require_rspec_support "caller_filter" -RSpec::Support.require_rspec_support "warnings" -RSpec::Support.require_rspec_support "object_formatter" - -require 'rspec/matchers' - -RSpec::Support.define_optimized_require_for_rspec(:expectations) { |f| require_relative(f) } - -%w[ - expectation_target - configuration - fail_with - handler - version -].each { |file| RSpec::Support.require_rspec_expectations(file) } - -module RSpec - # RSpec::Expectations provides a simple, readable API to express - # the expected outcomes in a code example. To express an expected - # outcome, wrap an object or block in `expect`, call `to` or `to_not` - # (aliased as `not_to`) and pass it a matcher object: - # - # expect(order.total).to eq(Money.new(5.55, :USD)) - # expect(list).to include(user) - # expect(message).not_to match(/foo/) - # expect { do_something }.to raise_error - # - # The last form (the block form) is needed to match against ruby constructs - # that are not objects, but can only be observed when executing a block - # of code. This includes raising errors, throwing symbols, yielding, - # and changing values. - # - # When `expect(...).to` is invoked with a matcher, it turns around - # and calls `matcher.matches?()`. For example, - # in the expression: - # - # expect(order.total).to eq(Money.new(5.55, :USD)) - # - # ...`eq(Money.new(5.55, :USD))` returns a matcher object, and it results - # in the equivalent of `eq.matches?(order.total)`. If `matches?` returns - # `true`, the expectation is met and execution continues. If `false`, then - # the spec fails with the message returned by `eq.failure_message`. - # - # Given the expression: - # - # expect(order.entries).not_to include(entry) - # - # ...the `not_to` method (also available as `to_not`) invokes the equivalent of - # `include.matches?(order.entries)`, but it interprets `false` as success, and - # `true` as a failure, using the message generated by - # `include.failure_message_when_negated`. - # - # rspec-expectations ships with a standard set of useful matchers, and writing - # your own matchers is quite simple. - # - # See [RSpec::Matchers](../RSpec/Matchers) for more information about the - # built-in matchers that ship with rspec-expectations, and how to write your - # own custom matchers. - module Expectations - # Exception raised when an expectation fails. - # - # @note We subclass Exception so that in a stub implementation if - # the user sets an expectation, it can't be caught in their - # code by a bare `rescue`. - # @api public - class ExpectationNotMetError < Exception - end - - # Exception raised from `aggregate_failures` when multiple expectations fail. - # - # @note The constant is defined here but the extensive logic of this class - # is lazily defined when `FailureAggregator` is autoloaded, since we do - # not need to waste time defining that functionality unless - # `aggregate_failures` is used. - class MultipleExpectationsNotMetError < ExpectationNotMetError - end - - autoload :BlockSnippetExtractor, "rspec/expectations/block_snippet_extractor" - autoload :FailureAggregator, "rspec/expectations/failure_aggregator" - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb deleted file mode 100644 index 25cc326..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb +++ /dev/null @@ -1,255 +0,0 @@ -module RSpec - module Expectations - # @private - class BlockSnippetExtractor # rubocop:disable Metrics/ClassLength - # rubocop should properly handle `Struct.new {}` as an inner class definition. - - attr_reader :proc, :method_name - - def self.try_extracting_single_line_body_of(proc, method_name) - lines = new(proc, method_name).body_content_lines - return nil unless lines.count == 1 - lines.first - rescue Error - nil - end - - def initialize(proc, method_name) - @proc = proc - @method_name = method_name.to_s.freeze - end - - # Ideally we should properly handle indentations of multiline snippet, - # but it's not implemented yet since because we use result of this method only when it's a - # single line and implementing the logic introduces additional complexity. - def body_content_lines - raw_body_lines.map(&:strip).reject(&:empty?) - end - - private - - def raw_body_lines - raw_body_snippet.split("\n") - end - - def raw_body_snippet - block_token_extractor.body_tokens.map(&:string).join - end - - def block_token_extractor - @block_token_extractor ||= BlockTokenExtractor.new(method_name, source, beginning_line_number) - end - - if RSpec.respond_to?(:world) - def source - raise TargetNotFoundError unless File.exist?(file_path) - RSpec.world.source_from_file(file_path) - end - else - # :nocov: - RSpec::Support.require_rspec_support 'source' - def source - raise TargetNotFoundError unless File.exist?(file_path) - @source ||= RSpec::Support::Source.from_file(file_path) - end - # :nocov: - end - - def file_path - source_location.first - end - - def beginning_line_number - source_location.last - end - - def source_location - proc.source_location || raise(TargetNotFoundError) - end - - Error = Class.new(StandardError) - TargetNotFoundError = Class.new(Error) - AmbiguousTargetError = Class.new(Error) - - # @private - # Performs extraction of block body snippet using tokens, - # which cannot be done with node information. - BlockTokenExtractor = Struct.new(:method_name, :source, :beginning_line_number) do - attr_reader :state, :body_tokens - - def initialize(*) - super - parse! - end - - private - - def parse! - @state = :initial - - catch(:finish) do - source.tokens.each do |token| - invoke_state_handler(token) - end - end - end - - def finish! - throw :finish - end - - def invoke_state_handler(token) - __send__("#{state}_state", token) - end - - def initial_state(token) - @state = :after_method_call if token.location == block_locator.method_call_location - end - - def after_method_call_state(token) - @state = :after_opener if handle_opener_token(token) - end - - def after_opener_state(token) - if handle_closer_token(token) - finish_or_find_next_block_if_incorrect! - elsif pipe_token?(token) - finalize_pending_tokens! - @state = :after_beginning_of_args - else - pending_tokens << token - handle_opener_token(token) - @state = :after_beginning_of_body unless token.type == :on_sp - end - end - - def after_beginning_of_args_state(token) - @state = :after_beginning_of_body if pipe_token?(token) - end - - def after_beginning_of_body_state(token) - if handle_closer_token(token) - finish_or_find_next_block_if_incorrect! - else - pending_tokens << token - handle_opener_token(token) - end - end - - def pending_tokens - @pending_tokens ||= [] - end - - def finalize_pending_tokens! - pending_tokens.freeze.tap do - @pending_tokens = nil - end - end - - def finish_or_find_next_block_if_incorrect! - body_tokens = finalize_pending_tokens! - - if correct_block?(body_tokens) - @body_tokens = body_tokens - finish! - else - @state = :after_method_call - end - end - - def handle_opener_token(token) - opener_token?(token).tap do |boolean| - opener_token_stack.push(token) if boolean - end - end - - def opener_token?(token) - token.type == :on_lbrace || (token.type == :on_kw && token.string == 'do') - end - - def handle_closer_token(token) - if opener_token_stack.last.closed_by?(token) - opener_token_stack.pop - opener_token_stack.empty? - else - false - end - end - - def opener_token_stack - @opener_token_stack ||= [] - end - - def pipe_token?(token) - token.type == :on_op && token.string == '|' - end - - def correct_block?(body_tokens) - return true if block_locator.body_content_locations.empty? - content_location = block_locator.body_content_locations.first - content_location.between?(body_tokens.first.location, body_tokens.last.location) - end - - def block_locator - @block_locator ||= BlockLocator.new(method_name, source, beginning_line_number) - end - end - - # @private - # Locates target block with node information (semantics), which tokens don't have. - BlockLocator = Struct.new(:method_name, :source, :beginning_line_number) do - def method_call_location - @method_call_location ||= method_ident_node.location - end - - def body_content_locations - @body_content_locations ||= block_body_node.map(&:location).compact - end - - private - - def method_ident_node - method_call_node = block_wrapper_node.children.first - method_call_node.find do |node| - method_ident_node?(node) - end - end - - def block_body_node - block_node = block_wrapper_node.children[1] - block_node.children.last - end - - def block_wrapper_node - case candidate_block_wrapper_nodes.size - when 1 - candidate_block_wrapper_nodes.first - when 0 - raise TargetNotFoundError - else - raise AmbiguousTargetError - end - end - - def candidate_block_wrapper_nodes - @candidate_block_wrapper_nodes ||= candidate_method_ident_nodes.map do |method_ident_node| - block_wrapper_node = method_ident_node.each_ancestor.find { |node| node.type == :method_add_block } - next nil unless block_wrapper_node - method_call_node = block_wrapper_node.children.first - method_call_node.include?(method_ident_node) ? block_wrapper_node : nil - end.compact - end - - def candidate_method_ident_nodes - source.nodes_by_line_number[beginning_line_number].select do |node| - method_ident_node?(node) - end - end - - def method_ident_node?(node) - node.type == :@ident && node.args.first == method_name - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb deleted file mode 100644 index 21620fb..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb +++ /dev/null @@ -1,244 +0,0 @@ -RSpec::Support.require_rspec_expectations "syntax" - -module RSpec - module Expectations - # Provides configuration options for rspec-expectations. - # If you are using rspec-core, you can access this via a - # block passed to `RSpec::Core::Configuration#expect_with`. - # Otherwise, you can access it via RSpec::Expectations.configuration. - # - # @example - # RSpec.configure do |rspec| - # rspec.expect_with :rspec do |c| - # # c is the config object - # end - # end - # - # # or - # - # RSpec::Expectations.configuration - class Configuration - # @private - FALSE_POSITIVE_BEHAVIOURS = - { - :warn => lambda { |message| RSpec.warning message }, - :raise => lambda { |message| raise ArgumentError, message }, - :nothing => lambda { |_| true }, - } - - def initialize - @on_potential_false_positives = :warn - @strict_predicate_matchers = false - end - - # Configures the supported syntax. - # @param [Array, Symbol] values the syntaxes to enable - # @example - # RSpec.configure do |rspec| - # rspec.expect_with :rspec do |c| - # c.syntax = :should - # # or - # c.syntax = :expect - # # or - # c.syntax = [:should, :expect] - # end - # end - def syntax=(values) - if Array(values).include?(:expect) - Expectations::Syntax.enable_expect - else - Expectations::Syntax.disable_expect - end - - if Array(values).include?(:should) - Expectations::Syntax.enable_should - else - Expectations::Syntax.disable_should - end - end - - # Configures the maximum character length that RSpec will print while - # formatting an object. You can set length to nil to prevent RSpec from - # doing truncation. - # @param [Fixnum] length the number of characters to limit the formatted output to. - # @example - # RSpec.configure do |rspec| - # rspec.expect_with :rspec do |c| - # c.max_formatted_output_length = 200 - # end - # end - def max_formatted_output_length=(length) - RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = length - end - - # The list of configured syntaxes. - # @return [Array] the list of configured syntaxes. - # @example - # unless RSpec::Matchers.configuration.syntax.include?(:expect) - # raise "this RSpec extension gem requires the rspec-expectations `:expect` syntax" - # end - def syntax - syntaxes = [] - syntaxes << :should if Expectations::Syntax.should_enabled? - syntaxes << :expect if Expectations::Syntax.expect_enabled? - syntaxes - end - - if ::RSpec.respond_to?(:configuration) - def color? - ::RSpec.configuration.color_enabled? - end - else - # :nocov: - # Indicates whether or not diffs should be colored. - # Delegates to rspec-core's color option if rspec-core - # is loaded; otherwise you can set it here. - attr_writer :color - - # Indicates whether or not diffs should be colored. - # Delegates to rspec-core's color option if rspec-core - # is loaded; otherwise you can set it here. - def color? - defined?(@color) && @color - end - # :nocov: - end - - # :nocov: Because this is only really _useful_ on 1.8, and hard to test elsewhere. - # - # Adds `should` and `should_not` to the given classes - # or modules. This can be used to ensure `should` works - # properly on things like proxy objects (particular - # `Delegator`-subclassed objects on 1.8). - # - # @param [Array] modules the list of classes or modules - # to add `should` and `should_not` to. - def add_should_and_should_not_to(*modules) - modules.each do |mod| - Expectations::Syntax.enable_should(mod) - end - end - # :nocov: - - # Sets or gets the backtrace formatter. The backtrace formatter should - # implement `#format_backtrace(Array)`. This is used - # to format backtraces of errors handled by the `raise_error` - # matcher. - # - # If you are using rspec-core, rspec-core's backtrace formatting - # will be used (including respecting the presence or absence of - # the `--backtrace` option). - # - # @!attribute [rw] backtrace_formatter - attr_writer :backtrace_formatter - def backtrace_formatter - @backtrace_formatter ||= if defined?(::RSpec.configuration.backtrace_formatter) - ::RSpec.configuration.backtrace_formatter - else - NullBacktraceFormatter - end - end - - # Sets if custom matcher descriptions and failure messages - # should include clauses from methods defined using `chain`. - # @param value [Boolean] - attr_writer :include_chain_clauses_in_custom_matcher_descriptions - - # Indicates whether or not custom matcher descriptions and failure messages - # should include clauses from methods defined using `chain`. It is - # false by default for backwards compatibility. - def include_chain_clauses_in_custom_matcher_descriptions? - @include_chain_clauses_in_custom_matcher_descriptions ||= false - end - - # @private - def reset_syntaxes_to_default - self.syntax = [:should, :expect] - RSpec::Expectations::Syntax.warn_about_should! - end - - # @api private - # Null implementation of a backtrace formatter used by default - # when rspec-core is not loaded. Does no filtering. - NullBacktraceFormatter = Module.new do - def self.format_backtrace(backtrace) - backtrace - end - end - - # Configures whether RSpec will warn about matcher use which will - # potentially cause false positives in tests. - # - # @param [Boolean] boolean - def warn_about_potential_false_positives=(boolean) - if boolean - self.on_potential_false_positives = :warn - elsif warn_about_potential_false_positives? - self.on_potential_false_positives = :nothing - else - # no-op, handler is something else - end - end - - # Configures what RSpec will do about matcher use which would potentially cause - # false positives in tests. Defaults to `:warn` since this is generally the desired behavior, - # but can also be set to `:raise` or `:nothing`. - # - # @overload on_potential_false_positives - # @return [Symbol] the behavior setting - # @overload on_potential_false_positives=(value) - # @param [Symbol] behavior can be set to `:warn`, `:raise` or `:nothing` - # @return [Symbol] the behavior setting - attr_reader :on_potential_false_positives - - def on_potential_false_positives=(behavior) - unless FALSE_POSITIVE_BEHAVIOURS.key?(behavior) - raise ArgumentError, "Supported values are: #{FALSE_POSITIVE_BEHAVIOURS.keys}" - end - @on_potential_false_positives = behavior - end - - # Configures RSpec to check predicate matchers to `be(true)` / `be(false)` (strict), - # or `be_truthy` / `be_falsey` (not strict). - # Historically, the default was `false`, but `true` is recommended. - # - # @overload strict_predicate_matchers - # @return [Boolean] - # @overload strict_predicate_matchers? - # @return [Boolean] - # @overload strict_predicate_matchers=(value) - # @param [Boolean] value - attr_reader :strict_predicate_matchers - - def strict_predicate_matchers=(value) - raise ArgumentError, "Pass `true` or `false`" unless value == true || value == false - @strict_predicate_matchers = value - end - - def strict_predicate_matchers? - @strict_predicate_matchers - end - - # Indicates whether RSpec will warn about matcher use which will - # potentially cause false positives in tests, generally you want to - # avoid such scenarios so this defaults to `true`. - def warn_about_potential_false_positives? - on_potential_false_positives == :warn - end - - # @private - def false_positives_handler - FALSE_POSITIVE_BEHAVIOURS.fetch(@on_potential_false_positives) - end - end - - # The configuration object. - # @return [RSpec::Expectations::Configuration] the configuration object - def self.configuration - @configuration ||= Configuration.new - end - - # set default syntax - configuration.reset_syntaxes_to_default - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb deleted file mode 100644 index 7d1e8d4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb +++ /dev/null @@ -1,163 +0,0 @@ -module RSpec - module Expectations - # Wraps the target of an expectation. - # - # @example - # expect(something) # => ExpectationTarget wrapping something - # expect { do_something } # => ExpectationTarget wrapping the block - # - # # used with `to` - # expect(actual).to eq(3) - # - # # with `not_to` - # expect(actual).not_to eq(3) - # - # @note `ExpectationTarget` is not intended to be instantiated - # directly by users. Use `expect` instead. - class ExpectationTarget - # @private - # Used as a sentinel value to be able to tell when the user - # did not pass an argument. We can't use `nil` for that because - # `nil` is a valid value to pass. - UndefinedValue = Module.new - - # @note this name aligns with `Minitest::Expectation` so that our - # {InstanceMethods} module can be included in that class when - # used in a Minitest context. - # @return [Object] the target of the expectation - attr_reader :target - - # @api private - def initialize(value) - @target = value - end - - # @private - def self.for(value, block) - if UndefinedValue.equal?(value) - unless block - raise ArgumentError, "You must pass either an argument or a block to `expect`." - end - BlockExpectationTarget.new(block) - elsif block - raise ArgumentError, "You cannot pass both an argument and a block to `expect`." - else - ValueExpectationTarget.new(value) - end - end - - # Defines instance {ExpectationTarget} instance methods. These are defined - # in a module so we can include it in `Minitest::Expectation` when - # `rspec/expectations/minitest_integration` is loaded in order to - # support usage with Minitest. - module InstanceMethods - # Runs the given expectation, passing if `matcher` returns true. - # @example - # expect(value).to eq(5) - # expect { perform }.to raise_error - # @param [Matcher] - # matcher - # @param [String, Proc] message optional message to display when the expectation fails - # @return [Boolean] true if the expectation succeeds (else raises) - # @see RSpec::Matchers - def to(matcher=nil, message=nil, &block) - prevent_operator_matchers(:to) unless matcher - RSpec::Expectations::PositiveExpectationHandler.handle_matcher(target, matcher, message, &block) - end - - # Runs the given expectation, passing if `matcher` returns false. - # @example - # expect(value).not_to eq(5) - # @param [Matcher] - # matcher - # @param [String, Proc] message optional message to display when the expectation fails - # @return [Boolean] false if the negative expectation succeeds (else raises) - # @see RSpec::Matchers - def not_to(matcher=nil, message=nil, &block) - prevent_operator_matchers(:not_to) unless matcher - RSpec::Expectations::NegativeExpectationHandler.handle_matcher(target, matcher, message, &block) - end - alias to_not not_to - - private - - def prevent_operator_matchers(verb) - raise ArgumentError, "The expect syntax does not support operator matchers, " \ - "so you must pass a matcher to `##{verb}`." - end - end - - include InstanceMethods - end - - # @private - # Validates the provided matcher to ensure it supports block - # expectations, in order to avoid user confusion when they - # use a block thinking the expectation will be on the return - # value of the block rather than the block itself. - class ValueExpectationTarget < ExpectationTarget - def to(matcher=nil, message=nil, &block) - enforce_value_expectation(matcher) - super - end - - def not_to(matcher=nil, message=nil, &block) - enforce_value_expectation(matcher) - super - end - - private - - def enforce_value_expectation(matcher) - return if supports_value_expectations?(matcher) - - RSpec.deprecate( - "expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}", - :message => - "The implicit block expectation syntax is deprecated, you should pass " \ - "a block rather than an argument to `expect` to use the provided " \ - "block expectation matcher or the matcher must implement " \ - "`supports_value_expectations?`. e.g `expect { value }.to " \ - "#{RSpec::Support::ObjectFormatter.format(matcher)}` not " \ - "`expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}`" - ) - end - - def supports_value_expectations?(matcher) - !matcher.respond_to?(:supports_value_expectations?) || matcher.supports_value_expectations? - end - end - - # @private - # Validates the provided matcher to ensure it supports block - # expectations, in order to avoid user confusion when they - # use a block thinking the expectation will be on the return - # value of the block rather than the block itself. - class BlockExpectationTarget < ExpectationTarget - def to(matcher, message=nil, &block) - enforce_block_expectation(matcher) - super - end - - def not_to(matcher, message=nil, &block) - enforce_block_expectation(matcher) - super - end - alias to_not not_to - - private - - def enforce_block_expectation(matcher) - return if supports_block_expectations?(matcher) - - raise ExpectationNotMetError, "You must pass an argument rather than a block to `expect` to use the provided " \ - "matcher (#{RSpec::Support::ObjectFormatter.format(matcher)}), or the matcher must implement " \ - "`supports_block_expectations?`." - end - - def supports_block_expectations?(matcher) - matcher.respond_to?(:supports_block_expectations?) && matcher.supports_block_expectations? - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb deleted file mode 100644 index 17b66b3..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb +++ /dev/null @@ -1,39 +0,0 @@ -module RSpec - module Expectations - class << self - # @private - class Differ - # @private - OBJECT_PREPARER = lambda do |object| - RSpec::Matchers::Composable.surface_descriptions_in(object) - end - end - - # @private - def differ - RSpec::Support::Differ.new( - :object_preparer => Differ::OBJECT_PREPARER, - :color => RSpec::Matchers.configuration.color? - ) - end - - # Raises an RSpec::Expectations::ExpectationNotMetError with message. - # @param [String] message - # @param [Object] expected - # @param [Object] actual - # - # Adds a diff to the failure message when `expected` and `actual` are - # both present. - def fail_with(message, expected=nil, actual=nil) - unless message - raise ArgumentError, "Failure message is nil. Does your matcher define the " \ - "appropriate failure_message[_when_negated] method to return a string?" - end - - message = ::RSpec::Matchers::MultiMatcherDiff.from(expected, actual).message_with_diff(message, differ) - - RSpec::Support.notify_failure(RSpec::Expectations::ExpectationNotMetError.new message) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb deleted file mode 100644 index b573bba..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb +++ /dev/null @@ -1,236 +0,0 @@ -module RSpec - module Expectations - # @private - class FailureAggregator - attr_reader :block_label, :metadata - - # @private - class AggregatedFailure - # :nocov: - # `inspect` was apparently used by some versions early in ruby 3 while constructing - # NoMethodError, but seems to be no longer. - # - # @private - MESSAGE = - 'AggregatedFailure: This method caused a failure which has been ' \ - 'suppressed to be aggregated into our failure report by returning ' \ - 'this value, further errors can be ignored.' - - def inspect - MESSAGE - end - # :nocov: - end - - AGGREGATED_FAILURE = AggregatedFailure.new - - def aggregate - RSpec::Support.with_failure_notifier(self) do - begin - yield - rescue ExpectationNotMetError => e - # Normally, expectation failures will be notified via the `call` method, below, - # but since the failure notifier uses a thread local variable, failing expectations - # in another thread will still raise. We handle that here and categorize it as part - # of `failures` rather than letting it fall through and be categorized as part of - # `other_errors`. - failures << e - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e - # While it is normally a bad practice to rescue `Exception`, it's important we do - # so here. It's low risk (`notify_aggregated_failures` below will re-raise the exception, - # or raise a `MultipleExpectationsNotMetError` that includes the exception), and it's - # essential that the user is notified of expectation failures that may have already - # occurred in the `aggregate_failures` block. Those expectation failures may provide - # important diagnostics for understanding why this exception occurred, and if we simply - # allowed this exception to be raised as-is, it would (wrongly) suggest to the user - # that the expectation passed when it did not, which would be quite confusing. - other_errors << e - end - end - - notify_aggregated_failures - end - - def failures - @failures ||= [] - end - - def other_errors - @other_errors ||= [] - end - - # This method is defined to satisfy the callable interface - # expected by `RSpec::Support.with_failure_notifier`. - def call(failure, options) - source_id = options[:source_id] - return if source_id && @seen_source_ids.key?(source_id) - - @seen_source_ids[source_id] = true - assign_backtrace(failure) unless failure.backtrace - failures << failure - - AGGREGATED_FAILURE - end - - private - - if RSpec::Support::Ruby.jruby? && RSpec::Support::Ruby.jruby_version < '9.2.0.0' - # On JRuby 9.1.x.x and before, `caller` and `raise` produce different backtraces with - # regards to `.java` stack frames. It's important that we use `raise` for JRuby to produce - # a backtrace that has a continuous common section with the raised `MultipleExpectationsNotMetError`, - # so that rspec-core's truncation logic can work properly on it to list the backtrace - # relative to the `aggregate_failures` block. - # :nocov: - def assign_backtrace(failure) - raise failure - rescue failure.class => e - failure.set_backtrace(e.backtrace) - end - # :nocov: - else - # Using `caller` performs better (and is simpler) than `raise` on most Rubies. - def assign_backtrace(failure) - failure.set_backtrace(caller) - end - end - - def initialize(block_label, metadata) - @block_label = block_label - @metadata = metadata - @seen_source_ids = {} # don't want to load stdlib set - end - - def notify_aggregated_failures - all_errors = failures + other_errors - - case all_errors.size - when 0 then return true - when 1 then RSpec::Support.notify_failure all_errors.first - else RSpec::Support.notify_failure MultipleExpectationsNotMetError.new(self) - end - end - end - - # Exception raised from `aggregate_failures` when multiple expectations fail. - class MultipleExpectationsNotMetError - # @return [String] The fully formatted exception message. - def message - @message ||= (["#{summary}:"] + enumerated_failures + enumerated_errors).join("\n\n") - end - - # @return [Array] The list of expectation failures. - def failures - @failure_aggregator.failures - end - - # @return [Array] The list of other exceptions. - def other_errors - @failure_aggregator.other_errors - end - - # @return [Array] The list of expectation failures and other exceptions, combined. - attr_reader :all_exceptions - - # @return [String] The user-assigned label for the aggregation block. - def aggregation_block_label - @failure_aggregator.block_label - end - - # @return [Hash] The metadata hash passed to `aggregate_failures`. - def aggregation_metadata - @failure_aggregator.metadata - end - - # @return [String] A summary of the failure, including the block label and a count of failures. - def summary - "Got #{exception_count_description} from failure aggregation " \ - "block#{block_description}" - end - - # return [String] A description of the failure/error counts. - def exception_count_description - failure_count = pluralize("failure", failures.size) - return failure_count if other_errors.empty? - error_count = pluralize("other error", other_errors.size) - "#{failure_count} and #{error_count}" - end - - private - - def initialize(failure_aggregator) - @failure_aggregator = failure_aggregator - @all_exceptions = failures + other_errors - end - - def block_description - return "" unless aggregation_block_label - " #{aggregation_block_label.inspect}" - end - - def pluralize(noun, count) - "#{count} #{noun}#{'s' unless count == 1}" - end - - def enumerated(exceptions, index_offset) - exceptions.each_with_index.map do |exception, index| - index += index_offset - formatted_message = "#{yield exception}\n#{format_backtrace(exception.backtrace).first}" - "#{index_label index}#{indented formatted_message, index}" - end - end - - def exclusion_patterns - patterns = %w[/lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle:] - patterns << "org/jruby/" if RSpec::Support::Ruby.jruby? - patterns.map! { |s| Regexp.new(s.gsub('/', File::SEPARATOR)) } - end - - def format_backtrace(backtrace) - backtrace.map { |l| backtrace_line(l) }.compact.tap { |filtered| filtered.concat backtrace if filtered.empty? } - end - - def backtrace_line(line) - return if [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *exclusion_patterns)].any? { |p| line =~ p } - - # It changes the current path that is relative to - # system root to be relative to the project root. - line.sub(/(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/, '\\1.\\2'.freeze).sub(/\A([^:]+:\d+)$/, '\\1'.freeze) - end - - def enumerated_failures - enumerated(failures, 0, &:message) - end - - def enumerated_errors - enumerated(other_errors, failures.size) do |error| - "#{error.class}: #{error.message}" - end - end - - def indented(failure_message, index) - line_1, *rest = failure_message.strip.lines.to_a - first_line_indentation = ' ' * (longest_index_label_width - width_of_label(index)) - - first_line_indentation + line_1 + rest.map do |line| - line =~ /\S/ ? indentation + line : line - end.join - end - - def indentation - @indentation ||= ' ' * longest_index_label_width - end - - def longest_index_label_width - @longest_index_label_width ||= width_of_label(failures.size) - end - - def width_of_label(index) - index_label(index).chars.count - end - - def index_label(index) - " #{index + 1}) " - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb deleted file mode 100644 index d86061a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb +++ /dev/null @@ -1,181 +0,0 @@ -module RSpec - module Expectations - # @private - module ExpectationHelper - def self.check_message(msg) - unless msg.nil? || msg.respond_to?(:to_str) || msg.respond_to?(:call) - RSpec.warning( - "ignoring the provided expectation message argument" \ - "(#{ msg.inspect }) since it is not a string or a proc" - ) - end - end - - # Returns an RSpec-3+ compatible matcher, wrapping a legacy one - # in an adapter if necessary. - # - # @private - def self.modern_matcher_from(matcher) - LegacyMatcherAdapter::RSpec2.wrap(matcher) || - LegacyMatcherAdapter::RSpec1.wrap(matcher) || matcher - end - - def self.with_matcher(handler, matcher, message) - check_message(message) - matcher = modern_matcher_from(matcher) - yield matcher - ensure - ::RSpec::Matchers.last_expectation_handler = handler - ::RSpec::Matchers.last_matcher = matcher - end - - def self.handle_failure(matcher, message, failure_message_method) - message = message.call if message.respond_to?(:call) - message ||= matcher.__send__(failure_message_method) - - if matcher.respond_to?(:diffable?) && matcher.diffable? - ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual - else - ::RSpec::Expectations.fail_with message - end - end - end - - # @private - class PositiveExpectationHandler - def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) - ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| - return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) unless initial_matcher - - match_result = matcher.matches?(actual, &block) - if custom_message && match_result.respond_to?(:error_generator) - match_result.error_generator.opts[:message] = custom_message - end - - match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message) - end - end - - def self.verb - 'is expected to' - end - - def self.should_method - :should - end - - def self.opposite_should_method - :should_not - end - end - - # @private - class NegativeExpectationHandler - def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) - ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| - return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) unless initial_matcher - - negated_match_result = does_not_match?(matcher, actual, &block) - if custom_message && negated_match_result.respond_to?(:error_generator) - negated_match_result.error_generator.opts[:message] = custom_message - end - - negated_match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message_when_negated) - end - end - - def self.does_not_match?(matcher, actual, &block) - if matcher.respond_to?(:does_not_match?) - matcher.does_not_match?(actual, &block) - else - !matcher.matches?(actual, &block) - end - end - - def self.verb - 'is expected not to' - end - - def self.should_method - :should_not - end - - def self.opposite_should_method - :should - end - end - - # Wraps a matcher written against one of the legacy protocols in - # order to present the current protocol. - # - # @private - class LegacyMatcherAdapter < Matchers::MatcherDelegator - def initialize(matcher) - super - ::RSpec.warn_deprecation(<<-EOS.gsub(/^\s+\|/, ''), :type => "legacy_matcher") - |#{matcher.class.name || matcher.inspect} implements a legacy RSpec matcher - |protocol. For the current protocol you should expose the failure messages - |via the `failure_message` and `failure_message_when_negated` methods. - |(Used from #{CallerFilter.first_non_rspec_line}) - EOS - end - - def self.wrap(matcher) - new(matcher) if interface_matches?(matcher) - end - - # Starting in RSpec 1.2 (and continuing through all 2.x releases), - # the failure message protocol was: - # * `failure_message_for_should` - # * `failure_message_for_should_not` - # @private - class RSpec2 < self - def failure_message - base_matcher.failure_message_for_should - end - - def failure_message_when_negated - base_matcher.failure_message_for_should_not - end - - def self.interface_matches?(matcher) - ( - !matcher.respond_to?(:failure_message) && - matcher.respond_to?(:failure_message_for_should) - ) || ( - !matcher.respond_to?(:failure_message_when_negated) && - matcher.respond_to?(:failure_message_for_should_not) - ) - end - end - - # Before RSpec 1.2, the failure message protocol was: - # * `failure_message` - # * `negative_failure_message` - # @private - class RSpec1 < self - def failure_message - base_matcher.failure_message - end - - def failure_message_when_negated - base_matcher.negative_failure_message - end - - # Note: `failure_message` is part of the RSpec 3 protocol - # (paired with `failure_message_when_negated`), so we don't check - # for `failure_message` here. - def self.interface_matches?(matcher) - !matcher.respond_to?(:failure_message_when_negated) && - matcher.respond_to?(:negative_failure_message) - end - end - end - - # RSpec 3.0 was released with the class name misspelled. For SemVer compatibility, - # we will provide this misspelled alias until 4.0. - # @deprecated Use LegacyMatcherAdapter instead. - # @private - LegacyMacherAdapter = LegacyMatcherAdapter - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb deleted file mode 100644 index 94cdb5f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'rspec/expectations' - -Minitest::Test.class_eval do - include ::RSpec::Matchers - - # This `expect` will only be called if the user is using Minitest < 5.6 - # or if they are _not_ using Minitest::Spec on 5.6+. Minitest::Spec on 5.6+ - # defines its own `expect` and will have the assertions incremented via our - # definitions of `to`/`not_to`/`to_not` below. - def expect(*a, &b) - self.assertions += 1 - super - end - - # Convert a `MultipleExpectationsNotMetError` to a `Minitest::Assertion` error so - # it gets counted in minitest's summary stats as a failure rather than an error. - # It would be nice to make `MultipleExpectationsNotMetError` subclass - # `Minitest::Assertion`, but Minitest's implementation does not treat subclasses - # the same, so this is the best we can do. - def aggregate_failures(*args, &block) - super - rescue RSpec::Expectations::MultipleExpectationsNotMetError => e - assertion_failed = Minitest::Assertion.new(e.message) - assertion_failed.set_backtrace e.backtrace - raise assertion_failed - end -end - -# Older versions of Minitest (e.g. before 5.6) do not define -# `Minitest::Expectation`. -if defined?(::Minitest::Expectation) - Minitest::Expectation.class_eval do - include RSpec::Expectations::ExpectationTarget::InstanceMethods - - def to(*args) - ctx.assertions += 1 - super - end - - def not_to(*args) - ctx.assertions += 1 - super - end - - def to_not(*args) - ctx.assertions += 1 - super - end - end -end - -module RSpec - module Expectations - remove_const :ExpectationNotMetError - # Exception raised when an expectation fails. - const_set :ExpectationNotMetError, ::Minitest::Assertion - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb deleted file mode 100644 index b843034..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb +++ /dev/null @@ -1,132 +0,0 @@ -module RSpec - module Expectations - # @api private - # Provides methods for enabling and disabling the available - # syntaxes provided by rspec-expectations. - module Syntax - module_function - - # @api private - # Determines where we add `should` and `should_not`. - def default_should_host - @default_should_host ||= ::Object.ancestors.last - end - - # @api private - # Instructs rspec-expectations to warn on first usage of `should` or `should_not`. - # Enabled by default. This is largely here to facilitate testing. - def warn_about_should! - @warn_about_should = true - end - - # @api private - # Generates a deprecation warning for the given method if no warning - # has already been issued. - def warn_about_should_unless_configured(method_name) - return unless @warn_about_should - - RSpec.deprecate( - "Using `#{method_name}` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax", - :replacement => "the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }`" - ) - - @warn_about_should = false - end - - # @api private - # Enables the `should` syntax. - def enable_should(syntax_host=default_should_host) - @warn_about_should = false if syntax_host == default_should_host - return if should_enabled?(syntax_host) - - syntax_host.module_exec do - def should(matcher=nil, message=nil, &block) - ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) - ::RSpec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block) - end - - def should_not(matcher=nil, message=nil, &block) - ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) - ::RSpec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block) - end - end - end - - # @api private - # Disables the `should` syntax. - def disable_should(syntax_host=default_should_host) - return unless should_enabled?(syntax_host) - - syntax_host.module_exec do - undef should - undef should_not - end - end - - # @api private - # Enables the `expect` syntax. - def enable_expect(syntax_host=::RSpec::Matchers) - return if expect_enabled?(syntax_host) - - syntax_host.module_exec do - def expect(value=::RSpec::Expectations::ExpectationTarget::UndefinedValue, &block) - ::RSpec::Expectations::ExpectationTarget.for(value, block) - end - end - end - - # @api private - # Disables the `expect` syntax. - def disable_expect(syntax_host=::RSpec::Matchers) - return unless expect_enabled?(syntax_host) - - syntax_host.module_exec do - undef expect - end - end - - # @api private - # Indicates whether or not the `should` syntax is enabled. - def should_enabled?(syntax_host=default_should_host) - syntax_host.method_defined?(:should) - end - - # @api private - # Indicates whether or not the `expect` syntax is enabled. - def expect_enabled?(syntax_host=::RSpec::Matchers) - syntax_host.method_defined?(:expect) - end - end - end -end - -if defined?(BasicObject) - # The legacy `:should` syntax adds the following methods directly to - # `BasicObject` so that they are available off of any object. Note, however, - # that this syntax does not always play nice with delegate/proxy objects. - # We recommend you use the non-monkeypatching `:expect` syntax instead. - class BasicObject - # @method should(matcher, message) - # Passes if `matcher` returns true. Available on every `Object`. - # @example - # actual.should eq expected - # actual.should match /expression/ - # @param [Matcher] - # matcher - # @param [String] message optional message to display when the expectation fails - # @return [Boolean] true if the expectation succeeds (else raises) - # @note This is only available when you have enabled the `:should` syntax. - # @see RSpec::Matchers - - # @method should_not(matcher, message) - # Passes if `matcher` returns false. Available on every `Object`. - # @example - # actual.should_not eq expected - # @param [Matcher] - # matcher - # @param [String] message optional message to display when the expectation fails - # @return [Boolean] false if the negative expectation succeeds (else raises) - # @note This is only available when you have enabled the `:should` syntax. - # @see RSpec::Matchers - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb deleted file mode 100644 index 0fc9ef9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb +++ /dev/null @@ -1,8 +0,0 @@ -module RSpec - module Expectations - # @private - module Version - STRING = '3.13.5' - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb deleted file mode 100644 index d5347d1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb +++ /dev/null @@ -1,1046 +0,0 @@ -require 'rspec/support' -RSpec::Support.require_rspec_support 'matcher_definition' -RSpec::Support.define_optimized_require_for_rspec(:matchers) { |f| require_relative(f) } - -%w[ - english_phrasing - composable - built_in - generated_descriptions - dsl - matcher_delegator - aliased_matcher - multi_matcher_diff -].each { |file| RSpec::Support.require_rspec_matchers(file) } - -# RSpec's top level namespace. All of rspec-expectations is contained -# in the `RSpec::Expectations` and `RSpec::Matchers` namespaces. -module RSpec - # RSpec::Matchers provides a number of useful matchers we use to define - # expectations. Any object that implements the [matcher protocol](Matchers/MatcherProtocol) - # can be used as a matcher. - # - # ## Predicates - # - # In addition to matchers that are defined explicitly, RSpec will create - # custom matchers on the fly for any arbitrary predicate, giving your specs a - # much more natural language feel. - # - # A Ruby predicate is a method that ends with a "?" and returns true or false. - # Common examples are `empty?`, `nil?`, and `instance_of?`. - # - # All you need to do is write `expect(..).to be_` followed by the predicate - # without the question mark, and RSpec will figure it out from there. - # For example: - # - # expect([]).to be_empty # => [].empty?() | passes - # expect([]).not_to be_empty # => [].empty?() | fails - # - # In addition to prefixing the predicate matchers with "be_", you can also use "be_a_" - # and "be_an_", making your specs read much more naturally: - # - # expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes - # - # expect(3).to be_a_kind_of(Integer) # => 3.kind_of?(Numeric) | passes - # expect(3).to be_a_kind_of(Numeric) # => 3.kind_of?(Numeric) | passes - # expect(3).to be_an_instance_of(Integer) # => 3.instance_of?(Integer) | passes - # expect(3).not_to be_an_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails - # - # RSpec will also create custom matchers for predicates like `has_key?`. To - # use this feature, just state that the object should have_key(:key) and RSpec will - # call has_key?(:key) on the target. For example: - # - # expect(:a => "A").to have_key(:a) - # expect(:a => "A").to have_key(:b) # fails - # - # You can use this feature to invoke any predicate that begins with "has_", whether it is - # part of the Ruby libraries (like `Hash#has_key?`) or a method you wrote on your own class. - # - # Note that RSpec does not provide composable aliases for these dynamic predicate - # matchers. You can easily define your own aliases, though: - # - # RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin - # expect(user_list).to include(a_user_who_is_an_admin) - # - # ## Alias Matchers - # - # With {RSpec::Matchers.alias_matcher}, you can easily create an - # alternate name for a given matcher. - # - # The description will also change according to the new name: - # - # RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to - # sum_to(3).description # => "sum to 3" - # a_list_that_sums_to(3).description # => "a list that sums to 3" - # - # or you can specify a custom description like this: - # - # RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description| - # description.sub("be sorted by", "a list sorted by") - # end - # - # be_sorted_by(:age).description # => "be sorted by age" - # a_list_sorted_by(:age).description # => "a list sorted by age" - # - # ## Custom Matchers - # - # When you find that none of the stock matchers provide a natural feeling - # expectation, you can very easily write your own using RSpec's matcher DSL - # or writing one from scratch. - # - # ### Matcher DSL - # - # Imagine that you are writing a game in which players can be in various - # zones on a virtual board. To specify that bob should be in zone 4, you - # could say: - # - # expect(bob.current_zone).to eql(Zone.new("4")) - # - # But you might find it more expressive to say: - # - # expect(bob).to be_in_zone("4") - # - # and/or - # - # expect(bob).not_to be_in_zone("3") - # - # You can create such a matcher like so: - # - # RSpec::Matchers.define :be_in_zone do |zone| - # match do |player| - # player.in_zone?(zone) - # end - # end - # - # This will generate a be_in_zone method that returns a matcher - # with logical default messages for failures. You can override the failure - # messages and the generated description as follows: - # - # RSpec::Matchers.define :be_in_zone do |zone| - # match do |player| - # player.in_zone?(zone) - # end - # - # failure_message do |player| - # # generate and return the appropriate string. - # end - # - # failure_message_when_negated do |player| - # # generate and return the appropriate string. - # end - # - # description do - # # generate and return the appropriate string. - # end - # end - # - # Each of the message-generation methods has access to the block arguments - # passed to the create method (in this case, zone). The - # failure message methods (failure_message and - # failure_message_when_negated) are passed the actual value (the - # receiver of expect(..) or expect(..).not_to). - # - # ### Custom Matcher from scratch - # - # You could also write a custom matcher from scratch, as follows: - # - # class BeInZone - # def initialize(expected) - # @expected = expected - # end - # - # def matches?(target) - # @target = target - # @target.current_zone.eql?(Zone.new(@expected)) - # end - # - # def failure_message - # "expected #{@target.inspect} to be in Zone #{@expected}" - # end - # - # def failure_message_when_negated - # "expected #{@target.inspect} not to be in Zone #{@expected}" - # end - # end - # - # ... and a method like this: - # - # def be_in_zone(expected) - # BeInZone.new(expected) - # end - # - # And then expose the method to your specs. This is normally done - # by including the method and the class in a module, which is then - # included in your spec: - # - # module CustomGameMatchers - # class BeInZone - # # ... - # end - # - # def be_in_zone(expected) - # # ... - # end - # end - # - # describe "Player behaviour" do - # include CustomGameMatchers - # # ... - # end - # - # or you can include in globally in a spec_helper.rb file required - # from your spec file(s): - # - # RSpec::configure do |config| - # config.include(CustomGameMatchers) - # end - # - # ### Making custom matchers composable - # - # RSpec's built-in matchers are designed to be composed, in expressions like: - # - # expect(["barn", 2.45]).to contain_exactly( - # a_value_within(0.1).of(2.5), - # a_string_starting_with("bar") - # ) - # - # Custom matchers can easily participate in composed matcher expressions like these. - # Include {RSpec::Matchers::Composable} in your custom matcher to make it support - # being composed (matchers defined using the DSL have this included automatically). - # Within your matcher's `matches?` method (or the `match` block, if using the DSL), - # use `values_match?(expected, actual)` rather than `expected == actual`. - # Under the covers, `values_match?` is able to match arbitrary - # nested data structures containing a mix of both matchers and non-matcher objects. - # It uses `===` and `==` to perform the matching, considering the values to - # match if either returns `true`. The `Composable` mixin also provides some helper - # methods for surfacing the matcher descriptions within your matcher's description - # or failure messages. - # - # RSpec's built-in matchers each have a number of aliases that rephrase the matcher - # from a verb phrase (such as `be_within`) to a noun phrase (such as `a_value_within`), - # which reads better when the matcher is passed as an argument in a composed matcher - # expressions, and also uses the noun-phrase wording in the matcher's `description`, - # for readable failure messages. You can alias your custom matchers in similar fashion - # using {RSpec::Matchers.alias_matcher}. - # - # ## Negated Matchers - # - # Sometimes if you want to test for the opposite using a more descriptive name - # instead of using `not_to`, you can use {RSpec::Matchers.define_negated_matcher}: - # - # RSpec::Matchers.define_negated_matcher :exclude, :include - # include(1, 2).description # => "include 1 and 2" - # exclude(1, 2).description # => "exclude 1 and 2" - # - # While the most obvious negated form may be to add a `not_` prefix, - # the failure messages you get with that form can be confusing (e.g. - # "expected [actual] to not [verb], but did not"). We've found it works - # best to find a more positive name for the negated form, such as - # `avoid_changing` rather than `not_change`. - # - module Matchers # rubocop:disable Metrics/ModuleLength - extend ::RSpec::Matchers::DSL - - # @!macro [attach] alias_matcher - # @!parse - # alias $1 $2 - # @!visibility private - # We define this override here so we can attach a YARD macro to it. - # It ensures that our docs list all the matcher aliases. - def self.alias_matcher(*args, &block) - super(*args, &block) - end - - # @!method self.alias_matcher(new_name, old_name, options={}, &description_override) - # Extended from {RSpec::Matchers::DSL#alias_matcher}. - - # @!method self.define(name, &declarations) - # Extended from {RSpec::Matchers::DSL#define}. - - # @!method self.define_negated_matcher(negated_name, base_name, &description_override) - # Extended from {RSpec::Matchers::DSL#define_negated_matcher}. - - # @method expect - # Supports `expect(actual).to matcher` syntax by wrapping `actual` in an - # `ExpectationTarget`. - # @example - # expect(actual).to eq(expected) - # expect(actual).not_to eq(expected) - # @return [Expectations::ExpectationTarget] - # @see Expectations::ExpectationTarget#to - # @see Expectations::ExpectationTarget#not_to - - # Allows multiple expectations in the provided block to fail, and then - # aggregates them into a single exception, rather than aborting on the - # first expectation failure like normal. This allows you to see all - # failures from an entire set of expectations without splitting each - # off into its own example (which may slow things down if the example - # setup is expensive). - # - # @param label [String] label for this aggregation block, which will be - # included in the aggregated exception message. - # @param metadata [Hash] additional metadata about this failure aggregation - # block. If multiple expectations fail, it will be exposed from the - # {Expectations::MultipleExpectationsNotMetError} exception. Mostly - # intended for internal RSpec use but you can use it as well. - # @yield Block containing as many expectation as you want. The block is - # simply yielded to, so you can trust that anything that works outside - # the block should work within it. - # @raise [Expectations::MultipleExpectationsNotMetError] raised when - # multiple expectations fail. - # @raise [Expectations::ExpectationNotMetError] raised when a single - # expectation fails. - # @raise [Exception] other sorts of exceptions will be raised as normal. - # - # @example - # aggregate_failures("verifying response") do - # expect(response.status).to eq(200) - # expect(response.headers).to include("Content-Type" => "text/plain") - # expect(response.body).to include("Success") - # end - # - # @note The implementation of this feature uses a thread-local variable, - # which means that if you have an expectation failure in another thread, - # it'll abort like normal. - def aggregate_failures(label=nil, metadata={}, &block) - Expectations::FailureAggregator.new(label, metadata).aggregate(&block) - end - - # Passes if actual is truthy (anything but false or nil) - def be_truthy - BuiltIn::BeTruthy.new - end - alias_matcher :a_truthy_value, :be_truthy - - # Passes if actual is falsey (false or nil) - def be_falsey - BuiltIn::BeFalsey.new - end - alias_matcher :be_falsy, :be_falsey - alias_matcher :a_falsey_value, :be_falsey - alias_matcher :a_falsy_value, :be_falsey - - # Passes if actual is nil - def be_nil - BuiltIn::BeNil.new - end - alias_matcher :a_nil_value, :be_nil - - # @example - # expect(actual).to be_truthy - # expect(actual).to be_falsey - # expect(actual).to be_nil - # expect(actual).to be_[arbitrary_predicate](*args) - # expect(actual).not_to be_nil - # expect(actual).not_to be_[arbitrary_predicate](*args) - # - # Given true, false, or nil, will pass if actual value is true, false or - # nil (respectively). Given no args means the caller should satisfy an if - # condition (to be or not to be). - # - # Predicates are any Ruby method that ends in a "?" and returns true or - # false. Given be_ followed by arbitrary_predicate (without the "?"), - # RSpec will match convert that into a query against the target object. - # - # The arbitrary_predicate feature will handle any predicate prefixed with - # "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of) or "be_" - # (e.g. be_empty), letting you choose the prefix that best suits the - # predicate. - def be(*args) - args.empty? ? Matchers::BuiltIn::Be.new : equal(*args) - end - alias_matcher :a_value, :be, :klass => AliasedMatcherWithOperatorSupport - - # passes if target.kind_of?(klass) - def be_a(klass) - be_a_kind_of(klass) - end - alias_method :be_an, :be_a - - # Passes if actual.instance_of?(expected) - # - # @example - # expect(5).to be_an_instance_of(Integer) - # expect(5).not_to be_an_instance_of(Numeric) - # expect(5).not_to be_an_instance_of(Float) - def be_an_instance_of(expected) - BuiltIn::BeAnInstanceOf.new(expected) - end - alias_method :be_instance_of, :be_an_instance_of - alias_matcher :an_instance_of, :be_an_instance_of - - # Passes if actual.kind_of?(expected) - # - # @example - # expect(5).to be_a_kind_of(Integer) - # expect(5).to be_a_kind_of(Numeric) - # expect(5).not_to be_a_kind_of(Float) - def be_a_kind_of(expected) - BuiltIn::BeAKindOf.new(expected) - end - alias_method :be_kind_of, :be_a_kind_of - alias_matcher :a_kind_of, :be_a_kind_of - - # Passes if actual.between?(min, max). Works with any Comparable object, - # including String, Symbol, Time, or Numeric (Fixnum, Bignum, Integer, - # Float, Complex, and Rational). - # - # By default, `be_between` is inclusive (i.e. passes when given either the max or min value), - # but you can make it `exclusive` by chaining that off the matcher. - # - # @example - # expect(5).to be_between(1, 10) - # expect(11).not_to be_between(1, 10) - # expect(10).not_to be_between(1, 10).exclusive - def be_between(min, max) - BuiltIn::BeBetween.new(min, max) - end - alias_matcher :a_value_between, :be_between - - # Passes if actual == expected +/- delta - # - # @example - # expect(result).to be_within(0.5).of(3.0) - # expect(result).not_to be_within(0.5).of(3.0) - def be_within(delta) - BuiltIn::BeWithin.new(delta) - end - alias_matcher :a_value_within, :be_within - alias_matcher :within, :be_within - - # Applied to a proc, specifies that its execution will cause some value to - # change. - # - # @param [Object] receiver - # @param [Symbol] message the message to send the receiver - # - # You can either pass receiver and message, or a block, - # but not both. - # - # When passing a block, it must use the `{ ... }` format, not - # do/end, as `{ ... }` binds to the `change` method, whereas do/end - # would errantly bind to the `expect(..).to` or `expect(...).not_to` method. - # - # You can chain any of the following off of the end to specify details - # about the change: - # - # * `from` - # * `to` - # - # or any one of: - # - # * `by` - # * `by_at_least` - # * `by_at_most` - # - # @example - # expect { - # team.add_player(player) - # }.to change(roster, :count) - # - # expect { - # team.add_player(player) - # }.to change(roster, :count).by(1) - # - # expect { - # team.add_player(player) - # }.to change(roster, :count).by_at_least(1) - # - # expect { - # team.add_player(player) - # }.to change(roster, :count).by_at_most(1) - # - # string = "string" - # expect { - # string.reverse! - # }.to change { string }.from("string").to("gnirts") - # - # string = "string" - # expect { - # string - # }.not_to change { string }.from("string") - # - # expect { - # person.happy_birthday - # }.to change(person, :birthday).from(32).to(33) - # - # expect { - # employee.develop_great_new_social_networking_app - # }.to change(employee, :title).from("Mail Clerk").to("CEO") - # - # expect { - # doctor.leave_office - # }.to change(doctor, :sign).from(/is in/).to(/is out/) - # - # user = User.new(:type => "admin") - # expect { - # user.symbolize_type - # }.to change(user, :type).from(String).to(Symbol) - # - # == Notes - # - # Evaluates `receiver.message` or `block` before and after it - # evaluates the block passed to `expect`. If the value is the same - # object, its before/after `hash` value is used to see if it has changed. - # Therefore, your object needs to properly implement `hash` to work correctly - # with this matcher. - # - # `expect( ... ).not_to change` supports the form that specifies `from` - # (which specifies what you expect the starting, unchanged value to be) - # but does not support forms with subsequent calls to `by`, `by_at_least`, - # `by_at_most` or `to`. - def change(receiver=nil, message=nil, &block) - BuiltIn::Change.new(receiver, message, &block) - end - alias_matcher :a_block_changing, :change - alias_matcher :changing, :change - - # Passes if actual contains all of the expected regardless of order. - # This works for collections. Pass in multiple args and it will only - # pass if all args are found in collection. - # - # @note This is also available using the `=~` operator with `should`, - # but `=~` is not supported with `expect`. - # - # @example - # expect([1, 2, 3]).to contain_exactly(1, 2, 3) - # expect([1, 2, 3]).to contain_exactly(1, 3, 2) - # - # @see #match_array - def contain_exactly(*items) - BuiltIn::ContainExactly.new(items) - end - alias_matcher :a_collection_containing_exactly, :contain_exactly - alias_matcher :containing_exactly, :contain_exactly - - # Passes if actual covers expected. This works for - # Ranges. You can also pass in multiple args - # and it will only pass if all args are found in Range. - # - # @example - # expect(1..10).to cover(5) - # expect(1..10).to cover(4, 6) - # expect(1..10).to cover(4, 6, 11) # fails - # expect(1..10).not_to cover(11) - # expect(1..10).not_to cover(5) # fails - # - # ### Warning:: Ruby >= 1.9 only - def cover(*values) - BuiltIn::Cover.new(*values) - end - alias_matcher :a_range_covering, :cover - alias_matcher :covering, :cover - - # Matches if the actual value ends with the expected value(s). In the case - # of a string, matches against the last `expected.length` characters of the - # actual string. In the case of an array, matches against the last - # `expected.length` elements of the actual array. - # - # @example - # expect("this string").to end_with "string" - # expect([0, 1, 2, 3, 4]).to end_with 4 - # expect([0, 2, 3, 4, 4]).to end_with 3, 4 - def end_with(*expected) - BuiltIn::EndWith.new(*expected) - end - alias_matcher :a_collection_ending_with, :end_with - alias_matcher :a_string_ending_with, :end_with - alias_matcher :ending_with, :end_with - - # Passes if actual == expected. - # - # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more - # information about equality in Ruby. - # - # @example - # expect(5).to eq(5) - # expect(5).not_to eq(3) - def eq(expected) - BuiltIn::Eq.new(expected) - end - alias_matcher :an_object_eq_to, :eq - alias_matcher :eq_to, :eq - - # Passes if `actual.eql?(expected)` - # - # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more - # information about equality in Ruby. - # - # @example - # expect(5).to eql(5) - # expect(5).not_to eql(3) - def eql(expected) - BuiltIn::Eql.new(expected) - end - alias_matcher :an_object_eql_to, :eql - alias_matcher :eql_to, :eql - - # Passes if actual.equal?(expected) (object identity). - # - # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more - # information about equality in Ruby. - # - # @example - # expect(5).to equal(5) # Integers are equal - # expect("5").not_to equal("5") # Strings that look the same are not the same object - def equal(expected) - BuiltIn::Equal.new(expected) - end - alias_matcher :an_object_equal_to, :equal - alias_matcher :equal_to, :equal - - # Passes if `actual.exist?` or `actual.exists?` - # - # @example - # expect(File).to exist("path/to/file") - def exist(*args) - BuiltIn::Exist.new(*args) - end - alias_matcher :an_object_existing, :exist - alias_matcher :existing, :exist - - # Passes if actual's attribute values match the expected attributes hash. - # This works no matter how you define your attribute readers. - # - # @example - # Person = Struct.new(:name, :age) - # person = Person.new("Bob", 32) - # - # expect(person).to have_attributes(:name => "Bob", :age => 32) - # expect(person).to have_attributes(:name => a_string_starting_with("B"), :age => (a_value > 30) ) - # - # @note It will fail if actual doesn't respond to any of the expected attributes. - # - # @example - # expect(person).to have_attributes(:color => "red") - def have_attributes(expected) - BuiltIn::HaveAttributes.new(expected) - end - alias_matcher :an_object_having_attributes, :have_attributes - alias_matcher :having_attributes, :have_attributes - - # Passes if actual includes expected. This works for - # collections and Strings. You can also pass in multiple args - # and it will only pass if all args are found in collection. - # - # @example - # expect([1,2,3]).to include(3) - # expect([1,2,3]).to include(2,3) - # expect([1,2,3]).to include(2,3,4) # fails - # expect([1,2,3]).not_to include(4) - # expect("spread").to include("read") - # expect("spread").not_to include("red") - # expect(:a => 1, :b => 2).to include(:a) - # expect(:a => 1, :b => 2).to include(:a, :b) - # expect(:a => 1, :b => 2).to include(:a => 1) - # expect(:a => 1, :b => 2).to include(:b => 2, :a => 1) - # expect(:a => 1, :b => 2).to include(:c) # fails - # expect(:a => 1, :b => 2).not_to include(:a => 2) - def include(*expected) - BuiltIn::Include.new(*expected) - end - alias_matcher :a_collection_including, :include - alias_matcher :a_string_including, :include - alias_matcher :a_hash_including, :include - alias_matcher :including, :include - - # Passes if the provided matcher passes when checked against all - # elements of the collection. - # - # @example - # expect([1, 3, 5]).to all be_odd - # expect([1, 3, 6]).to all be_odd # fails - # - # @note The negative form `not_to all` is not supported. Instead - # use `not_to include` or pass a negative form of a matcher - # as the argument (e.g. `all exclude(:foo)`). - # - # @note You can also use this with compound matchers as well. - # - # @example - # expect([1, 3, 5]).to all( be_odd.and be_an(Integer) ) - def all(expected) - BuiltIn::All.new(expected) - end - - # Given a `Regexp` or `String`, passes if `actual.match(pattern)` - # Given an arbitrary nested data structure (e.g. arrays and hashes), - # matches if `expected === actual` || `actual == expected` for each - # pair of elements. - # - # @example - # expect(email).to match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) - # expect(email).to match("@example.com") - # - # @example - # hash = { - # :a => { - # :b => ["foo", 5], - # :c => { :d => 2.05 } - # } - # } - # - # expect(hash).to match( - # :a => { - # :b => a_collection_containing_exactly( - # a_string_starting_with("f"), - # an_instance_of(Integer) - # ), - # :c => { :d => (a_value < 3) } - # } - # ) - # - # @note The `match_regex` alias is deprecated and is not recommended for use. - # It was added in 2.12.1 to facilitate its use from within custom - # matchers (due to how the custom matcher DSL was evaluated in 2.x, - # `match` could not be used there), but is no longer needed in 3.x. - def match(expected) - BuiltIn::Match.new(expected) - end - alias_matcher :match_regex, :match - alias_matcher :an_object_matching, :match - alias_matcher :a_string_matching, :match - alias_matcher :matching, :match - - # An alternate form of `contain_exactly` that accepts - # the expected contents as a single array arg rather - # than splatted out as individual items. - # - # @example - # expect(results).to contain_exactly(1, 2) - # # is identical to: - # expect(results).to match_array([1, 2]) - # - # @see #contain_exactly - def match_array(items) - contain_exactly(*items) - end - alias_matcher :an_array_matching, :match_array do |desc| - desc.sub("contain exactly", "an array containing exactly") - end - - # With no arg, passes if the block outputs `to_stdout` or `to_stderr`. - # With a string, passes if the block outputs that specific string `to_stdout` or `to_stderr`. - # With a regexp or matcher, passes if the block outputs a string `to_stdout` or `to_stderr` that matches. - # - # To capture output from any spawned subprocess as well, use `to_stdout_from_any_process` or - # `to_stderr_from_any_process`. Output from any process that inherits the main process's corresponding - # standard stream will be captured. - # - # @example - # expect { print 'foo' }.to output.to_stdout - # expect { print 'foo' }.to output('foo').to_stdout - # expect { print 'foo' }.to output(/foo/).to_stdout - # - # expect { do_something }.to_not output.to_stdout - # - # expect { warn('foo') }.to output.to_stderr - # expect { warn('foo') }.to output('foo').to_stderr - # expect { warn('foo') }.to output(/foo/).to_stderr - # - # expect { do_something }.to_not output.to_stderr - # - # expect { system('echo foo') }.to output("foo\n").to_stdout_from_any_process - # expect { system('echo foo', out: :err) }.to output("foo\n").to_stderr_from_any_process - # - # @note `to_stdout` and `to_stderr` work by temporarily replacing `$stdout` or `$stderr`, - # so they're not able to intercept stream output that explicitly uses `STDOUT`/`STDERR` - # or that uses a reference to `$stdout`/`$stderr` that was stored before the - # matcher was used. - # @note `to_stdout_from_any_process` and `to_stderr_from_any_process` use Tempfiles, and - # are thus significantly (~30x) slower than `to_stdout` and `to_stderr`. - def output(expected=nil) - BuiltIn::Output.new(expected) - end - alias_matcher :a_block_outputting, :output - - # With no args, matches if any error is raised. - # With a named error, matches only if that specific error is raised. - # With a named error and message specified as a String, matches only if both match. - # With a named error and message specified as a Regexp, matches only if both match. - # Pass an optional block to perform extra verifications on the exception matched - # - # @example - # expect { do_something_risky }.to raise_error - # expect { do_something_risky }.to raise_error(PoorRiskDecisionError) - # expect { do_something_risky }.to raise_error(PoorRiskDecisionError) { |error| expect(error.data).to eq 42 } - # expect { do_something_risky }.to raise_error { |error| expect(error.data).to eq 42 } - # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, "that was too risky") - # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, /oo ri/) - # expect { do_something_risky }.to raise_error("that was too risky") - # - # expect { do_something_risky }.not_to raise_error - def raise_error(error=BuiltIn::RaiseError::UndefinedValue, message=nil, &block) - BuiltIn::RaiseError.new(error, message, &block) - end - alias_method :raise_exception, :raise_error - - alias_matcher :a_block_raising, :raise_error do |desc| - desc.sub("raise", "a block raising") - end - - alias_matcher :raising, :raise_error do |desc| - desc.sub("raise", "raising") - end - - # Matches if the target object responds to all of the names - # provided. Names can be Strings or Symbols. - # - # @example - # expect("string").to respond_to(:length) - # - def respond_to(*names) - BuiltIn::RespondTo.new(*names) - end - alias_matcher :an_object_responding_to, :respond_to - alias_matcher :responding_to, :respond_to - - # Passes if the submitted block returns true. Yields target to the - # block. - # - # Generally speaking, this should be thought of as a last resort when - # you can't find any other way to specify the behaviour you wish to - # specify. - # - # If you do find yourself in such a situation, you could always write - # a custom matcher, which would likely make your specs more expressive. - # - # @param description [String] optional description to be used for this matcher. - # - # @example - # expect(5).to satisfy { |n| n > 3 } - # expect(5).to satisfy("be greater than 3") { |n| n > 3 } - def satisfy(description=nil, &block) - BuiltIn::Satisfy.new(description, &block) - end - alias_matcher :an_object_satisfying, :satisfy - alias_matcher :satisfying, :satisfy - - # Matches if the actual value starts with the expected value(s). In the - # case of a string, matches against the first `expected.length` characters - # of the actual string. In the case of an array, matches against the first - # `expected.length` elements of the actual array. - # - # @example - # expect("this string").to start_with "this s" - # expect([0, 1, 2, 3, 4]).to start_with 0 - # expect([0, 2, 3, 4, 4]).to start_with 0, 1 - def start_with(*expected) - BuiltIn::StartWith.new(*expected) - end - alias_matcher :a_collection_starting_with, :start_with - alias_matcher :a_string_starting_with, :start_with - alias_matcher :starting_with, :start_with - - # Given no argument, matches if a proc throws any Symbol. - # - # Given a Symbol, matches if the given proc throws the specified Symbol. - # - # Given a Symbol and an arg, matches if the given proc throws the - # specified Symbol with the specified arg. - # - # @example - # expect { do_something_risky }.to throw_symbol - # expect { do_something_risky }.to throw_symbol(:that_was_risky) - # expect { do_something_risky }.to throw_symbol(:that_was_risky, 'culprit') - # - # expect { do_something_risky }.not_to throw_symbol - # expect { do_something_risky }.not_to throw_symbol(:that_was_risky) - # expect { do_something_risky }.not_to throw_symbol(:that_was_risky, 'culprit') - def throw_symbol(expected_symbol=nil, expected_arg=nil) - BuiltIn::ThrowSymbol.new(expected_symbol, expected_arg) - end - - alias_matcher :a_block_throwing, :throw_symbol do |desc| - desc.sub("throw", "a block throwing") - end - - alias_matcher :throwing, :throw_symbol do |desc| - desc.sub("throw", "throwing") - end - - # Passes if the method called in the expect block yields, regardless - # of whether or not arguments are yielded. - # - # @example - # expect { |b| 5.tap(&b) }.to yield_control - # expect { |b| "a".to_sym(&b) }.not_to yield_control - # - # @note Your expect block must accept a parameter and pass it on to - # the method-under-test as a block. - def yield_control - BuiltIn::YieldControl.new - end - alias_matcher :a_block_yielding_control, :yield_control - alias_matcher :yielding_control, :yield_control - - # Passes if the method called in the expect block yields with - # no arguments. Fails if it does not yield, or yields with arguments. - # - # @example - # expect { |b| User.transaction(&b) }.to yield_with_no_args - # expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5` - # expect { |b| "a".to_sym(&b) }.not_to yield_with_no_args # because it does not yield - # - # @note Your expect block must accept a parameter and pass it on to - # the method-under-test as a block. - # @note This matcher is not designed for use with methods that yield - # multiple times. - def yield_with_no_args - BuiltIn::YieldWithNoArgs.new - end - alias_matcher :a_block_yielding_with_no_args, :yield_with_no_args - alias_matcher :yielding_with_no_args, :yield_with_no_args - - # Given no arguments, matches if the method called in the expect - # block yields with arguments (regardless of what they are or how - # many there are). - # - # Given arguments, matches if the method called in the expect block - # yields with arguments that match the given arguments. - # - # Argument matching is done using `===` (the case match operator) - # and `==`. If the expected and actual arguments match with either - # operator, the matcher will pass. - # - # @example - # expect { |b| 5.tap(&b) }.to yield_with_args # because #tap yields an arg - # expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5 - # expect { |b| 5.tap(&b) }.to yield_with_args(Integer) # because Integer === 5 - # expect { |b| File.open("f.txt", &b) }.to yield_with_args(/txt/) # because /txt/ === "f.txt" - # - # expect { |b| User.transaction(&b) }.not_to yield_with_args # because it yields no args - # expect { |b| 5.tap(&b) }.not_to yield_with_args(1, 2, 3) - # - # @note Your expect block must accept a parameter and pass it on to - # the method-under-test as a block. - # @note This matcher is not designed for use with methods that yield - # multiple times. - def yield_with_args(*args) - BuiltIn::YieldWithArgs.new(*args) - end - alias_matcher :a_block_yielding_with_args, :yield_with_args - alias_matcher :yielding_with_args, :yield_with_args - - # Designed for use with methods that repeatedly yield (such as - # iterators). Passes if the method called in the expect block yields - # multiple times with arguments matching those given. - # - # Argument matching is done using `===` (the case match operator) - # and `==`. If the expected and actual arguments match with either - # operator, the matcher will pass. - # - # @example - # expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) - # expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2]) - # expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2) - # - # @note Your expect block must accept a parameter and pass it on to - # the method-under-test as a block. - def yield_successive_args(*args) - BuiltIn::YieldSuccessiveArgs.new(*args) - end - alias_matcher :a_block_yielding_successive_args, :yield_successive_args - alias_matcher :yielding_successive_args, :yield_successive_args - - # Delegates to {RSpec::Expectations.configuration}. - # This is here because rspec-core's `expect_with` option - # looks for a `configuration` method on the mixin - # (`RSpec::Matchers`) to yield to a block. - # @return [RSpec::Expectations::Configuration] the configuration object - def self.configuration - Expectations.configuration - end - - private - - BE_PREDICATE_REGEX = /^(?:be_(?:an?_)?)(.*)/ - HAS_REGEX = /^(?:have_)(.*)/ - DYNAMIC_MATCHER_REGEX = Regexp.union(BE_PREDICATE_REGEX, HAS_REGEX) - - def method_missing(method, *args, &block) - case method.to_s - when BE_PREDICATE_REGEX - BuiltIn::BePredicate.new(method, *args, &block) - when HAS_REGEX - BuiltIn::Has.new(method, *args, &block) - else - super - end - end - ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) - - if RUBY_VERSION.to_f >= 1.9 - def respond_to_missing?(method, *) - method =~ DYNAMIC_MATCHER_REGEX || super - end - else # for 1.8.7 - # :nocov: - def respond_to?(method, *) - method = method.to_s - method =~ DYNAMIC_MATCHER_REGEX || super - end - public :respond_to? - # :nocov: - end - - # @api private - def self.is_a_matcher?(obj) - return true if ::RSpec::Matchers::BuiltIn::BaseMatcher === obj - begin - return false if obj.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher) - rescue NoMethodError - # Some objects, like BasicObject, don't implemented standard - # reflection methods. - return false - end - return false unless obj.respond_to?(:matches?) - - obj.respond_to?(:failure_message) || - obj.respond_to?(:failure_message_for_should) # support legacy matchers - end - - ::RSpec::Support.register_matcher_definition do |obj| - is_a_matcher?(obj) - end - - # @api private - def self.is_a_describable_matcher?(obj) - is_a_matcher?(obj) && obj.respond_to?(:description) - end - - class << self - private - - if RSpec::Support::Ruby.mri? && RUBY_VERSION[0, 3] == '1.9' - # Note that `included` doesn't work for this because it is triggered - # _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather - # than _before_, like `append_features`. It's important we check this before - # in order to find the cases where it was already previously included. - # @api private - # :nocov: - def append_features(mod) - return super if mod < self # `mod < self` indicates a re-inclusion. - - subclasses = ObjectSpace.each_object(Class).select { |c| c < mod && c < self } - return super unless subclasses.any? - - subclasses.reject! { |s| subclasses.any? { |s2| s < s2 } } # Filter to the root ancestor. - subclasses = subclasses.map { |s| "`#{s}`" }.join(", ") - - RSpec.warning "`#{self}` has been included in a superclass (`#{mod}`) " \ - "after previously being included in subclasses (#{subclasses}), " \ - "which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \ - "(https://redmine.ruby-lang.org/issues/3351). To work around this, " \ - "either upgrade to MRI 2.0+, include a dup of the module (e.g. " \ - "`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \ - "before it is included in subclasses (#{subclasses}). See " \ - "https://github.com/rspec/rspec-expectations/issues/814 for more info" - - super - end - # :nocov: - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb deleted file mode 100644 index c52c4c4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb +++ /dev/null @@ -1,116 +0,0 @@ -module RSpec - module Matchers - # Decorator that wraps a matcher and overrides `description` - # using the provided block in order to support an alias - # of a matcher. This is intended for use when composing - # matchers, so that you can use an expression like - # `include( a_value_within(0.1).of(3) )` rather than - # `include( be_within(0.1).of(3) )`, and have the corresponding - # description read naturally. - # - # @api private - class AliasedMatcher < MatcherDelegator - def initialize(base_matcher, description_block) - @description_block = description_block - super(base_matcher) - end - - # Forward messages on to the wrapped matcher. - # Since many matchers provide a fluent interface - # (e.g. `a_value_within(0.1).of(3)`), we need to wrap - # the returned value if it responds to `description`, - # so that our override can be applied when it is eventually - # used. - def method_missing(*) - return_val = super - return return_val unless RSpec::Matchers.is_a_matcher?(return_val) - self.class.new(return_val, @description_block) - end - - # Provides the description of the aliased matcher. Aliased matchers - # are designed to behave identically to the original matcher except - # for the description and failure messages. The description is different - # to reflect the aliased name. - # - # @api private - def description - @description_block.call(super) - end - - # Provides the failure_message of the aliased matcher. Aliased matchers - # are designed to behave identically to the original matcher except - # for the description and failure messages. The failure_message is different - # to reflect the aliased name. - # - # @api private - def failure_message - @description_block.call(super) - end - - # Provides the failure_message_when_negated of the aliased matcher. Aliased matchers - # are designed to behave identically to the original matcher except - # for the description and failure messages. The failure_message_when_negated is different - # to reflect the aliased name. - # - # @api private - def failure_message_when_negated - @description_block.call(super) - end - end - - # Decorator used for matchers that have special implementations of - # operators like `==` and `===`. - # @private - class AliasedMatcherWithOperatorSupport < AliasedMatcher - # We undef these so that they get delegated via `method_missing`. - undef == - undef === - end - - # @private - class AliasedNegatedMatcher < AliasedMatcher - def matches?(*args, &block) - if @base_matcher.respond_to?(:does_not_match?) - @base_matcher.does_not_match?(*args, &block) - else - !super - end - end - - def does_not_match?(*args, &block) - @base_matcher.matches?(*args, &block) - end - - def failure_message - optimal_failure_message(__method__, :failure_message_when_negated) - end - - def failure_message_when_negated - optimal_failure_message(__method__, :failure_message) - end - - private - - DefaultFailureMessages = BuiltIn::BaseMatcher::DefaultFailureMessages - - # For a matcher that uses the default failure messages, we prefer to - # use the override provided by the `description_block`, because it - # includes the phrasing that the user has expressed a preference for - # by going through the effort of defining a negated matcher. - # - # However, if the override didn't actually change anything, then we - # should return the opposite failure message instead -- the overridden - # message is going to be confusing if we return it as-is, as it represents - # the non-negated failure message for a negated match (or vice versa). - def optimal_failure_message(same, inverted) - if DefaultFailureMessages.has_default_failure_messages?(@base_matcher) - base_message = @base_matcher.__send__(same) - overridden = @description_block.call(base_message) - return overridden if overridden != base_message - end - - @base_matcher.__send__(inverted) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb deleted file mode 100644 index e6237ff..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb +++ /dev/null @@ -1,53 +0,0 @@ -RSpec::Support.require_rspec_matchers "built_in/base_matcher" - -module RSpec - module Matchers - # Container module for all built-in matchers. The matcher classes are here - # (rather than directly under `RSpec::Matchers`) in order to prevent name - # collisions, since `RSpec::Matchers` gets included into the user's namespace. - # - # Autoloading is used to delay when the matcher classes get loaded, allowing - # rspec-matchers to boot faster, and avoiding loading matchers the user is - # not using. - module BuiltIn - autoload :BeAKindOf, 'rspec/matchers/built_in/be_kind_of' - autoload :BeAnInstanceOf, 'rspec/matchers/built_in/be_instance_of' - autoload :BeBetween, 'rspec/matchers/built_in/be_between' - autoload :Be, 'rspec/matchers/built_in/be' - autoload :BeComparedTo, 'rspec/matchers/built_in/be' - autoload :BeFalsey, 'rspec/matchers/built_in/be' - autoload :BeHelpers, 'rspec/matchers/built_in/be' - autoload :BeNil, 'rspec/matchers/built_in/be' - autoload :BePredicate, 'rspec/matchers/built_in/has' - autoload :BeTruthy, 'rspec/matchers/built_in/be' - autoload :BeWithin, 'rspec/matchers/built_in/be_within' - autoload :Change, 'rspec/matchers/built_in/change' - autoload :Compound, 'rspec/matchers/built_in/compound' - autoload :ContainExactly, 'rspec/matchers/built_in/contain_exactly' - autoload :Cover, 'rspec/matchers/built_in/cover' - autoload :EndWith, 'rspec/matchers/built_in/start_or_end_with' - autoload :Eq, 'rspec/matchers/built_in/eq' - autoload :Eql, 'rspec/matchers/built_in/eql' - autoload :Equal, 'rspec/matchers/built_in/equal' - autoload :Exist, 'rspec/matchers/built_in/exist' - autoload :Has, 'rspec/matchers/built_in/has' - autoload :HaveAttributes, 'rspec/matchers/built_in/have_attributes' - autoload :Include, 'rspec/matchers/built_in/include' - autoload :All, 'rspec/matchers/built_in/all' - autoload :Match, 'rspec/matchers/built_in/match' - autoload :NegativeOperatorMatcher, 'rspec/matchers/built_in/operators' - autoload :OperatorMatcher, 'rspec/matchers/built_in/operators' - autoload :Output, 'rspec/matchers/built_in/output' - autoload :PositiveOperatorMatcher, 'rspec/matchers/built_in/operators' - autoload :RaiseError, 'rspec/matchers/built_in/raise_error' - autoload :RespondTo, 'rspec/matchers/built_in/respond_to' - autoload :Satisfy, 'rspec/matchers/built_in/satisfy' - autoload :StartWith, 'rspec/matchers/built_in/start_or_end_with' - autoload :ThrowSymbol, 'rspec/matchers/built_in/throw_symbol' - autoload :YieldControl, 'rspec/matchers/built_in/yield' - autoload :YieldSuccessiveArgs, 'rspec/matchers/built_in/yield' - autoload :YieldWithArgs, 'rspec/matchers/built_in/yield' - autoload :YieldWithNoArgs, 'rspec/matchers/built_in/yield' - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb deleted file mode 100644 index 27cce20..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb +++ /dev/null @@ -1,86 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `all`. - # Not intended to be instantiated directly. - class All < BaseMatcher - # @private - attr_reader :matcher, :failed_objects - - def initialize(matcher) - @matcher = matcher - @failed_objects = {} - end - - # @private - def does_not_match?(_actual) - raise NotImplementedError, '`expect().not_to all( matcher )` is not supported.' - end - - # @api private - # @return [String] - def failure_message - unless iterable? - return "#{improve_hash_formatting(super)}, but was not iterable" - end - - all_messages = [improve_hash_formatting(super)] - failed_objects.each do |index, matcher_failure_message| - all_messages << failure_message_for_item(index, matcher_failure_message) - end - all_messages.join("\n\n") - end - - # @api private - # @return [String] - def description - improve_hash_formatting "all #{description_of matcher}" - end - - private - - def match(_expected, _actual) - return false unless iterable? - - index_failed_objects - failed_objects.empty? - end - - def index_failed_objects - actual.each_with_index do |actual_item, index| - cloned_matcher = matcher.clone - matches = cloned_matcher.matches?(actual_item) - failed_objects[index] = cloned_matcher.failure_message unless matches - end - end - - def failure_message_for_item(index, failure_message) - failure_message = indent_multiline_message(add_new_line_if_needed(failure_message)) - indent_multiline_message("object at index #{index} failed to match:#{failure_message}") - end - - def add_new_line_if_needed(message) - message.start_with?("\n") ? message : "\n#{message}" - end - - def indent_multiline_message(message) - message = message.sub(/\n+\z/, '') - message.lines.map do |line| - line =~ /\S/ ? ' ' + line : line - end.join - end - - def initialize_copy(other) - @matcher = @matcher.clone - @failed_objects = @failed_objects.clone - super - end - - def iterable? - @actual.respond_to?(:each_with_index) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb deleted file mode 100644 index 8dd5133..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb +++ /dev/null @@ -1,225 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # - # Used _internally_ as a base class for matchers that ship with - # rspec-expectations and rspec-rails. - # - # ### Warning: - # - # This class is for internal use, and subject to change without notice. - # We strongly recommend that you do not base your custom matchers on this - # class. If/when this changes, we will announce it and remove this warning. - class BaseMatcher - include RSpec::Matchers::Composable - - # @api private - # Used to detect when no arg is passed to `initialize`. - # `nil` cannot be used because it's a valid value to pass. - UNDEFINED = Object.new.freeze - - # @private - attr_reader :actual, :expected, :rescued_exception - - # @private - attr_writer :matcher_name - - def initialize(expected=UNDEFINED) - @expected = expected unless UNDEFINED.equal?(expected) - end - - # @api private - # Indicates if the match is successful. Delegates to `match`, which - # should be defined on a subclass. Takes care of consistently - # initializing the `actual` attribute. - def matches?(actual) - @actual = actual - match(expected, actual) - end - - # @api private - # Used to wrap a block of code that will indicate failure by - # raising one of the named exceptions. - # - # This is used by rspec-rails for some of its matchers that - # wrap rails' assertions. - def match_unless_raises(*exceptions) - exceptions.unshift Exception if exceptions.empty? - begin - yield - true - rescue *exceptions => @rescued_exception - false - end - end - - # @api private - # Generates a description using {EnglishPhrasing}. - # @return [String] - def description - desc = EnglishPhrasing.split_words(self.class.matcher_name) - desc << EnglishPhrasing.list(@expected) if defined?(@expected) - desc - end - - # @api private - # Matchers are not diffable by default. Override this to make your - # subclass diffable. - def diffable? - false - end - - # @api private - # Most matchers are value matchers (i.e. meant to work with `expect(value)`) - # rather than block matchers (i.e. meant to work with `expect { }`), so - # this defaults to false. Block matchers must override this to return true. - def supports_block_expectations? - false - end - - # @private - def supports_value_expectations? - true - end - - # @api private - def expects_call_stack_jump? - false - end - - # @private - def expected_formatted - RSpec::Support::ObjectFormatter.format(@expected) - end - - # @private - def actual_formatted - RSpec::Support::ObjectFormatter.format(@actual) - end - - # @private - def self.matcher_name - @matcher_name ||= underscore(name.split('::').last) - end - - # @private - def matcher_name - if defined?(@matcher_name) - @matcher_name - else - self.class.matcher_name - end - end - - # @private - # Borrowed from ActiveSupport. - def self.underscore(camel_cased_word) - word = camel_cased_word.to_s.dup - word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2') - word.gsub!(/([a-z\d])([A-Z])/, '\1_\2') - word.tr!('-', '_') - word.downcase! - word - end - private_class_method :underscore - - # @private - module HashFormatting - # `{ :a => 5, :b => 2 }.inspect` produces: - # - # {:a=>5, :b=>2} - # - # ...but it looks much better as: - # - # {:a => 5, :b => 2} - # - # This is idempotent and safe to run on a string multiple times. - def improve_hash_formatting(inspect_string) - inspect_string.gsub(/(\S)=>(\S)/, '\1 => \2') - end - module_function :improve_hash_formatting - end - - include HashFormatting - - # @private - module StringEncodingFormatting - # @api private - # @return [Boolean] True if the actual and expected string encoding are different. - # i.e. the failure may be related to encoding differences and the encoding - # should be shown to the user. false otherwise. - if String.method_defined?(:encoding) - def string_encoding_differs? - actual.is_a?(String) && expected.is_a?(String) && actual.encoding != expected.encoding - end - else - # @api private - # @return [Boolean] False always as the curent Ruby version does not support String encoding - # :nocov: - def string_encoding_differs? - false - end - # :nocov: - end - module_function :string_encoding_differs? - - if String.method_defined?(:encoding) - # @api private - # Formats a String's encoding as a human readable string - # @param value [String] - # @return [String] - def format_encoding(value) - "#" - end - else - # @api private - # Formats a String's encoding as a human readable string - # @param _value [String] - # @return [nil] nil as the curent Ruby version does not support String encoding - # :nocov: - def format_encoding(_value) - nil - end - # :nocov: - end - module_function :format_encoding - end - - include StringEncodingFormatting - - # @api private - # Provides default implementations of failure messages, based on the `description`. - module DefaultFailureMessages - # @api private - # Provides a good generic failure message. Based on `description`. - # When subclassing, if you are not satisfied with this failure message - # you often only need to override `description`. - # @return [String] - def failure_message - "expected #{description_of @actual} to #{description}".dup - end - - # @api private - # Provides a good generic negative failure message. Based on `description`. - # When subclassing, if you are not satisfied with this failure message - # you often only need to override `description`. - # @return [String] - def failure_message_when_negated - "expected #{description_of @actual} not to #{description}".dup - end - - # @private - def self.has_default_failure_messages?(matcher) - matcher.method(:failure_message).owner == self && - matcher.method(:failure_message_when_negated).owner == self - rescue NameError - false - end - end - - include DefaultFailureMessages - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb deleted file mode 100644 index 40d4017..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb +++ /dev/null @@ -1,191 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `be_truthy`. - # Not intended to be instantiated directly. - class BeTruthy < BaseMatcher - # @api private - # @return [String] - def failure_message - "expected: truthy value\n got: #{actual_formatted}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected: falsey value\n got: #{actual_formatted}" - end - - private - - def match(_, actual) - !!actual - end - end - - # @api private - # Provides the implementation for `be_falsey`. - # Not intended to be instantiated directly. - class BeFalsey < BaseMatcher - # @api private - # @return [String] - def failure_message - "expected: falsey value\n got: #{actual_formatted}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected: truthy value\n got: #{actual_formatted}" - end - - private - - def match(_, actual) - !actual - end - end - - # @api private - # Provides the implementation for `be_nil`. - # Not intended to be instantiated directly. - class BeNil < BaseMatcher - # @api private - # @return [String] - def failure_message - "expected: nil\n got: #{actual_formatted}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected: not nil\n got: nil" - end - - private - - def match(_, actual) - actual.nil? - end - end - - # @private - module BeHelpers - private - - def args_to_s - @args.empty? ? "" : parenthesize(inspected_args.join(', ')) - end - - def parenthesize(string) - "(#{string})" - end - - def inspected_args - @args.map { |a| RSpec::Support::ObjectFormatter.format(a) } - end - - def expected_to_sentence - EnglishPhrasing.split_words(@expected) - end - - def args_to_sentence - EnglishPhrasing.list(@args) - end - end - - # @api private - # Provides the implementation for `be`. - # Not intended to be instantiated directly. - class Be < BaseMatcher - include BeHelpers - - def initialize(*args) - @args = args - end - - # @api private - # @return [String] - def failure_message - "expected #{actual_formatted} to evaluate to true" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected #{actual_formatted} to evaluate to false" - end - - [:==, :<, :<=, :>=, :>, :===, :=~].each do |operator| - define_method operator do |operand| - BeComparedTo.new(operand, operator) - end - end - - private - - def match(_, actual) - !!actual - end - end - - # @api private - # Provides the implementation of `be value`. - # Not intended to be instantiated directly. - class BeComparedTo < BaseMatcher - include BeHelpers - - def initialize(operand, operator) - @expected = operand - @operator = operator - @args = [] - end - - def matches?(actual) - perform_match(actual) - rescue ArgumentError, NoMethodError - false - end - - def does_not_match?(actual) - !perform_match(actual) - rescue ArgumentError, NoMethodError - false - end - - # @api private - # @return [String] - def failure_message - "expected: #{@operator} #{expected_formatted}\n" \ - " got: #{@operator.to_s.gsub(/./, ' ')} #{actual_formatted}" - end - - # @api private - # @return [String] - def failure_message_when_negated - message = "`expect(#{actual_formatted}).not_to " \ - "be #{@operator} #{expected_formatted}`" - if [:<, :>, :<=, :>=].include?(@operator) - message + " not only FAILED, it is a bit confusing." - else - message - end - end - - # @api private - # @return [String] - def description - "be #{@operator} #{expected_to_sentence}#{args_to_sentence}" - end - - private - - def perform_match(actual) - @actual = actual - @actual.__send__ @operator, @expected - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb deleted file mode 100644 index 55f084e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb +++ /dev/null @@ -1,77 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `be_between`. - # Not intended to be instantiated directly. - class BeBetween < BaseMatcher - def initialize(min, max) - @min, @max = min, max - inclusive - end - - # @api public - # Makes the between comparison inclusive. - # - # @example - # expect(3).to be_between(2, 3).inclusive - # - # @note The matcher is inclusive by default; this simply provides - # a way to be more explicit about it. - def inclusive - @less_than_operator = :<= - @greater_than_operator = :>= - @mode = :inclusive - self - end - - # @api public - # Makes the between comparison exclusive. - # - # @example - # expect(3).to be_between(2, 4).exclusive - def exclusive - @less_than_operator = :< - @greater_than_operator = :> - @mode = :exclusive - self - end - - # @api private - # @return [Boolean] - def matches?(actual) - @actual = actual - comparable? && compare - rescue ArgumentError - false - end - - # @api private - # @return [String] - def failure_message - "#{super}#{not_comparable_clause}" - end - - # @api private - # @return [String] - def description - "be between #{description_of @min} and #{description_of @max} (#{@mode})" - end - - private - - def comparable? - @actual.respond_to?(@less_than_operator) && @actual.respond_to?(@greater_than_operator) - end - - def not_comparable_clause - ", but it does not respond to `#{@less_than_operator}` and `#{@greater_than_operator}`" unless comparable? - end - - def compare - @actual.__send__(@greater_than_operator, @min) && @actual.__send__(@less_than_operator, @max) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb deleted file mode 100644 index e71d380..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb +++ /dev/null @@ -1,26 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `be_an_instance_of`. - # Not intended to be instantiated directly. - class BeAnInstanceOf < BaseMatcher - # @api private - # @return [String] - def description - "be an instance of #{expected}" - end - - private - - def match(expected, actual) - actual.instance_of?(expected) - rescue NoMethodError - raise ::ArgumentError, "The #{matcher_name} matcher requires that " \ - "the actual object responds to #instance_of? method " \ - "but a `NoMethodError` was encountered instead." - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb deleted file mode 100644 index 4fe23bd..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb +++ /dev/null @@ -1,20 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `be_a_kind_of`. - # Not intended to be instantiated directly. - class BeAKindOf < BaseMatcher - private - - def match(expected, actual) - actual.kind_of?(expected) - rescue NoMethodError - raise ::ArgumentError, "The #{matcher_name} matcher requires that " \ - "the actual object responds to #kind_of? method " \ - "but a `NoMethodError` was encountered instead." - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb deleted file mode 100644 index 7a2b5b5..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb +++ /dev/null @@ -1,72 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `be_within`. - # Not intended to be instantiated directly. - class BeWithin < BaseMatcher - def initialize(delta) - @delta = delta - end - - # @api public - # Sets the expected value. - def of(expected) - @expected = expected - @tolerance = @delta - @unit = '' - self - end - - # @api public - # Sets the expected value, and makes the matcher do - # a percent comparison. - def percent_of(expected) - @expected = expected - @tolerance = @expected.abs * @delta / 100.0 - @unit = '%' - self - end - - # @private - def matches?(actual) - @actual = actual - raise needs_expected unless defined? @expected - numeric? && (@actual - @expected).abs <= @tolerance - end - - # @api private - # @return [String] - def failure_message - "expected #{actual_formatted} to #{description}#{not_numeric_clause}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected #{actual_formatted} not to #{description}" - end - - # @api private - # @return [String] - def description - "be within #{@delta}#{@unit} of #{expected_formatted}" - end - - private - - def numeric? - @actual.respond_to?(:-) - end - - def needs_expected - ArgumentError.new "You must set an expected value using #of: be_within(#{@delta}).of(expected_value)" - end - - def not_numeric_clause - ", but it could not be treated as a numeric value" unless numeric? - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb deleted file mode 100644 index 00e65dc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb +++ /dev/null @@ -1,452 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `change`. - # Not intended to be instantiated directly. - class Change < BaseMatcher - # @api public - # Specifies the delta of the expected change. - def by(expected_delta) - ChangeRelatively.new(change_details, expected_delta, :by) do |actual_delta| - values_match?(expected_delta, actual_delta) - end - end - - # @api public - # Specifies a minimum delta of the expected change. - def by_at_least(minimum) - ChangeRelatively.new(change_details, minimum, :by_at_least) do |actual_delta| - actual_delta >= minimum - end - end - - # @api public - # Specifies a maximum delta of the expected change. - def by_at_most(maximum) - ChangeRelatively.new(change_details, maximum, :by_at_most) do |actual_delta| - actual_delta <= maximum - end - end - - # @api public - # Specifies the new value you expect. - def to(value) - ChangeToValue.new(change_details, value) - end - - # @api public - # Specifies the original value. - def from(value) - ChangeFromValue.new(change_details, value) - end - - # @private - def matches?(event_proc) - raise_block_syntax_error if block_given? - perform_change(event_proc) && change_details.changed? - end - - def does_not_match?(event_proc) - raise_block_syntax_error if block_given? - perform_change(event_proc) && !change_details.changed? - end - - # @api private - # @return [String] - def failure_message - "expected #{change_details.value_representation} to have changed, " \ - "but #{positive_failure_reason}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected #{change_details.value_representation} not to have changed, " \ - "but #{negative_failure_reason}" - end - - # @api private - # @return [String] - def description - "change #{change_details.value_representation}" - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - private - - def initialize(receiver=nil, message=nil, &block) - @receiver = receiver - @message = message - @block = block - end - - def change_details - @change_details ||= ChangeDetails.new(matcher_name, @receiver, @message, &@block) - end - - def perform_change(event_proc) - @event_proc = event_proc - change_details.perform_change(event_proc) do |actual_before| - # pre-compute values derived from the `before` value before the - # mutation is applied, in case the specified mutation is mutation - # of a single object (rather than a changing what object a method - # returns). We need to cache these values before the `before` value - # they are based on potentially gets mutated. - @actual_before_description = description_of(actual_before) - end - end - - def raise_block_syntax_error - raise SyntaxError, "Block not received by the `change` matcher. " \ - "Perhaps you want to use `{ ... }` instead of do/end?" - end - - def positive_failure_reason - return "was not given a block" unless Proc === @event_proc - "is still #{@actual_before_description}" - end - - def negative_failure_reason - return "was not given a block" unless Proc === @event_proc - "did change from #{@actual_before_description} " \ - "to #{description_of change_details.actual_after}" - end - end - - # Used to specify a relative change. - # @api private - class ChangeRelatively < BaseMatcher - def initialize(change_details, expected_delta, relativity, &comparer) - @change_details = change_details - @expected_delta = expected_delta - @relativity = relativity - @comparer = comparer - end - - # @private - def failure_message - "expected #{@change_details.value_representation} to have changed " \ - "#{@relativity.to_s.tr('_', ' ')} " \ - "#{description_of @expected_delta}, but #{failure_reason}" - end - - # @private - def matches?(event_proc) - @event_proc = event_proc - @change_details.perform_change(event_proc) && @comparer.call(@change_details.actual_delta) - end - - # @private - def does_not_match?(_event_proc) - raise NotImplementedError, "`expect { }.not_to change " \ - "{ }.#{@relativity}()` is not supported" - end - - # @private - def description - "change #{@change_details.value_representation} " \ - "#{@relativity.to_s.tr('_', ' ')} #{description_of @expected_delta}" - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - private - - def failure_reason - return "was not given a block" unless Proc === @event_proc - "was changed by #{description_of @change_details.actual_delta}" - end - end - - # @api private - # Base class for specifying a change from and/or to specific values. - class SpecificValuesChange < BaseMatcher - # @private - MATCH_ANYTHING = ::Object.ancestors.last - - def initialize(change_details, from, to) - @change_details = change_details - @expected_before = from - @expected_after = to - end - - # @private - def matches?(event_proc) - perform_change(event_proc) && @change_details.changed? && @matches_before && matches_after? - end - - # @private - def description - "change #{@change_details.value_representation} #{change_description}" - end - - # @private - def failure_message - return not_given_a_block_failure unless Proc === @event_proc - return before_value_failure unless @matches_before - return did_not_change_failure unless @change_details.changed? - after_value_failure - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - private - - def perform_change(event_proc) - @event_proc = event_proc - @change_details.perform_change(event_proc) do |actual_before| - # pre-compute values derived from the `before` value before the - # mutation is applied, in case the specified mutation is mutation - # of a single object (rather than a changing what object a method - # returns). We need to cache these values before the `before` value - # they are based on potentially gets mutated. - @matches_before = values_match?(@expected_before, actual_before) - @actual_before_description = description_of(actual_before) - end - end - - def matches_after? - values_match?(@expected_after, @change_details.actual_after) - end - - def before_value_failure - "expected #{@change_details.value_representation} " \ - "to have initially been #{description_of @expected_before}, " \ - "but was #{@actual_before_description}" - end - - def after_value_failure - "expected #{@change_details.value_representation} " \ - "to have changed to #{description_of @expected_after}, " \ - "but is now #{description_of @change_details.actual_after}" - end - - def did_not_change_failure - "expected #{@change_details.value_representation} " \ - "to have changed #{change_description}, but did not change" - end - - def did_change_failure - "expected #{@change_details.value_representation} not to have changed, but " \ - "did change from #{@actual_before_description} " \ - "to #{description_of @change_details.actual_after}" - end - - def not_given_a_block_failure - "expected #{@change_details.value_representation} to have changed " \ - "#{change_description}, but was not given a block" - end - end - - # @api private - # Used to specify a change from a specific value - # (and, optionally, to a specific value). - class ChangeFromValue < SpecificValuesChange - def initialize(change_details, expected_before) - @description_suffix = nil - super(change_details, expected_before, MATCH_ANYTHING) - end - - # @api public - # Specifies the new value you expect. - def to(value) - @expected_after = value - @description_suffix = " to #{description_of value}" - self - end - - # @private - def does_not_match?(event_proc) - if @description_suffix - raise NotImplementedError, "`expect { }.not_to change { }.to()` " \ - "is not supported" - end - - perform_change(event_proc) && !@change_details.changed? && @matches_before - end - - # @private - def failure_message_when_negated - return not_given_a_block_failure unless Proc === @event_proc - return before_value_failure unless @matches_before - did_change_failure - end - - private - - def change_description - "from #{description_of @expected_before}#{@description_suffix}" - end - end - - # @api private - # Used to specify a change to a specific value - # (and, optionally, from a specific value). - class ChangeToValue < SpecificValuesChange - def initialize(change_details, expected_after) - @description_suffix = nil - super(change_details, MATCH_ANYTHING, expected_after) - end - - # @api public - # Specifies the original value. - def from(value) - @expected_before = value - @description_suffix = " from #{description_of value}" - self - end - - # @private - def does_not_match?(_event_proc) - raise NotImplementedError, "`expect { }.not_to change { }.to()` " \ - "is not supported" - end - - private - - def change_description - "to #{description_of @expected_after}#{@description_suffix}" - end - end - - # @private - # Encapsulates the details of the before/after values. - # - # Note that this class exposes the `actual_after` value, to allow the - # matchers above to derive failure messages, etc from the value on demand - # as needed, but it intentionally does _not_ expose the `actual_before` - # value. Some usages of the `change` matcher mutate a specific object - # returned by the value proc, which means that failure message snippets, - # etc, which are derived from the `before` value may not be accurate if - # they are lazily computed as needed. We must pre-compute them before - # applying the change in the `expect` block. To ensure that all `change` - # matchers do that properly, we do not expose the `actual_before` value. - # Instead, matchers must pass a block to `perform_change`, which yields - # the `actual_before` value before applying the change. - class ChangeDetails - attr_reader :actual_after - - UNDEFINED = Module.new.freeze - - def initialize(matcher_name, receiver=nil, message=nil, &block) - if receiver && !message - raise( - ArgumentError, - "`change` requires either an object and message " \ - "(`change(obj, :msg)`) or a block (`change { }`). " \ - "You passed an object but no message." - ) - end - - @matcher_name = matcher_name - @receiver = receiver - @message = message - @value_proc = block - # TODO: temporary measure to mute warning of access to an initialized - # instance variable when a deprecated implicit block expectation - # syntax is used. This may be removed once `fail` is used, and the - # matcher never issues this warning. - @actual_after = UNDEFINED - end - - def value_representation - @value_representation ||= - if @message - "`#{message_notation(@receiver, @message)}`" - elsif (value_block_snippet = extract_value_block_snippet) - "`#{value_block_snippet}`" - else - 'result' - end - end - - def perform_change(event_proc) - @actual_before = evaluate_value_proc - @before_hash = @actual_before.hash - yield @actual_before if block_given? - - return false unless Proc === event_proc - event_proc.call - - @actual_after = evaluate_value_proc - @actual_hash = @actual_after.hash - true - end - - def changed? - # Consider it changed if either: - # - # - The before/after values are unequal - # - The before/after values have different hash values - # - # The latter case specifically handles the case when the value proc - # returns the exact same object, but it has been mutated. - # - # Note that it is not sufficient to only check the hashes; it is - # possible for two values to be unequal (and of different classes) - # but to return the same hash value. Also, some objects may change - # their hash after being compared with `==`/`!=`. - @actual_before != @actual_after || @before_hash != @actual_hash - end - - def actual_delta - @actual_after - @actual_before - end - - private - - def evaluate_value_proc - @value_proc ? @value_proc.call : @receiver.__send__(@message) - end - - def message_notation(receiver, message) - case receiver - when Module - "#{receiver}.#{message}" - else - "#{Support.class_of(receiver)}##{message}" - end - end - - if RSpec::Support::RubyFeatures.ripper_supported? - def extract_value_block_snippet - return nil unless @value_proc - Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@value_proc, @matcher_name) - end - else - # :nocov: - def extract_value_block_snippet - nil - end - # :nocov: - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb deleted file mode 100644 index 3a7fb1e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb +++ /dev/null @@ -1,293 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Base class for `and` and `or` compound matchers. - class Compound < BaseMatcher - # @private - attr_reader :matcher_1, :matcher_2, :evaluator - - def initialize(matcher_1, matcher_2) - @matcher_1 = matcher_1 - @matcher_2 = matcher_2 - end - - # @private - def does_not_match?(_actual) - raise NotImplementedError, "`expect(...).not_to matcher.#{conjunction} matcher` " \ - "is not supported, since it creates a bit of an ambiguity. Instead, define negated versions " \ - "of whatever matchers you wish to negate with `RSpec::Matchers.define_negated_matcher` and " \ - "use `expect(...).to matcher.#{conjunction} matcher`." - end - - # @api private - # @return [String] - def description - "#{matcher_1.description} #{conjunction} #{matcher_2.description}" - end - - # @api private - def supports_block_expectations? - matcher_supports_block_expectations?(matcher_1) && - matcher_supports_block_expectations?(matcher_2) - end - - # @api private - def supports_value_expectations? - matcher_supports_value_expectations?(matcher_1) && - matcher_supports_value_expectations?(matcher_2) - end - - # @api private - def expects_call_stack_jump? - NestedEvaluator.matcher_expects_call_stack_jump?(matcher_1) || - NestedEvaluator.matcher_expects_call_stack_jump?(matcher_2) - end - - # @api private - # @return [Boolean] - def diffable? - matcher_is_diffable?(matcher_1) || matcher_is_diffable?(matcher_2) - end - - # @api private - # @return [RSpec::Matchers::MultiMatcherDiff] - def expected - return nil unless evaluator - ::RSpec::Matchers::MultiMatcherDiff.for_many_matchers(diffable_matcher_list) - end - - protected - - def diffable_matcher_list - list = [] - list.concat(diffable_matcher_list_for(matcher_1)) unless matcher_1_matches? - list.concat(diffable_matcher_list_for(matcher_2)) unless matcher_2_matches? - list - end - - private - - def initialize_copy(other) - @matcher_1 = @matcher_1.clone - @matcher_2 = @matcher_2.clone - super - end - - def match(_expected, actual) - evaluator_klass = if supports_block_expectations? && Proc === actual - NestedEvaluator - elsif supports_value_expectations? - SequentialEvaluator - else - # Can't raise an ArgumentError in this context, as it's rescued - raise "Block and value matchers can't be combined in a compound expectation (#{matcher_1.description}, #{matcher_2.description})" - end - - @evaluator = evaluator_klass.new(actual, matcher_1, matcher_2) - end - - def indent_multiline_message(message) - message.lines.map do |line| - line =~ /\S/ ? ' ' + line : line - end.join - end - - def compound_failure_message - "#{indent_multiline_message(matcher_1.failure_message.sub(/\n+\z/, ''))}" \ - "\n\n...#{conjunction}:" \ - "\n\n#{indent_multiline_message(matcher_2.failure_message.sub(/\A\n+/, ''))}" - end - - def matcher_1_matches? - evaluator.matcher_matches?(matcher_1) - end - - def matcher_2_matches? - evaluator.matcher_matches?(matcher_2) - end - - def matcher_supports_block_expectations?(matcher) - matcher.supports_block_expectations? - rescue NoMethodError - false - end - - def matcher_supports_value_expectations?(matcher) - matcher.supports_value_expectations? - rescue NoMethodError - true - end - - def matcher_is_diffable?(matcher) - matcher.diffable? - rescue NoMethodError - false - end - - def diffable_matcher_list_for(matcher) - return [] unless matcher_is_diffable?(matcher) - return matcher.diffable_matcher_list if Compound === matcher - [matcher] - end - - # For value expectations, we can evaluate the matchers sequentially. - class SequentialEvaluator - def initialize(actual, *) - @actual = actual - end - - def matcher_matches?(matcher) - matcher.matches?(@actual) - end - end - - # Normally, we evaluate the matching sequentially. For an expression like - # `expect(x).to foo.and bar`, this becomes: - # - # expect(x).to foo - # expect(x).to bar - # - # For block expectations, we need to nest them instead, so that - # `expect { x }.to foo.and bar` becomes: - # - # expect { - # expect { x }.to foo - # }.to bar - # - # This is necessary so that the `expect` block is only executed once. - class NestedEvaluator - def initialize(actual, matcher_1, matcher_2) - @actual = actual - @matcher_1 = matcher_1 - @matcher_2 = matcher_2 - @match_results = {} - - inner, outer = order_block_matchers - - @match_results[outer] = outer.matches?(Proc.new do |*args| - @match_results[inner] = inner.matches?(inner_matcher_block(args)) - end) - end - - def matcher_matches?(matcher) - @match_results.fetch(matcher) do - raise ArgumentError, "Your #{matcher.description} has no match " \ - "results, this can occur when an unexpected call stack or " \ - "local jump occurs. Perhaps one of your matchers needs to " \ - "declare `expects_call_stack_jump?` as `true`?" - end - end - - private - - # Some block matchers (such as `yield_xyz`) pass args to the `expect` block. - # When such a matcher is used as the outer matcher, we need to forward the - # the args on to the `expect` block. - def inner_matcher_block(outer_args) - return @actual if outer_args.empty? - - Proc.new do |*inner_args| - unless inner_args.empty? - raise ArgumentError, "(#{@matcher_1.description}) and " \ - "(#{@matcher_2.description}) cannot be combined in a compound expectation " \ - "since both matchers pass arguments to the block." - end - - @actual.call(*outer_args) - end - end - - # For a matcher like `raise_error` or `throw_symbol`, where the block will jump - # up the call stack, we need to order things so that it is the inner matcher. - # For example, we need it to be this: - # - # expect { - # expect { - # x += 1 - # raise "boom" - # }.to raise_error("boom") - # }.to change { x }.by(1) - # - # ...rather than: - # - # expect { - # expect { - # x += 1 - # raise "boom" - # }.to change { x }.by(1) - # }.to raise_error("boom") - # - # In the latter case, the after-block logic in the `change` matcher would never - # get executed because the `raise "boom"` line would jump to the `rescue` in the - # `raise_error` logic, so only the former case will work properly. - # - # This method figures out which matcher should be the inner matcher and which - # should be the outer matcher. - def order_block_matchers - return @matcher_1, @matcher_2 unless self.class.matcher_expects_call_stack_jump?(@matcher_2) - return @matcher_2, @matcher_1 unless self.class.matcher_expects_call_stack_jump?(@matcher_1) - - raise ArgumentError, "(#{@matcher_1.description}) and " \ - "(#{@matcher_2.description}) cannot be combined in a compound expectation " \ - "because they both expect a call stack jump." - end - - def self.matcher_expects_call_stack_jump?(matcher) - matcher.expects_call_stack_jump? - rescue NoMethodError - false - end - end - - # @api public - # Matcher used to represent a compound `and` expectation. - class And < self - # @api private - # @return [String] - def failure_message - if matcher_1_matches? - matcher_2.failure_message - elsif matcher_2_matches? - matcher_1.failure_message - else - compound_failure_message - end - end - - private - - def match(*) - super - matcher_1_matches? && matcher_2_matches? - end - - def conjunction - "and" - end - end - - # @api public - # Matcher used to represent a compound `or` expectation. - class Or < self - # @api private - # @return [String] - def failure_message - compound_failure_message - end - - private - - def match(*) - super - matcher_1_matches? || matcher_2_matches? - end - - def conjunction - "or" - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb deleted file mode 100644 index f80572c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb +++ /dev/null @@ -1,312 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # rubocop:disable Metrics/ClassLength - # @api private - # Provides the implementation for `contain_exactly` and `match_array`. - # Not intended to be instantiated directly. - class ContainExactly < BaseMatcher - # @api private - # @return [String] - def failure_message - if Array === actual - generate_failure_message - else - "expected a collection that can be converted to an array with " \ - "`#to_ary` or `#to_a`, but got #{actual_formatted}" - end - end - - # @api private - # @return [String] - def failure_message_when_negated - list = EnglishPhrasing.list(surface_descriptions_in(expected)) - "expected #{actual_formatted} not to contain exactly#{list}" - end - - # @api private - # @return [String] - def description - list = EnglishPhrasing.list(surface_descriptions_in(expected)) - "contain exactly#{list}" - end - - def matches?(actual) - @pairings_maximizer = nil - @best_solution = nil - @extra_items = nil - @missing_items = nil - super(actual) - end - - private - - def generate_failure_message - message = expected_collection_line - message += actual_collection_line - message += missing_elements_line unless missing_items.empty? - message += extra_elements_line unless extra_items.empty? - message - end - - def expected_collection_line - message_line('expected collection contained', expected, true) - end - - def actual_collection_line - message_line('actual collection contained', actual) - end - - def missing_elements_line - message_line('the missing elements were', missing_items, true) - end - - def extra_elements_line - message_line('the extra elements were', extra_items) - end - - def describe_collection(collection, surface_descriptions=false) - if surface_descriptions - "#{description_of(safe_sort(surface_descriptions_in collection))}\n" - else - "#{description_of(safe_sort(collection))}\n" - end - end - - def message_line(prefix, collection, surface_descriptions=false) - "%-32s%s" % [prefix + ':', - describe_collection(collection, surface_descriptions)] - end - - def match(_expected, _actual) - return false unless convert_actual_to_an_array - match_when_sorted? || (extra_items.empty? && missing_items.empty?) - end - - # This cannot always work (e.g. when dealing with unsortable items, - # or matchers as expected items), but it's practically free compared to - # the slowness of the full matching algorithm, and in common cases this - # works, so it's worth a try. - def match_when_sorted? - values_match?(safe_sort(expected), safe_sort(actual)) - end - - def convert_actual_to_an_array - if actual.respond_to?(:to_ary) - @actual = actual.to_ary - elsif actual.respond_to?(:to_a) && !to_a_disallowed?(actual) - @actual = actual.to_a - else - false - end - end - - def safe_sort(array) - array.sort - rescue Support::AllExceptionsExceptOnesWeMustNotRescue - array - end - - if RUBY_VERSION == "1.8.7" - # :nocov: - def to_a_disallowed?(object) - case object - when NilClass, String then true - else Kernel == RSpec::Support.method_handle_for(object, :to_a).owner - end - end - # :nocov: - else - def to_a_disallowed?(object) - NilClass === object - end - end - - def missing_items - @missing_items ||= best_solution.unmatched_expected_indexes.map do |index| - expected[index] - end - end - - def extra_items - @extra_items ||= best_solution.unmatched_actual_indexes.map do |index| - actual[index] - end - end - - def best_solution - @best_solution ||= pairings_maximizer.find_best_solution - end - - def pairings_maximizer - @pairings_maximizer ||= begin - expected_matches = Hash[Array.new(expected.size) { |i| [i, []] }] - actual_matches = Hash[Array.new(actual.size) { |i| [i, []] }] - - expected.each_with_index do |e, ei| - actual.each_with_index do |a, ai| - next unless values_match?(e, a) - - expected_matches[ei] << ai - actual_matches[ai] << ei - end - end - - PairingsMaximizer.new(expected_matches, actual_matches) - end - end - - # Once we started supporting composing matchers, the algorithm for this matcher got - # much more complicated. Consider this expression: - # - # expect(["fool", "food"]).to contain_exactly(/foo/, /fool/) - # - # This should pass (because we can pair /fool/ with "fool" and /foo/ with "food"), but - # the original algorithm used by this matcher would pair the first elements it could - # (/foo/ with "fool"), which would leave /fool/ and "food" unmatched. When we have - # an expected element which is a matcher that matches a superset of actual items - # compared to another expected element matcher, we need to consider every possible pairing. - # - # This class is designed to maximize the number of actual/expected pairings -- or, - # conversely, to minimize the number of unpaired items. It's essentially a brute - # force solution, but with a few heuristics applied to reduce the size of the - # problem space: - # - # * Any items which match none of the items in the other list are immediately - # placed into the `unmatched_expected_indexes` or `unmatched_actual_indexes` array. - # The extra items and missing items in the matcher failure message are derived - # from these arrays. - # * Any items which reciprocally match only each other are paired up and not - # considered further. - # - # What's left is only the items which match multiple items from the other list - # (or vice versa). From here, it performs a brute-force depth-first search, - # looking for a solution which pairs all elements in both lists, or, barring that, - # that produces the fewest unmatched items. - # - # @private - class PairingsMaximizer - # @private - Solution = Struct.new(:unmatched_expected_indexes, :unmatched_actual_indexes, - :indeterminate_expected_indexes, :indeterminate_actual_indexes) do - def worse_than?(other) - unmatched_item_count > other.unmatched_item_count - end - - def candidate? - indeterminate_expected_indexes.empty? && - indeterminate_actual_indexes.empty? - end - - def ideal? - candidate? && ( - unmatched_expected_indexes.empty? || - unmatched_actual_indexes.empty? - ) - end - - def unmatched_item_count - unmatched_expected_indexes.count + unmatched_actual_indexes.count - end - - def +(derived_candidate_solution) - self.class.new( - unmatched_expected_indexes + derived_candidate_solution.unmatched_expected_indexes, - unmatched_actual_indexes + derived_candidate_solution.unmatched_actual_indexes, - # Ignore the indeterminate indexes: by the time we get here, - # we've dealt with all indeterminates. - [], [] - ) - end - end - - attr_reader :expected_to_actual_matched_indexes, :actual_to_expected_matched_indexes, :solution - - def initialize(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes) - @expected_to_actual_matched_indexes = expected_to_actual_matched_indexes - @actual_to_expected_matched_indexes = actual_to_expected_matched_indexes - - unmatched_expected_indexes, indeterminate_expected_indexes = - categorize_indexes(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes) - - unmatched_actual_indexes, indeterminate_actual_indexes = - categorize_indexes(actual_to_expected_matched_indexes, expected_to_actual_matched_indexes) - - @solution = Solution.new(unmatched_expected_indexes, unmatched_actual_indexes, - indeterminate_expected_indexes, indeterminate_actual_indexes) - end - - def find_best_solution - return solution if solution.candidate? - best_solution_so_far = NullSolution - - expected_index = solution.indeterminate_expected_indexes.first - actuals = expected_to_actual_matched_indexes[expected_index] - - actuals.each do |actual_index| - solution = best_solution_for_pairing(expected_index, actual_index) - return solution if solution.ideal? - best_solution_so_far = solution if best_solution_so_far.worse_than?(solution) - end - - best_solution_so_far - end - - private - - # @private - # Starting solution that is worse than any other real solution. - NullSolution = Class.new do - def self.worse_than?(_other) - true - end - end - - def categorize_indexes(indexes_to_categorize, other_indexes) - unmatched = [] - indeterminate = [] - - indexes_to_categorize.each_pair do |index, matches| - if matches.empty? - unmatched << index - elsif !reciprocal_single_match?(matches, index, other_indexes) - indeterminate << index - end - end - - return unmatched, indeterminate - end - - def reciprocal_single_match?(matches, index, other_list) - return false unless matches.one? - other_list[matches.first] == [index] - end - - def best_solution_for_pairing(expected_index, actual_index) - modified_expecteds = apply_pairing_to( - solution.indeterminate_expected_indexes, - expected_to_actual_matched_indexes, actual_index) - - modified_expecteds.delete(expected_index) - - modified_actuals = apply_pairing_to( - solution.indeterminate_actual_indexes, - actual_to_expected_matched_indexes, expected_index) - - modified_actuals.delete(actual_index) - - solution + self.class.new(modified_expecteds, modified_actuals).find_best_solution - end - - def apply_pairing_to(indeterminates, original_matches, other_list_index) - indeterminates.inject({}) do |accum, index| - accum[index] = original_matches[index] - [other_list_index] - accum - end - end - end - end - # rubocop:enable Metrics/ClassLength - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb deleted file mode 100644 index aa91310..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb +++ /dev/null @@ -1,171 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Abstract class to implement `once`, `at_least` and other - # count constraints. - module CountExpectation - # @api public - # Specifies that the method is expected to match once. - def once - exactly(1) - end - - # @api public - # Specifies that the method is expected to match twice. - def twice - exactly(2) - end - - # @api public - # Specifies that the method is expected to match thrice. - def thrice - exactly(3) - end - - # @api public - # Specifies that the method is expected to match the given number of times. - def exactly(number) - set_expected_count(:==, number) - self - end - - # @api public - # Specifies the maximum number of times the method is expected to match - def at_most(number) - set_expected_count(:<=, number) - self - end - - # @api public - # Specifies the minimum number of times the method is expected to match - def at_least(number) - set_expected_count(:>=, number) - self - end - - # @api public - # No-op. Provides syntactic sugar. - def times - self - end - - protected - # @api private - attr_reader :count_expectation_type, :expected_count - - private - - if RUBY_VERSION.to_f > 1.8 - def cover?(count, number) - count.cover?(number) - end - else - # :nocov: - def cover?(count, number) - number >= count.first && number <= count.last - end - # :nocov: - end - - def expected_count_matches?(actual_count) - @actual_count = actual_count - return @actual_count > 0 unless count_expectation_type - return cover?(expected_count, actual_count) if count_expectation_type == :<=> - - @actual_count.__send__(count_expectation_type, expected_count) - end - - def has_expected_count? - !!count_expectation_type - end - - def set_expected_count(relativity, n) - raise_unsupported_count_expectation if unsupported_count_expectation?(relativity) - - count = count_constraint_to_number(n) - - if count_expectation_type == :<= && relativity == :>= - raise_impossible_count_expectation(count) if count > expected_count - @count_expectation_type = :<=> - @expected_count = count..expected_count - elsif count_expectation_type == :>= && relativity == :<= - raise_impossible_count_expectation(count) if count < expected_count - @count_expectation_type = :<=> - @expected_count = expected_count..count - else - @count_expectation_type = relativity - @expected_count = count - end - end - - def raise_impossible_count_expectation(count) - text = - case count_expectation_type - when :<= then "at_least(#{count}).at_most(#{expected_count})" - when :>= then "at_least(#{expected_count}).at_most(#{count})" - end - raise ArgumentError, "The constraint #{text} is not possible" - end - - def raise_unsupported_count_expectation - text = - case count_expectation_type - when :<= then "at_least" - when :>= then "at_most" - when :<=> then "at_least/at_most combination" - else "count" - end - raise ArgumentError, "Multiple #{text} constraints are not supported" - end - - def count_constraint_to_number(n) - case n - when Numeric then n - when :once then 1 - when :twice then 2 - when :thrice then 3 - else - raise ArgumentError, "Expected a number, :once, :twice or :thrice," \ - " but got #{n}" - end - end - - def unsupported_count_expectation?(relativity) - return true if count_expectation_type == :== - return true if count_expectation_type == :<=> - (count_expectation_type == :<= && relativity == :<=) || - (count_expectation_type == :>= && relativity == :>=) - end - - def count_expectation_description - "#{human_readable_expectation_type}#{human_readable_count(expected_count)}" - end - - def count_failure_reason(action) - "#{count_expectation_description}" \ - " but #{action}#{human_readable_count(@actual_count)}" - end - - def human_readable_expectation_type - case count_expectation_type - when :<= then ' at most' - when :>= then ' at least' - when :<=> then ' between' - else '' - end - end - - def human_readable_count(count) - case count - when Range then " #{count.first} and #{count.last} times" - when nil then '' - when 1 then ' once' - when 2 then ' twice' - else " #{count} times" - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb deleted file mode 100644 index 47474a2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb +++ /dev/null @@ -1,24 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `cover`. - # Not intended to be instantiated directly. - class Cover < BaseMatcher - def initialize(*expected) - @expected = expected - end - - def matches?(range) - @actual = range - @expected.all? { |e| range.cover?(e) } - end - - def does_not_match?(range) - @actual = range - expected.none? { |e| range.cover?(e) } - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb deleted file mode 100644 index 08ed656..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb +++ /dev/null @@ -1,44 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `eq`. - # Not intended to be instantiated directly. - class Eq < BaseMatcher - # @api private - # @return [String] - def failure_message - if string_encoding_differs? - "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using ==)\n" - else - "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n" - end - end - - # @api private - # @return [String] - def failure_message_when_negated - "\nexpected: value != #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n" - end - - # @api private - # @return [String] - def description - "eq #{expected_formatted}" - end - - # @api private - # @return [Boolean] - def diffable? - true - end - - private - - def match(expected, actual) - actual == expected - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb deleted file mode 100644 index 32560df..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb +++ /dev/null @@ -1,38 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `eql`. - # Not intended to be instantiated directly. - class Eql < BaseMatcher - # @api private - # @return [String] - def failure_message - if string_encoding_differs? - "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using eql?)\n" - else - "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n" - end - end - - # @api private - # @return [String] - def failure_message_when_negated - "\nexpected: value != #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n" - end - - # @api private - # @return [Boolean] - def diffable? - true - end - - private - - def match(expected, actual) - actual.eql? expected - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb deleted file mode 100644 index bbab3ed..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb +++ /dev/null @@ -1,81 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `equal`. - # Not intended to be instantiated directly. - class Equal < BaseMatcher - # @api private - # @return [String] - def failure_message - if expected_is_a_literal_singleton? - simple_failure_message - else - detailed_failure_message - end - end - - # @api private - # @return [String] - def failure_message_when_negated - <<-MESSAGE - -expected not #{inspect_object(actual)} - got #{inspect_object(expected)} - -Compared using equal?, which compares object identity. - -MESSAGE - end - - # @api private - # @return [Boolean] - def diffable? - !expected_is_a_literal_singleton? - end - - private - - def match(expected, actual) - actual.equal? expected - end - - LITERAL_SINGLETONS = [true, false, nil] - - def expected_is_a_literal_singleton? - LITERAL_SINGLETONS.include?(expected) - end - - def actual_inspected - if LITERAL_SINGLETONS.include?(actual) - actual_formatted - else - inspect_object(actual) - end - end - - def simple_failure_message - "\nexpected #{expected_formatted}\n got #{actual_inspected}\n" - end - - def detailed_failure_message - <<-MESSAGE - -expected #{inspect_object(expected)} - got #{inspect_object(actual)} - -Compared using equal?, which compares object identity, -but expected and actual are not the same object. Use -`expect(actual).to eq(expected)` if you don't care about -object identity in this example. - -MESSAGE - end - - def inspect_object(o) - "#<#{o.class}:#{o.object_id}> => #{RSpec::Support::ObjectFormatter.format(o)}" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb deleted file mode 100644 index 438625d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb +++ /dev/null @@ -1,90 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `exist`. - # Not intended to be instantiated directly. - class Exist < BaseMatcher - def initialize(*expected) - @expected = expected - end - - # @api private - # @return [Boolean] - def matches?(actual) - @actual = actual - @test = ExistenceTest.new @actual, @expected - @test.valid_test? && @test.actual_exists? - end - - # @api private - # @return [Boolean] - def does_not_match?(actual) - @actual = actual - @test = ExistenceTest.new @actual, @expected - @test.valid_test? && !@test.actual_exists? - end - - # @api private - # @return [String] - def failure_message - "expected #{actual_formatted} to exist#{@test.validity_message}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected #{actual_formatted} not to exist#{@test.validity_message}" - end - - # @api private - # Simple class for memoizing actual/expected for this matcher - # and examining the match - class ExistenceTest < Struct.new(:actual, :expected) - # @api private - # @return [Boolean] - def valid_test? - uniq_truthy_values.size == 1 - end - - # @api private - # @return [Boolean] - def actual_exists? - existence_values.first - end - - # @api private - # @return [String] - def validity_message - case uniq_truthy_values.size - when 0 - " but it does not respond to either `exist?` or `exists?`" - when 2 - " but `exist?` and `exists?` returned different values:\n\n"\ - " exist?: #{existence_values.first}\n"\ - "exists?: #{existence_values.last}" - end - end - - private - - def uniq_truthy_values - @uniq_truthy_values ||= existence_values.map { |v| !!v }.uniq - end - - def existence_values - @existence_values ||= predicates.map { |p| actual.__send__(p, *expected) } - end - - def predicates - @predicates ||= [:exist?, :exists?].select { |p| actual.respond_to?(p) && !deprecated(p, actual) } - end - - def deprecated(predicate, actual) - predicate == :exists? && (File == actual || FileTest == actual || Dir == actual) - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb deleted file mode 100644 index 0f4e7e4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb +++ /dev/null @@ -1,194 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for dynamic predicate matchers. - # Not intended to be inherited directly. - class DynamicPredicate < BaseMatcher - include BeHelpers - - def initialize(method_name, *args, &block) - @method_name, @args, @block = method_name, args, block - end - ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true) - - # @private - def matches?(actual, &block) - @actual = actual - @block ||= block - predicate_accessible? && predicate_matches? - end - - # @private - def does_not_match?(actual, &block) - @actual = actual - @block ||= block - predicate_accessible? && predicate_matches?(false) - end - - # @api private - # @return [String] - def failure_message - failure_message_expecting(true) - end - - # @api private - # @return [String] - def failure_message_when_negated - failure_message_expecting(false) - end - - # @api private - # @return [String] - def description - "#{method_description}#{args_to_sentence}" - end - - private - - # Catch a semi-frequent typo - if you have strict_predicate_matchers disabled and - # expect(spy).to have_receieveddd(:foo) it would be evergreen - the dynamic matcher - # queries `has_receiveddd?`, the spy _fakes_ the method, returning its (truthy) self. - if defined?(RSpec::Mocks::Double) - def really_responds_to?(method) - if RSpec::Mocks::Double === @actual - @actual.respond_to?(method) && methods_include?(method) - else - @actual.respond_to?(method) - end - end - else - # :nocov: - def really_responds_to?(method) - @actual.respond_to?(method) - end - # :nocov: - end - - def predicate_accessible? - really_responds_to?(predicate) - end - - # support 1.8.7, evaluate once at load time for performance - if String === methods.first - # :nocov: - def private_predicate? - @actual.private_methods.include? predicate.to_s - end - - def methods_include?(method) - @actual.methods.include?(method.to_s) - end - # :nocov: - else - def private_predicate? - @actual.private_methods.include? predicate - end - - def methods_include?(method) - @actual.methods.include?(method) - end - end - - def predicate_result - @predicate_result = actual.__send__(predicate_method_name, *@args, &@block) - end - - def predicate_method_name - predicate - end - - def predicate_matches?(value=true) - if RSpec::Expectations.configuration.strict_predicate_matchers? - value == predicate_result - else - value == !!predicate_result - end - end - - def root - # On 1.9, there appears to be a bug where String#match can return `false` - # rather than the match data object. Changing to Regex#match appears to - # work around this bug. For an example of this bug, see: - # https://travis-ci.org/rspec/rspec-expectations/jobs/27549635 - self.class::REGEX.match(@method_name.to_s).captures.first - end - - def method_description - EnglishPhrasing.split_words(@method_name) - end - - def failure_message_expecting(value) - validity_message || - "expected `#{actual_formatted}.#{predicate}#{args_to_s}` to #{expectation_of value}, got #{description_of @predicate_result}" - end - - def expectation_of(value) - if RSpec::Expectations.configuration.strict_predicate_matchers? - "return #{value}" - elsif value - "be truthy" - else - "be falsey" - end - end - - def validity_message - return nil if predicate_accessible? - - "expected #{actual_formatted} to respond to `#{predicate}`#{failure_to_respond_explanation}" - end - - def failure_to_respond_explanation - if private_predicate? - " but `#{predicate}` is a private method" - end - end - end - - # @api private - # Provides the implementation for `has_`. - # Not intended to be instantiated directly. - class Has < DynamicPredicate - # :nodoc: - REGEX = Matchers::HAS_REGEX - private - def predicate - @predicate ||= :"has_#{root}?" - end - end - - # @api private - # Provides the implementation of `be_`. - # Not intended to be instantiated directly. - class BePredicate < DynamicPredicate - # :nodoc: - REGEX = Matchers::BE_PREDICATE_REGEX - private - def predicate - @predicate ||= :"#{root}?" - end - - def predicate_method_name - actual.respond_to?(predicate) ? predicate : present_tense_predicate - end - - def failure_to_respond_explanation - super || if predicate == :true? - " or perhaps you meant `be true` or `be_truthy`" - elsif predicate == :false? - " or perhaps you meant `be false` or `be_falsey`" - end - end - - def predicate_accessible? - super || really_responds_to?(present_tense_predicate) - end - - def present_tense_predicate - :"#{root}s?" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb deleted file mode 100644 index 89be3f2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb +++ /dev/null @@ -1,114 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `have_attributes`. - # Not intended to be instantiated directly. - class HaveAttributes < BaseMatcher - # @private - attr_reader :respond_to_failed - - def initialize(expected) - @expected = expected - @values = {} - @respond_to_failed = false - @negated = false - end - - # @private - def actual - @values - end - - # @api private - # @return [Boolean] - def matches?(actual) - @actual = actual - @negated = false - return false unless respond_to_attributes? - perform_match(:all?) - end - - # @api private - # @return [Boolean] - def does_not_match?(actual) - @actual = actual - @negated = true - return false unless respond_to_attributes? - perform_match(:none?) - end - - # @api private - # @return [String] - def description - described_items = surface_descriptions_in(expected) - improve_hash_formatting "have attributes #{RSpec::Support::ObjectFormatter.format(described_items)}" - end - - # @api private - # @return [Boolean] - def diffable? - !@respond_to_failed && !@negated - end - - # @api private - # @return [String] - def failure_message - respond_to_failure_message_or do - "expected #{actual_formatted} to #{description} but had attributes #{ formatted_values }" - end - end - - # @api private - # @return [String] - def failure_message_when_negated - respond_to_failure_message_or { "expected #{actual_formatted} not to #{description}" } - end - - private - - def cache_all_values - @values = {} - expected.each do |attribute_key, _attribute_value| - actual_value = @actual.__send__(attribute_key) - @values[attribute_key] = actual_value - end - end - - def perform_match(predicate) - cache_all_values - expected.__send__(predicate) do |attribute_key, attribute_value| - actual_has_attribute?(attribute_key, attribute_value) - end - end - - def actual_has_attribute?(attribute_key, attribute_value) - values_match?(attribute_value, @values.fetch(attribute_key)) - end - - def respond_to_attributes? - matches = respond_to_matcher.matches?(@actual) - @respond_to_failed = !matches - matches - end - - def respond_to_matcher - @respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments.tap { |m| m.ignoring_method_signature_failure! } - end - - def respond_to_failure_message_or - if respond_to_failed - respond_to_matcher.failure_message - else - improve_hash_formatting(yield) - end - end - - def formatted_values - values = RSpec::Support::ObjectFormatter.format(@values) - improve_hash_formatting(values) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb deleted file mode 100644 index 3fedee3..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb +++ /dev/null @@ -1,218 +0,0 @@ -require 'rspec/matchers/built_in/count_expectation' - -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `include`. - # Not intended to be instantiated directly. - class Include < BaseMatcher # rubocop:disable Metrics/ClassLength - include CountExpectation - # @private - attr_reader :expecteds - - # @api private - def initialize(*expecteds) - raise(ArgumentError, 'include() is not supported, please supply an argument') if expecteds.empty? - @expecteds = expecteds - end - - # @api private - # @return [Boolean] - def matches?(actual) - check_actual?(actual) && - if check_expected_count? - expected_count_matches?(count_inclusions) - else - perform_match { |v| v } - end - end - - # @api private - # @return [Boolean] - def does_not_match?(actual) - check_actual?(actual) && - if check_expected_count? - !expected_count_matches?(count_inclusions) - else - perform_match { |v| !v } - end - end - - # @api private - # @return [String] - def description - improve_hash_formatting("include#{readable_list_of(expecteds)}#{count_expectation_description}") - end - - # @api private - # @return [String] - def failure_message - format_failure_message("to") { super } - end - - # @api private - # @return [String] - def failure_message_when_negated - format_failure_message("not to") { super } - end - - # @api private - # @return [Boolean] - def diffable? - !diff_would_wrongly_highlight_matched_item? - end - - # @api private - # @return [Array, Hash] - def expected - if expecteds.one? && Hash === expecteds.first - expecteds.first - else - expecteds - end - end - - private - - def check_actual?(actual) - actual = actual.to_hash if convert_to_hash?(actual) - @actual = actual - @actual.respond_to?(:include?) - end - - def check_expected_count? - case - when !has_expected_count? - return false - when expecteds.size != 1 - raise NotImplementedError, 'Count constraint supported only when testing for a single value being included' - when actual.is_a?(Hash) - raise NotImplementedError, 'Count constraint on hash keys not implemented' - end - true - end - - def format_failure_message(preposition) - msg = if actual.respond_to?(:include?) - "expected #{description_of @actual} #{preposition}" \ - " include#{readable_list_of @divergent_items}" \ - "#{count_failure_reason('it is included') if has_expected_count?}" - else - "#{yield}, but it does not respond to `include?`" - end - improve_hash_formatting(msg) - end - - def readable_list_of(items) - described_items = surface_descriptions_in(items) - if described_items.all? { |item| item.is_a?(Hash) } - " #{described_items.inject(:merge).inspect}" - else - EnglishPhrasing.list(described_items) - end - end - - def perform_match(&block) - @divergent_items = excluded_from_actual(&block) - @divergent_items.empty? - end - - def excluded_from_actual - return [] unless @actual.respond_to?(:include?) - - expecteds.inject([]) do |memo, expected_item| - if comparing_hash_to_a_subset?(expected_item) - expected_item.each do |(key, value)| - memo << { key => value } unless yield actual_hash_includes?(key, value) - end - elsif comparing_hash_keys?(expected_item) - memo << expected_item unless yield actual_hash_has_key?(expected_item) - else - memo << expected_item unless yield actual_collection_includes?(expected_item) - end - memo - end - end - - def comparing_hash_to_a_subset?(expected_item) - actual.is_a?(Hash) && expected_item.is_a?(Hash) - end - - def actual_hash_includes?(expected_key, expected_value) - actual_value = - actual.fetch(expected_key) do - actual.find(Proc.new { return false }) { |actual_key, _| values_match?(expected_key, actual_key) }[1] - end - values_match?(expected_value, actual_value) - end - - def comparing_hash_keys?(expected_item) - actual.is_a?(Hash) && !expected_item.is_a?(Hash) - end - - def actual_hash_has_key?(expected_key) - # We check `key?` first for perf: - # `key?` is O(1), but `any?` is O(N). - - has_exact_key = - begin - actual.key?(expected_key) - rescue - false - end - - has_exact_key || actual.keys.any? { |key| values_match?(expected_key, key) } - end - - def actual_collection_includes?(expected_item) - return actual.scan(expected_item).size > 0 if Regexp === expected_item && String === actual - return true if actual.include?(expected_item) - - # String lacks an `any?` method... - return false unless actual.respond_to?(:any?) - - actual.any? { |value| values_match?(expected_item, value) } - end - - if RUBY_VERSION < '1.9' - # :nocov: - def count_enumerable(expected_item) - actual.select { |value| values_match?(expected_item, value) }.size - end - # :nocov: - else - def count_enumerable(expected_item) - actual.count { |value| values_match?(expected_item, value) } - end - end - - def count_inclusions - @divergent_items = expected - case actual - when String - actual.scan(expected.first).length - when Enumerable - count_enumerable(Hash === expected ? expected : expected.first) - else - raise NotImplementedError, 'Count constraints are implemented for Enumerable and String values only' - end - end - - def diff_would_wrongly_highlight_matched_item? - return false unless actual.is_a?(String) && expected.is_a?(Array) - return false if Regexp === expecteds.first - - lines = actual.split("\n") - expected.any? do |str| - actual.include?(str) && lines.none? { |line| line == str } - end - end - - def convert_to_hash?(obj) - !obj.respond_to?(:include?) && obj.respond_to?(:to_hash) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb deleted file mode 100644 index a822f76..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb +++ /dev/null @@ -1,120 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `match`. - # Not intended to be instantiated directly. - class Match < BaseMatcher - def initialize(expected) - super(expected) - - @expected_captures = nil - end - # @api private - # @return [String] - def description - if @expected_captures && @expected.match(actual) - "match #{surface_descriptions_in(expected).inspect} with captures #{surface_descriptions_in(@expected_captures).inspect}" - else - "match #{surface_descriptions_in(expected).inspect}" - end - end - - # @api private - # @return [Boolean] - def diffable? - true - end - - # Used to specify the captures we match against - # @return [self] - def with_captures(*captures) - @expected_captures = captures - self - end - - # @api private - # @return [String] - def failure_message - if Array === expected && !(actual.respond_to?(:to_a) || actual.respond_to?(:to_ary)) - return "expected a collection that can be converted to an array with " \ - "`#to_ary` or `#to_a`, but got #{actual_formatted}" - end - - super - end - - private - - def match(expected, actual) - return match_captures(expected, actual) if @expected_captures - return true if values_match?(expected, actual) - return false if Array === expected - return false unless can_safely_call_match?(expected, actual) - actual.match(expected) - end - - def can_safely_call_match?(expected, actual) - return false unless actual.respond_to?(:match) - - !(RSpec::Matchers.is_a_matcher?(expected) && - (String === actual || Regexp === actual)) - end - - def match_captures(expected, actual) - match = actual.match(expected) - if match - match = ReliableMatchData.new(match) - if match.names.empty? - values_match?(@expected_captures, match.captures) - else - expected_matcher = @expected_captures.last - values_match?(expected_matcher, Hash[match.names.zip(match.captures)]) || - values_match?(expected_matcher, Hash[match.names.map(&:to_sym).zip(match.captures)]) || - values_match?(@expected_captures, match.captures) - end - else - false - end - end - end - - # @api private - # Used to wrap match data and make it reliable for 1.8.7 - class ReliableMatchData - def initialize(match_data) - @match_data = match_data - end - - if RUBY_VERSION == "1.8.7" - # @api private - # Returns match data names for named captures - # @return Array - # :nocov: - def names - [] - end - # :nocov: - else - # @api private - # Returns match data names for named captures - # @return Array - def names - match_data.names - end - end - - # @api private - # returns an array of captures from the match data - # @return Array - def captures - match_data.captures - end - - protected - - attr_reader :match_data - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb deleted file mode 100644 index 64f8f3b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb +++ /dev/null @@ -1,128 +0,0 @@ -require 'rspec/support' - -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for operator matchers. - # Not intended to be instantiated directly. - # Only available for use with `should`. - class OperatorMatcher - class << self - # @private - def registry - @registry ||= {} - end - - # @private - def register(klass, operator, matcher) - registry[klass] ||= {} - registry[klass][operator] = matcher - end - - # @private - def unregister(klass, operator) - registry[klass] && registry[klass].delete(operator) - end - - # @private - def get(klass, operator) - klass.ancestors.each do |ancestor| - matcher = registry[ancestor] && registry[ancestor][operator] - return matcher if matcher - end - - nil - end - end - - register Enumerable, '=~', BuiltIn::ContainExactly - - def initialize(actual) - @actual = actual - end - - # @private - def self.use_custom_matcher_or_delegate(operator) - define_method(operator) do |expected| - if !has_non_generic_implementation_of?(operator) && (matcher = OperatorMatcher.get(@actual.class, operator)) - @actual.__send__(::RSpec::Matchers.last_expectation_handler.should_method, matcher.new(expected)) - else - eval_match(@actual, operator, expected) - end - end - - negative_operator = operator.sub(/^=/, '!') - if negative_operator != operator && respond_to?(negative_operator) - define_method(negative_operator) do |_expected| - opposite_should = ::RSpec::Matchers.last_expectation_handler.opposite_should_method - raise "RSpec does not support `#{::RSpec::Matchers.last_expectation_handler.should_method} #{negative_operator} expected`. " \ - "Use `#{opposite_should} #{operator} expected` instead." - end - end - end - - ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator| - use_custom_matcher_or_delegate operator - end - - # @private - def fail_with_message(message) - RSpec::Expectations.fail_with(message, @expected, @actual) - end - - # @api private - # @return [String] - def description - "#{@operator} #{RSpec::Support::ObjectFormatter.format(@expected)}" - end - - private - - def has_non_generic_implementation_of?(op) - Support.method_handle_for(@actual, op).owner != ::Kernel - rescue NameError - false - end - - def eval_match(actual, operator, expected) - ::RSpec::Matchers.last_matcher = self - @operator, @expected = operator, expected - __delegate_operator(actual, operator, expected) - end - end - - # @private - # Handles operator matcher for `should`. - class PositiveOperatorMatcher < OperatorMatcher - def __delegate_operator(actual, operator, expected) - if actual.__send__(operator, expected) - true - else - expected_formatted = RSpec::Support::ObjectFormatter.format(expected) - actual_formatted = RSpec::Support::ObjectFormatter.format(actual) - - if ['==', '===', '=~'].include?(operator) - fail_with_message("expected: #{expected_formatted}\n got: #{actual_formatted} (using #{operator})") - else - fail_with_message("expected: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") - end - end - end - end - - # @private - # Handles operator matcher for `should_not`. - class NegativeOperatorMatcher < OperatorMatcher - def __delegate_operator(actual, operator, expected) - return false unless actual.__send__(operator, expected) - - expected_formatted = RSpec::Support::ObjectFormatter.format(expected) - actual_formatted = RSpec::Support::ObjectFormatter.format(actual) - - fail_with_message("expected not: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb deleted file mode 100644 index 8c3cced..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb +++ /dev/null @@ -1,207 +0,0 @@ -require 'stringio' - -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `output`. - # Not intended to be instantiated directly. - class Output < BaseMatcher - def initialize(expected) - @expected = expected - @actual = "" - @block = nil - @stream_capturer = NullCapture - end - - def matches?(block) - @block = block - return false unless Proc === block - @actual = @stream_capturer.capture(block) - @expected ? values_match?(@expected, @actual) : captured? - end - - def does_not_match?(block) - !matches?(block) && Proc === block - end - - # @api public - # Tells the matcher to match against stdout. - # Works only when the main Ruby process prints to stdout - def to_stdout - @stream_capturer = CaptureStdout - self - end - - # @api public - # Tells the matcher to match against stderr. - # Works only when the main Ruby process prints to stderr - def to_stderr - @stream_capturer = CaptureStderr - self - end - - # @api public - # Tells the matcher to match against stdout. - # Works when subprocesses print to stdout as well. - # This is significantly (~30x) slower than `to_stdout` - def to_stdout_from_any_process - @stream_capturer = CaptureStreamToTempfile.new("stdout", $stdout) - self - end - - # @api public - # Tells the matcher to match against stderr. - # Works when subprocesses print to stderr as well. - # This is significantly (~30x) slower than `to_stderr` - def to_stderr_from_any_process - @stream_capturer = CaptureStreamToTempfile.new("stderr", $stderr) - self - end - - # @api private - # @return [String] - def failure_message - "expected block to #{description}, but #{positive_failure_reason}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected block to not #{description}, but #{negative_failure_reason}" - end - - # @api private - # @return [String] - def description - if @expected - "output #{description_of @expected} to #{@stream_capturer.name}" - else - "output to #{@stream_capturer.name}" - end - end - - # @api private - # @return [Boolean] - def diffable? - true - end - - # @api private - # Indicates this matcher matches against a block. - # @return [True] - def supports_block_expectations? - true - end - - # @api private - # Indicates this matcher matches against a block only. - # @return [False] - def supports_value_expectations? - false - end - - private - - def captured? - @actual.length > 0 - end - - def positive_failure_reason - return "was not a block" unless Proc === @block - return "output #{actual_output_description}" if @expected - "did not" - end - - def negative_failure_reason - return "was not a block" unless Proc === @block - "output #{actual_output_description}" - end - - def actual_output_description - return "nothing" unless captured? - actual_formatted - end - end - - # @private - module NullCapture - def self.name - "some stream" - end - - def self.capture(_block) - raise "You must chain `to_stdout` or `to_stderr` off of the `output(...)` matcher." - end - end - - # @private - module CaptureStdout - def self.name - 'stdout' - end - - def self.capture(block) - captured_stream = StringIO.new - - original_stream = $stdout - $stdout = captured_stream - - block.call - - captured_stream.string - ensure - $stdout = original_stream - end - end - - # @private - module CaptureStderr - def self.name - 'stderr' - end - - def self.capture(block) - captured_stream = StringIO.new - - original_stream = $stderr - $stderr = captured_stream - - block.call - - captured_stream.string - ensure - $stderr = original_stream - end - end - - # @private - class CaptureStreamToTempfile < Struct.new(:name, :stream) - def capture(block) - # We delay loading tempfile until it is actually needed because - # we want to minimize stdlibs loaded so that users who use a - # portion of the stdlib can't have passing specs while forgetting - # to load it themselves. `CaptureStreamToTempfile` is rarely used - # and `tempfile` pulls in a bunch of things (delegate, tmpdir, - # thread, fileutils, etc), so it's worth delaying it until this point. - require 'tempfile' - - original_stream = stream.clone - captured_stream = Tempfile.new(name) - - begin - captured_stream.sync = true - stream.reopen(captured_stream) - block.call - captured_stream.rewind - captured_stream.read - ensure - stream.reopen(original_stream) - captured_stream.close - captured_stream.unlink - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb deleted file mode 100644 index bbaaf62..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb +++ /dev/null @@ -1,275 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `raise_error`. - # Not intended to be instantiated directly. - # rubocop:disable Metrics/ClassLength - # rubocop:disable Lint/RescueException - class RaiseError - include Composable - - # Used as a sentinel value to be able to tell when the user did not pass an - # argument. We can't use `nil` for that because we need to warn when `nil` is - # passed in a different way. It's an Object, not a Module, since Module's `===` - # does not evaluate to true when compared to itself. - # - # Note; this _is_ the default value supplied for expected_error_or_message, but - # because there are two method-calls involved, that default is actually supplied - # in the definition of the _matcher_ method, `RSpec::Matchers#raise_error` - UndefinedValue = Object.new.freeze - - def initialize(expected_error_or_message, expected_message, &block) - @block = block - @actual_error = nil - @warn_about_bare_error = UndefinedValue === expected_error_or_message - @warn_about_nil_error = expected_error_or_message.nil? - - case expected_error_or_message - when nil, UndefinedValue - @expected_error = Exception - @expected_message = expected_message - when String, Regexp - @expected_error = Exception - @expected_message = expected_error_or_message - else - @expected_error = expected_error_or_message - @expected_message = expected_message - end - end - - # @api public - # Specifies the expected error message. - def with_message(expected_message) - raise_message_already_set if @expected_message - @warn_about_bare_error = false - @expected_message = expected_message - self - end - - # rubocop:disable Metrics/MethodLength - # @private - def matches?(given_proc, negative_expectation=false, &block) - @given_proc = given_proc - @block ||= block - @raised_expected_error = false - @with_expected_message = false - @eval_block = false - @eval_block_passed = false - - return false unless Proc === given_proc - - begin - given_proc.call - rescue Exception => @actual_error - if values_match?(@expected_error, @actual_error) || - values_match?(@expected_error, actual_error_message) - @raised_expected_error = true - @with_expected_message = verify_message - end - end - - unless negative_expectation - warn_about_bare_error! if warn_about_bare_error? - warn_about_nil_error! if warn_about_nil_error? - eval_block if ready_to_eval_block? - end - - expectation_matched? - end - # rubocop:enable Metrics/MethodLength - - # @private - def does_not_match?(given_proc) - warn_for_negative_false_positives! - !matches?(given_proc, :negative_expectation) && Proc === given_proc - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - # @private - def expects_call_stack_jump? - true - end - - # @api private - # @return [String] - def failure_message - @eval_block ? actual_error_message : "expected #{expected_error}#{given_error}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected no #{expected_error}#{given_error}" - end - - # @api private - # @return [String] - def description - "raise #{expected_error}" - end - - private - - def actual_error_message - return nil unless @actual_error - - @actual_error.respond_to?(:original_message) ? @actual_error.original_message : @actual_error.message - end - - def expectation_matched? - error_and_message_match? && block_matches? - end - - def error_and_message_match? - @raised_expected_error && @with_expected_message - end - - def block_matches? - @eval_block ? @eval_block_passed : true - end - - def ready_to_eval_block? - @raised_expected_error && @with_expected_message && @block - end - - def eval_block - @eval_block = true - begin - @block[@actual_error] - @eval_block_passed = true - rescue Exception => err - @actual_error = err - end - end - - def verify_message - return true if @expected_message.nil? - values_match?(@expected_message, actual_error_message.to_s) - end - - def warn_for_negative_false_positives! - expression = if expecting_specific_exception? && @expected_message - "`expect { }.not_to raise_error(SpecificErrorClass, message)`" - elsif expecting_specific_exception? - "`expect { }.not_to raise_error(SpecificErrorClass)`" - elsif @expected_message - "`expect { }.not_to raise_error(message)`" - elsif @warn_about_nil_error - "`expect { }.not_to raise_error(nil)`" - end - - return unless expression - - warn_about_negative_false_positive! expression - end - - def handle_warning(message) - RSpec::Expectations.configuration.false_positives_handler.call(message) - end - - def warn_about_bare_error? - @warn_about_bare_error && @block.nil? - end - - def warn_about_nil_error? - @warn_about_nil_error - end - - def warn_about_bare_error! - handle_warning("Using the `raise_error` matcher without providing a specific " \ - "error or message risks false positives, since `raise_error` " \ - "will match when Ruby raises a `NoMethodError`, `NameError` or " \ - "`ArgumentError`, potentially allowing the expectation to pass " \ - "without even executing the method you are intending to call. " \ - "#{warning}"\ - "Instead consider providing a specific error class or message. " \ - "This message can be suppressed by setting: " \ - "`RSpec::Expectations.configuration.on_potential_false" \ - "_positives = :nothing`") - end - - def warn_about_nil_error! - handle_warning("Using the `raise_error` matcher with a `nil` error is probably " \ - "unintentional, it risks false positives, since `raise_error` " \ - "will match when Ruby raises a `NoMethodError`, `NameError` or " \ - "`ArgumentError`, potentially allowing the expectation to pass " \ - "without even executing the method you are intending to call. " \ - "#{warning}"\ - "Instead consider providing a specific error class or message. " \ - "This message can be suppressed by setting: " \ - "`RSpec::Expectations.configuration.on_potential_false" \ - "_positives = :nothing`") - end - - def warn_about_negative_false_positive!(expression) - handle_warning("Using #{expression} risks false positives, since literally " \ - "any other error would cause the expectation to pass, " \ - "including those raised by Ruby (e.g. `NoMethodError`, `NameError` " \ - "and `ArgumentError`), meaning the code you are intending to test " \ - "may not even get reached. Instead consider using " \ - "`expect { }.not_to raise_error` or `expect { }.to raise_error" \ - "(DifferentSpecificErrorClass)`. This message can be suppressed by " \ - "setting: `RSpec::Expectations.configuration.on_potential_false" \ - "_positives = :nothing`") - end - - def expected_error - case @expected_message - when nil - if RSpec::Support.is_a_matcher?(@expected_error) - "Exception with #{description_of(@expected_error)}" - else - description_of(@expected_error) - end - when Regexp - "#{@expected_error} with message matching #{description_of(@expected_message)}" - else - "#{@expected_error} with #{description_of(@expected_message)}" - end - end - - def format_backtrace(backtrace) - formatter = Matchers.configuration.backtrace_formatter - formatter.format_backtrace(backtrace) - end - - def given_error - return " but was not given a block" unless Proc === @given_proc - return " but nothing was raised" unless @actual_error - - backtrace = format_backtrace(@actual_error.backtrace) - [ - ", got #{description_of(@actual_error)} with backtrace:", - *backtrace - ].join("\n # ") - end - - def expecting_specific_exception? - @expected_error != Exception - end - - def raise_message_already_set - raise "`expect { }.to raise_error(message).with_message(message)` is not valid. " \ - 'The matcher only allows the expected message to be specified once' - end - - def warning - warning = "Actual error raised was #{description_of(@actual_error)}. " - warning if @actual_error - end - end - # rubocop:enable Lint/RescueException - # rubocop:enable Metrics/ClassLength - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb deleted file mode 100644 index 9adbe04..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb +++ /dev/null @@ -1,200 +0,0 @@ -RSpec::Support.require_rspec_support "method_signature_verifier" - -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `respond_to`. - # Not intended to be instantiated directly. - class RespondTo < BaseMatcher - def initialize(*names) - @names = names - @expected_arity = nil - @expected_keywords = [] - @ignoring_method_signature_failure = false - @unlimited_arguments = nil - @arbitrary_keywords = nil - end - - # @api public - # Specifies the number of expected arguments. - # - # @example - # expect(obj).to respond_to(:message).with(3).arguments - def with(n) - @expected_arity = n - self - end - - # @api public - # Specifies keyword arguments, if any. - # - # @example - # expect(obj).to respond_to(:message).with_keywords(:color, :shape) - # @example with an expected number of arguments - # expect(obj).to respond_to(:message).with(3).arguments.and_keywords(:color, :shape) - def with_keywords(*keywords) - @expected_keywords = keywords - self - end - alias :and_keywords :with_keywords - - # @api public - # Specifies that the method accepts any keyword, i.e. the method has - # a splatted keyword parameter of the form **kw_args. - # - # @example - # expect(obj).to respond_to(:message).with_any_keywords - def with_any_keywords - @arbitrary_keywords = true - self - end - alias :and_any_keywords :with_any_keywords - - # @api public - # Specifies that the number of arguments has no upper limit, i.e. the - # method has a splatted parameter of the form *args. - # - # @example - # expect(obj).to respond_to(:message).with_unlimited_arguments - def with_unlimited_arguments - @unlimited_arguments = true - self - end - alias :and_unlimited_arguments :with_unlimited_arguments - - # @api public - # No-op. Intended to be used as syntactic sugar when using `with`. - # - # @example - # expect(obj).to respond_to(:message).with(3).arguments - def argument - self - end - alias :arguments :argument - - # @private - def matches?(actual) - find_failing_method_names(actual, :reject).empty? - end - - # @private - def does_not_match?(actual) - find_failing_method_names(actual, :select).empty? - end - - # @api private - # @return [String] - def failure_message - "expected #{actual_formatted} to respond to #{@failing_method_names.map { |name| description_of(name) }.join(', ')}#{with_arity}" - end - - # @api private - # @return [String] - def failure_message_when_negated - failure_message.sub(/to respond to/, 'not to respond to') - end - - # @api private - # @return [String] - def description - "respond to #{pp_names}#{with_arity}" - end - - # @api private - # Used by other matchers to suppress a check - def ignoring_method_signature_failure! - @ignoring_method_signature_failure = true - end - - private - - def find_failing_method_names(actual, filter_method) - @actual = actual - @failing_method_names = @names.__send__(filter_method) do |name| - @actual.respond_to?(name) && matches_arity?(actual, name) - end - end - - def matches_arity?(actual, name) - ArityCheck.new(@expected_arity, @expected_keywords, @arbitrary_keywords, @unlimited_arguments).matches?(actual, name) - rescue NameError - return true if @ignoring_method_signature_failure - raise ArgumentError, "The #{matcher_name} matcher requires that " \ - "the actual object define the method(s) in " \ - "order to check arity, but the method " \ - "`#{name}` is not defined. Remove the arity " \ - "check or define the method to continue." - end - - def with_arity - str = ''.dup - str << " with #{with_arity_string}" if @expected_arity - str << " #{str.length == 0 ? 'with' : 'and'} #{with_keywords_string}" if @expected_keywords && @expected_keywords.count > 0 - str << " #{str.length == 0 ? 'with' : 'and'} unlimited arguments" if @unlimited_arguments - str << " #{str.length == 0 ? 'with' : 'and'} any keywords" if @arbitrary_keywords - str - end - - def with_arity_string - "#{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}" - end - - def with_keywords_string - kw_str = case @expected_keywords.count - when 1 - @expected_keywords.first.inspect - when 2 - @expected_keywords.map(&:inspect).join(' and ') - else - "#{@expected_keywords[0...-1].map(&:inspect).join(', ')}, and #{@expected_keywords.last.inspect}" - end - - "keyword#{@expected_keywords.count == 1 ? '' : 's'} #{kw_str}" - end - - def pp_names - @names.length == 1 ? "##{@names.first}" : description_of(@names) - end - - # @private - class ArityCheck - def initialize(expected_arity, expected_keywords, arbitrary_keywords, unlimited_arguments) - expectation = Support::MethodSignatureExpectation.new - - if expected_arity.is_a?(Range) - expectation.min_count = expected_arity.min - expectation.max_count = expected_arity.max - else - expectation.min_count = expected_arity - end - - expectation.keywords = expected_keywords - expectation.expect_unlimited_arguments = unlimited_arguments - expectation.expect_arbitrary_keywords = arbitrary_keywords - @expectation = expectation - end - - def matches?(actual, name) - return true if @expectation.empty? - verifier_for(actual, name).with_expectation(@expectation).valid? - end - - def verifier_for(actual, name) - Support::StrictSignatureVerifier.new(method_signature_for(actual, name)) - end - - def method_signature_for(actual, name) - method_handle = Support.method_handle_for(actual, name) - - if name == :new && method_handle.owner === ::Class && ::Class === actual - Support::MethodSignature.new(actual.instance_method(:initialize)) - else - Support::MethodSignature.new(method_handle) - end - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb deleted file mode 100644 index a50967b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb +++ /dev/null @@ -1,62 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `satisfy`. - # Not intended to be instantiated directly. - class Satisfy < BaseMatcher - def initialize(description=nil, &block) - @description = description - @block = block - end - - # @private - def matches?(actual, &block) - @block = block if block - @actual = actual - @block.call(actual) - end - - # @private - def description - @description ||= "satisfy #{block_representation}" - end - - # @api private - # @return [String] - def failure_message - "expected #{actual_formatted} to #{description}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected #{actual_formatted} not to #{description}" - end - - private - - if RSpec::Support::RubyFeatures.ripper_supported? - def block_representation - if (block_snippet = extract_block_snippet) - "expression `#{block_snippet}`" - else - 'block' - end - end - - def extract_block_snippet - return nil unless @block - Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@block, matcher_name) - end - else - # :nocov: - def block_representation - 'block' - end - # :nocov: - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb deleted file mode 100644 index 81f06c2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb +++ /dev/null @@ -1,94 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Base class for the `end_with` and `start_with` matchers. - # Not intended to be instantiated directly. - class StartOrEndWith < BaseMatcher - def initialize(*expected) - @actual_does_not_have_ordered_elements = false - @expected = expected.length == 1 ? expected.first : expected - end - - # @api private - # @return [String] - def failure_message - super.tap do |msg| - if @actual_does_not_have_ordered_elements - msg << ", but it does not have ordered elements" - elsif !actual.respond_to?(:[]) - msg << ", but it cannot be indexed using #[]" - end - end - end - - # @api private - # @return [String] - def description - return super unless Hash === expected - english_name = EnglishPhrasing.split_words(self.class.matcher_name) - description_of_expected = surface_descriptions_in(expected).inspect - "#{english_name} #{description_of_expected}" - end - - private - - def match(_expected, actual) - return false unless actual.respond_to?(:[]) - - begin - return true if subsets_comparable? && subset_matches? - element_matches? - rescue ArgumentError - @actual_does_not_have_ordered_elements = true - return false - end - end - - def subsets_comparable? - # Structs support the Enumerable interface but don't really have - # the semantics of a subset of a larger set... - return false if Struct === expected - - expected.respond_to?(:length) - end - end - - # For RSpec 3.1, the base class was named `StartAndEndWith`. For SemVer reasons, - # we still provide this constant until 4.0. - # @deprecated Use StartOrEndWith instead. - # @private - StartAndEndWith = StartOrEndWith - - # @api private - # Provides the implementation for `start_with`. - # Not intended to be instantiated directly. - class StartWith < StartOrEndWith - private - - def subset_matches? - values_match?(expected, actual[0, expected.length]) - end - - def element_matches? - values_match?(expected, actual[0]) - end - end - - # @api private - # Provides the implementation for `end_with`. - # Not intended to be instantiated directly. - class EndWith < StartOrEndWith - private - - def subset_matches? - values_match?(expected, actual[-expected.length, expected.length]) - end - - def element_matches? - values_match?(expected, actual[-1]) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb deleted file mode 100644 index e1bb4c5..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb +++ /dev/null @@ -1,138 +0,0 @@ -module RSpec - module Matchers - module BuiltIn - # @api private - # Provides the implementation for `throw_symbol`. - # Not intended to be instantiated directly. - class ThrowSymbol - include Composable - - def initialize(expected_symbol=nil, expected_arg=nil) - @expected_symbol = expected_symbol - @expected_arg = expected_arg - @caught_symbol = @caught_arg = nil - end - - # rubocop:disable Metrics/MethodLength - # @private - def matches?(given_proc) - @block = given_proc - return false unless Proc === given_proc - - begin - if @expected_symbol.nil? - given_proc.call - else - @caught_arg = catch :proc_did_not_throw_anything do - catch @expected_symbol do - given_proc.call - throw :proc_did_not_throw_anything, :nothing_thrown - end - end - - if @caught_arg == :nothing_thrown - @caught_arg = nil - else - @caught_symbol = @expected_symbol - end - end - - # Ruby 1.8 uses NameError with `symbol' - # Ruby 1.9 uses ArgumentError with :symbol - rescue NameError, ArgumentError => e - unless (match_data = e.message.match(/uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/)) - other_exception = e - raise - end - @caught_symbol = match_data.captures[1].to_sym - rescue => other_exception - raise - ensure - # rubocop:disable Lint/EnsureReturn - unless other_exception - if @expected_symbol.nil? - return !!@caught_symbol - else - if @expected_arg.nil? - return @caught_symbol == @expected_symbol - else - return (@caught_symbol == @expected_symbol) && values_match?(@expected_arg, @caught_arg) - end - end - end - # rubocop:enable Lint/EnsureReturn - end - end - # rubocop:enable Metrics/MethodLength - - def does_not_match?(given_proc) - !matches?(given_proc) && Proc === given_proc - end - - # @api private - # @return [String] - def failure_message - "expected #{expected} to be thrown, #{actual_result}" - end - - # @api private - # @return [String] - def failure_message_when_negated - "expected #{expected('no Symbol')}#{' not' if @expected_symbol} to be thrown, #{actual_result}" - end - - # @api private - # @return [String] - def description - "throw #{expected}" - end - - # @api private - # Indicates this matcher matches against a block. - # @return [True] - def supports_block_expectations? - true - end - - # @api private - def supports_value_expectations? - false - end - - # @api private - def expects_call_stack_jump? - true - end - - private - - def actual_result - return "but was not a block" unless Proc === @block - "got #{caught}" - end - - def expected(symbol_desc='a Symbol') - throw_description(@expected_symbol || symbol_desc, @expected_arg) - end - - def caught - throw_description(@caught_symbol || 'nothing', @caught_arg) - end - - def throw_description(symbol, arg) - symbol_description = symbol.is_a?(String) ? symbol : description_of(symbol) - - arg_description = if arg - " with #{description_of arg}" - elsif @expected_arg && @caught_symbol == @expected_symbol - " with no argument" - else - "" - end - - symbol_description + arg_description - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb deleted file mode 100644 index c443dc0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb +++ /dev/null @@ -1,375 +0,0 @@ -require 'rspec/matchers/built_in/count_expectation' - -RSpec::Support.require_rspec_support 'method_signature_verifier' - -module RSpec - module Matchers - module BuiltIn - # @private - # Object that is yielded to `expect` when one of the - # yield matchers is used. Provides information about - # the yield behavior of the object-under-test. - class YieldProbe - def self.probe(block, &callback) - probe = new(block, &callback) - return probe unless probe.has_block? - probe.probe - end - - attr_accessor :num_yields, :yielded_args - - def initialize(block, &callback) - @block = block - @callback = callback || Proc.new {} - @used = false - self.num_yields = 0 - self.yielded_args = [] - end - - def has_block? - Proc === @block - end - - def probe - assert_valid_expect_block! - @block.call(self) - assert_used! - self - end - - def to_proc - @used = true - - probe = self - callback = @callback - Proc.new do |*args| - probe.num_yields += 1 - probe.yielded_args << args - callback.call(*args) - nil # to indicate the block does not return a meaningful value - end - end - - def single_yield_args - yielded_args.first - end - - def yielded_once?(matcher_name) - case num_yields - when 1 then true - when 0 then false - else - raise "The #{matcher_name} matcher is not designed to be used with a " \ - 'method that yields multiple times. Use the yield_successive_args ' \ - 'matcher for that case.' - end - end - - def assert_used! - return if @used - raise 'You must pass the argument yielded to your expect block on ' \ - 'to the method-under-test as a block. It acts as a probe that ' \ - 'allows the matcher to detect whether or not the method-under-test ' \ - 'yields, and, if so, how many times, and what the yielded arguments ' \ - 'are.' - end - - if RUBY_VERSION.to_f > 1.8 - def assert_valid_expect_block! - block_signature = RSpec::Support::BlockSignature.new(@block) - return if RSpec::Support::StrictSignatureVerifier.new(block_signature, [self]).valid? - raise 'Your expect block must accept an argument to be used with this ' \ - 'matcher. Pass the argument as a block on to the method you are testing.' - end - else - # :nocov: - # On 1.8.7, `lambda { }.arity` and `lambda { |*a| }.arity` both return -1, - # so we can't distinguish between accepting no args and an arg splat. - # It's OK to skip, this, though; it just provides a nice error message - # when the user forgets to accept an arg in their block. They'll still get - # the `assert_used!` error message from above, which is sufficient. - def assert_valid_expect_block! - # nothing to do - end - # :nocov: - end - end - - # @api private - # Provides the implementation for `yield_control`. - # Not intended to be instantiated directly. - class YieldControl < BaseMatcher - include CountExpectation - # @private - def matches?(block) - @probe = YieldProbe.probe(block) - return false unless @probe.has_block? - expected_count_matches?(@probe.num_yields) - end - - # @private - def does_not_match?(block) - !matches?(block) && @probe.has_block? - end - - # @api private - # @return [String] - def failure_message - 'expected given block to yield control' + failure_reason - end - - # @api private - # @return [String] - def failure_message_when_negated - 'expected given block not to yield control' + failure_reason - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - private - - def failure_reason - return ' but was not a block' unless @probe.has_block? - return "#{count_expectation_description} but did not yield" if @probe.num_yields == 0 - count_failure_reason('yielded') - end - end - - # @api private - # Provides the implementation for `yield_with_no_args`. - # Not intended to be instantiated directly. - class YieldWithNoArgs < BaseMatcher - # @private - def matches?(block) - @probe = YieldProbe.probe(block) - return false unless @probe.has_block? - @probe.yielded_once?(:yield_with_no_args) && @probe.single_yield_args.empty? - end - - # @private - def does_not_match?(block) - !matches?(block) && @probe.has_block? - end - - # @private - def failure_message - "expected given block to yield with no arguments, but #{positive_failure_reason}" - end - - # @private - def failure_message_when_negated - "expected given block not to yield with no arguments, but #{negative_failure_reason}" - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - private - - def positive_failure_reason - return 'was not a block' unless @probe.has_block? - return 'did not yield' if @probe.num_yields.zero? - "yielded with arguments: #{description_of @probe.single_yield_args}" - end - - def negative_failure_reason - return 'was not a block' unless @probe.has_block? - 'did' - end - end - - # @api private - # Provides the implementation for `yield_with_args`. - # Not intended to be instantiated directly. - class YieldWithArgs < BaseMatcher - def initialize(*args) - @expected = args - end - - # @private - def matches?(block) - @args_matched_when_yielded = true - @probe = YieldProbe.new(block) do - @actual = @probe.single_yield_args - @actual_formatted = actual_formatted - @args_matched_when_yielded &&= args_currently_match? - end - return false unless @probe.has_block? - @probe.probe - @probe.yielded_once?(:yield_with_args) && @args_matched_when_yielded - end - - # @private - def does_not_match?(block) - !matches?(block) && @probe.has_block? - end - - # @private - def failure_message - "expected given block to yield with arguments, but #{positive_failure_reason}" - end - - # @private - def failure_message_when_negated - "expected given block not to yield with arguments, but #{negative_failure_reason}" - end - - # @private - def description - desc = 'yield with args' - desc = "#{desc}(#{expected_arg_description})" unless @expected.empty? - desc - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - private - - def positive_failure_reason - return 'was not a block' unless @probe.has_block? - return 'did not yield' if @probe.num_yields.zero? - @positive_args_failure - end - - def expected_arg_description - @expected.map { |e| description_of e }.join(', ') - end - - def negative_failure_reason - if !@probe.has_block? - 'was not a block' - elsif @args_matched_when_yielded && !@expected.empty? - 'yielded with expected arguments' \ - "\nexpected not: #{surface_descriptions_in(@expected).inspect}" \ - "\n got: #{@actual_formatted}" - else - 'did' - end - end - - def args_currently_match? - if @expected.empty? # expect {...}.to yield_with_args - @positive_args_failure = 'yielded with no arguments' if @actual.empty? - return !@actual.empty? - end - - unless (match = all_args_match?) - @positive_args_failure = 'yielded with unexpected arguments' \ - "\nexpected: #{surface_descriptions_in(@expected).inspect}" \ - "\n got: #{@actual_formatted}" - end - - match - end - - def all_args_match? - values_match?(@expected, @actual) - end - end - - # @api private - # Provides the implementation for `yield_successive_args`. - # Not intended to be instantiated directly. - class YieldSuccessiveArgs < BaseMatcher - def initialize(*args) - @expected = args - end - - # @private - def matches?(block) - @actual_formatted = [] - @actual = [] - args_matched_when_yielded = true - yield_count = 0 - - @probe = YieldProbe.probe(block) do |*arg_array| - arg_or_args = arg_array.size == 1 ? arg_array.first : arg_array - @actual_formatted << RSpec::Support::ObjectFormatter.format(arg_or_args) - @actual << arg_or_args - args_matched_when_yielded &&= values_match?(@expected[yield_count], arg_or_args) - yield_count += 1 - end - - return false unless @probe.has_block? - args_matched_when_yielded && yield_count == @expected.length - end - - def does_not_match?(block) - !matches?(block) && @probe.has_block? - end - - # @private - def failure_message - 'expected given block to yield successively with arguments, ' \ - "but #{positive_failure_reason}" - end - - # @private - def failure_message_when_negated - 'expected given block not to yield successively with arguments, ' \ - "but #{negative_failure_reason}" - end - - # @private - def description - "yield successive args(#{expected_arg_description})" - end - - # @private - def supports_block_expectations? - true - end - - # @private - def supports_value_expectations? - false - end - - private - - def expected_arg_description - @expected.map { |e| description_of e }.join(', ') - end - - def positive_failure_reason - return 'was not a block' unless @probe.has_block? - - 'yielded with unexpected arguments' \ - "\nexpected: #{surface_descriptions_in(@expected).inspect}" \ - "\n got: [#{@actual_formatted.join(", ")}]" - end - - def negative_failure_reason - return 'was not a block' unless @probe.has_block? - - 'yielded with expected arguments' \ - "\nexpected not: #{surface_descriptions_in(@expected).inspect}" \ - "\n got: [#{@actual_formatted.join(", ")}]" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb deleted file mode 100644 index e4816e9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb +++ /dev/null @@ -1,171 +0,0 @@ -RSpec::Support.require_rspec_support "fuzzy_matcher" - -module RSpec - module Matchers - # Mixin designed to support the composable matcher features - # of RSpec 3+. Mix it into your custom matcher classes to - # allow them to be used in a composable fashion. - # - # @api public - module Composable - # Creates a compound `and` expectation. The matcher will - # only pass if both sub-matchers pass. - # This can be chained together to form an arbitrarily long - # chain of matchers. - # - # @example - # expect(alphabet).to start_with("a").and end_with("z") - # expect(alphabet).to start_with("a") & end_with("z") - # - # @note The negative form (`expect(...).not_to matcher.and other`) - # is not supported at this time. - def and(matcher) - BuiltIn::Compound::And.new self, matcher - end - alias & and - - # Creates a compound `or` expectation. The matcher will - # pass if either sub-matcher passes. - # This can be chained together to form an arbitrarily long - # chain of matchers. - # - # @example - # expect(stoplight.color).to eq("red").or eq("green").or eq("yellow") - # expect(stoplight.color).to eq("red") | eq("green") | eq("yellow") - # - # @note The negative form (`expect(...).not_to matcher.or other`) - # is not supported at this time. - def or(matcher) - BuiltIn::Compound::Or.new self, matcher - end - alias | or - - # Delegates to `#matches?`. Allows matchers to be used in composable - # fashion and also supports using matchers in case statements. - def ===(value) - matches?(value) - end - - private - - # This provides a generic way to fuzzy-match an expected value against - # an actual value. It understands nested data structures (e.g. hashes - # and arrays) and is able to match against a matcher being used as - # the expected value or within the expected value at any level of - # nesting. - # - # Within a custom matcher you are encouraged to use this whenever your - # matcher needs to match two values, unless it needs more precise semantics. - # For example, the `eq` matcher _does not_ use this as it is meant to - # use `==` (and only `==`) for matching. - # - # @param expected [Object] what is expected - # @param actual [Object] the actual value - # - # @!visibility public - def values_match?(expected, actual) - expected = with_matchers_cloned(expected) - Support::FuzzyMatcher.values_match?(expected, actual) - end - - # Returns the description of the given object in a way that is - # aware of composed matchers. If the object is a matcher with - # a `description` method, returns the description; otherwise - # returns `object.inspect`. - # - # You are encouraged to use this in your custom matcher's - # `description`, `failure_message` or - # `failure_message_when_negated` implementation if you are - # supporting matcher arguments. - # - # @!visibility public - def description_of(object) - RSpec::Support::ObjectFormatter.format(object) - end - - # Transforms the given data structure (typically a hash or array) - # into a new data structure that, when `#inspect` is called on it, - # will provide descriptions of any contained matchers rather than - # the normal `#inspect` output. - # - # You are encouraged to use this in your custom matcher's - # `description`, `failure_message` or - # `failure_message_when_negated` implementation if you are - # supporting any arguments which may be a data structure - # containing matchers. - # - # @!visibility public - def surface_descriptions_in(item) - if Matchers.is_a_describable_matcher?(item) - DescribableItem.new(item) - elsif Hash === item - Hash[surface_descriptions_in(item.to_a)] - elsif Struct === item || unreadable_io?(item) - RSpec::Support::ObjectFormatter.format(item) - elsif should_enumerate?(item) - item.map { |subitem| surface_descriptions_in(subitem) } - else - item - end - end - - # @private - # Historically, a single matcher instance was only checked - # against a single value. Given that the matcher was only - # used once, it's been common to memoize some intermediate - # calculation that is derived from the `actual` value in - # order to reuse that intermediate result in the failure - # message. - # - # This can cause a problem when using such a matcher as an - # argument to another matcher in a composed matcher expression, - # since the matcher instance may be checked against multiple - # values and produce invalid results due to the memoization. - # - # To deal with this, we clone any matchers in `expected` via - # this method when using `values_match?`, so that any memoization - # does not "leak" between checks. - def with_matchers_cloned(object) - if Matchers.is_a_matcher?(object) - object.clone - elsif Hash === object - Hash[with_matchers_cloned(object.to_a)] - elsif should_enumerate?(object) - object.map { |subobject| with_matchers_cloned(subobject) } - else - object - end - end - - # @api private - # We should enumerate arrays as long as they are not recursive. - def should_enumerate?(item) - Array === item && item.none? { |subitem| subitem.equal?(item) } - end - - # @api private - def unreadable_io?(object) - return false unless IO === object - object.each {} # STDOUT is enumerable but raises an error - false - rescue IOError - true - end - module_function :surface_descriptions_in, :should_enumerate?, :unreadable_io? - - # Wraps an item in order to surface its `description` via `inspect`. - # @api private - DescribableItem = Struct.new(:item) do - # Inspectable version of the item description - def inspect - "(#{item.description})" - end - - # A pretty printed version of the item description. - def pretty_print(pp) - pp.text "(#{item.description})" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb deleted file mode 100644 index 4905dd8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb +++ /dev/null @@ -1,546 +0,0 @@ -RSpec::Support.require_rspec_support "with_keywords_when_needed" - -module RSpec - module Matchers - # Defines the custom matcher DSL. - module DSL - # Defines a matcher alias. The returned matcher's `description` will be overridden - # to reflect the phrasing of the new name, which will be used in failure messages - # when passed as an argument to another matcher in a composed matcher expression. - # - # @example - # RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to - # sum_to(3).description # => "sum to 3" - # a_list_that_sums_to(3).description # => "a list that sums to 3" - # - # @example - # RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description| - # description.sub("be sorted by", "a list sorted by") - # end - # - # be_sorted_by(:age).description # => "be sorted by age" - # a_list_sorted_by(:age).description # => "a list sorted by age" - # - # @param new_name [Symbol] the new name for the matcher - # @param old_name [Symbol] the original name for the matcher - # @param options [Hash] options for the aliased matcher - # @option options [Class] :klass the ruby class to use as the decorator. (Not normally used). - # @yield [String] optional block that, when given, is used to define the overridden - # logic. The yielded arg is the original description or failure message. If no - # block is provided, a default override is used based on the old and new names. - # @see RSpec::Matchers - def alias_matcher(new_name, old_name, options={}, &description_override) - description_override ||= lambda do |old_desc| - old_desc.gsub(EnglishPhrasing.split_words(old_name), EnglishPhrasing.split_words(new_name)) - end - klass = options.fetch(:klass) { AliasedMatcher } - - define_method(new_name) do |*args, &block| - matcher = __send__(old_name, *args, &block) - matcher.matcher_name = new_name if matcher.respond_to?(:matcher_name=) - klass.new(matcher, description_override) - end - ruby2_keywords new_name if respond_to?(:ruby2_keywords, true) - end - - # Defines a negated matcher. The returned matcher's `description` and `failure_message` - # will be overridden to reflect the phrasing of the new name, and the match logic will - # be based on the original matcher but negated. - # - # @example - # RSpec::Matchers.define_negated_matcher :exclude, :include - # include(1, 2).description # => "include 1 and 2" - # exclude(1, 2).description # => "exclude 1 and 2" - # - # @param negated_name [Symbol] the name for the negated matcher - # @param base_name [Symbol] the name of the original matcher that will be negated - # @yield [String] optional block that, when given, is used to define the overridden - # logic. The yielded arg is the original description or failure message. If no - # block is provided, a default override is used based on the old and new names. - # @see RSpec::Matchers - def define_negated_matcher(negated_name, base_name, &description_override) - alias_matcher(negated_name, base_name, :klass => AliasedNegatedMatcher, &description_override) - end - - # Defines a custom matcher. - # - # @param name [Symbol] the name for the matcher - # @yield [Object] block that is used to define the matcher. - # The block is evaluated in the context of your custom matcher class. - # When args are passed to your matcher, they will be yielded here, - # usually representing the expected value(s). - # @see RSpec::Matchers - def define(name, &declarations) - warn_about_block_args(name, declarations) - define_method name do |*expected, &block_arg| - RSpec::Matchers::DSL::Matcher.new(name, declarations, self, *expected, &block_arg) - end - end - alias_method :matcher, :define - - private - - if Proc.method_defined?(:parameters) - def warn_about_block_args(name, declarations) - declarations.parameters.each do |type, arg_name| - next unless type == :block - RSpec.warning("Your `#{name}` custom matcher receives a block argument (`#{arg_name}`), " \ - "but due to limitations in ruby, RSpec cannot provide the block. Instead, " \ - "use the `block_arg` method to access the block") - end - end - else - # :nocov: - def warn_about_block_args(*) - # There's no way to detect block params on 1.8 since the method reflection APIs don't expose it - end - # :nocov: - end - - RSpec.configure { |c| c.extend self } if RSpec.respond_to?(:configure) - - # Contains the methods that are available from within the - # `RSpec::Matchers.define` DSL for creating custom matchers. - module Macros - # Stores the block that is used to determine whether this matcher passes - # or fails. The block should return a boolean value. When the matcher is - # passed to `expect(...).to` and the block returns `true`, then the expectation - # passes. Similarly, when the matcher is passed to `expect(...).not_to` and the - # block returns `false`, then the expectation passes. - # - # @example - # - # RSpec::Matchers.define :be_even do - # match do |actual| - # actual.even? - # end - # end - # - # expect(4).to be_even # passes - # expect(3).not_to be_even # passes - # expect(3).to be_even # fails - # expect(4).not_to be_even # fails - # - # By default the match block will swallow expectation errors (e.g. - # caused by using an expectation such as `expect(1).to eq 2`), if you - # wish to allow these to bubble up, pass in the option - # `:notify_expectation_failures => true`. - # - # @param [Hash] options for defining the behavior of the match block. - # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`) - def match(options={}, &match_block) - define_user_override(:matches?, match_block) do |actual| - @actual = actual - RSpec::Support.with_failure_notifier(RAISE_NOTIFIER) do - begin - super(*actual_arg_for(match_block)) - rescue RSpec::Expectations::ExpectationNotMetError - raise if options[:notify_expectation_failures] - false - end - end - end - end - - # @private - RAISE_NOTIFIER = Proc.new { |err, _opts| raise err } - - # Use this to define the block for a negative expectation (`expect(...).not_to`) - # when the positive and negative forms require different handling. This - # is rarely necessary, but can be helpful, for example, when specifying - # asynchronous processes that require different timeouts. - # - # By default the match block will swallow expectation errors (e.g. - # caused by using an expectation such as `expect(1).to eq 2`), if you - # wish to allow these to bubble up, pass in the option - # `:notify_expectation_failures => true`. - # - # @param [Hash] options for defining the behavior of the match block. - # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`) - def match_when_negated(options={}, &match_block) - define_user_override(:does_not_match?, match_block) do |actual| - begin - @actual = actual - RSpec::Support.with_failure_notifier(RAISE_NOTIFIER) do - super(*actual_arg_for(match_block)) - end - rescue RSpec::Expectations::ExpectationNotMetError - raise if options[:notify_expectation_failures] - false - end - end - end - - # Use this instead of `match` when the block will raise an exception - # rather than returning false to indicate a failure. - # - # @example - # - # RSpec::Matchers.define :accept_as_valid do |candidate_address| - # match_unless_raises ValidationException do |validator| - # validator.validate(candidate_address) - # end - # end - # - # expect(email_validator).to accept_as_valid("person@company.com") - # - # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) - def match_unless_raises(expected_exception=Exception, &match_block) - define_user_override(:matches?, match_block) do |actual| - @actual = actual - begin - super(*actual_arg_for(match_block)) - rescue expected_exception => @rescued_exception - false - else - true - end - end - end - - # Customizes the failure message to use when this matcher is - # asked to positively match. Only use this when the message - # generated by default doesn't suit your needs. - # - # @example - # - # RSpec::Matchers.define :have_strength do |expected| - # match { your_match_logic } - # - # failure_message do |actual| - # "Expected strength of #{expected}, but had #{actual.strength}" - # end - # end - # - # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) - def failure_message(&definition) - define_user_override(__method__, definition) - end - - # Customize the failure message to use when this matcher is asked - # to negatively match. Only use this when the message generated by - # default doesn't suit your needs. - # - # @example - # - # RSpec::Matchers.define :have_strength do |expected| - # match { your_match_logic } - # - # failure_message_when_negated do |actual| - # "Expected not to have strength of #{expected}, but did" - # end - # end - # - # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) - def failure_message_when_negated(&definition) - define_user_override(__method__, definition) - end - - # Customize the description to use for one-liners. Only use this when - # the description generated by default doesn't suit your needs. - # - # @example - # - # RSpec::Matchers.define :qualify_for do |expected| - # match { your_match_logic } - # - # description do - # "qualify for #{expected}" - # end - # end - # - # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) - def description(&definition) - define_user_override(__method__, definition) - end - - # Tells the matcher to diff the actual and expected values in the failure - # message. - def diffable - define_method(:diffable?) { true } - end - - # Declares that the matcher can be used in a block expectation. - # Users will not be able to use your matcher in a block - # expectation without declaring this. - # (e.g. `expect { do_something }.to matcher`). - def supports_block_expectations - define_method(:supports_block_expectations?) { true } - end - - # Convenience for defining methods on this matcher to create a fluent - # interface. The trick about fluent interfaces is that each method must - # return self in order to chain methods together. `chain` handles that - # for you. If the method is invoked and the - # `include_chain_clauses_in_custom_matcher_descriptions` config option - # hash been enabled, the chained method name and args will be added to the - # default description and failure message. - # - # In the common case where you just want the chained method to store some - # value(s) for later use (e.g. in `match`), you can provide one or more - # attribute names instead of a block; the chained method will store its - # arguments in instance variables with those names, and the values will - # be exposed via getters. - # - # @example - # - # RSpec::Matchers.define :have_errors_on do |key| - # chain :with do |message| - # @message = message - # end - # - # match do |actual| - # actual.errors[key] == @message - # end - # end - # - # expect(minor).to have_errors_on(:age).with("Not old enough to participate") - def chain(method_name, *attr_names, &definition) - unless block_given? ^ attr_names.any? - raise ArgumentError, "You must pass either a block or some attribute names (but not both) to `chain`." - end - - definition = assign_attributes(attr_names) if attr_names.any? - - define_user_override(method_name, definition) do |*args, &block| - super(*args, &block) - @chained_method_clauses.push([method_name, args]) - self - end - end - - def assign_attributes(attr_names) - attr_reader(*attr_names) - private(*attr_names) - - lambda do |*attr_values| - attr_names.zip(attr_values) do |attr_name, attr_value| - instance_variable_set(:"@#{attr_name}", attr_value) - end - end - end - - # assign_attributes isn't defined in the private section below because - # that makes MRI 1.9.2 emit a warning about private attributes. - private :assign_attributes - - private - - # Does the following: - # - # - Defines the named method using a user-provided block - # in @user_method_defs, which is included as an ancestor - # in the singleton class in which we eval the `define` block. - # - Defines an overridden definition for the same method - # usign the provided `our_def` block. - # - Provides a default `our_def` block for the common case - # of needing to call the user's definition with `@actual` - # as an arg, but only if their block's arity can handle it. - # - # This compiles the user block into an actual method, allowing - # them to use normal method constructs like `return` - # (e.g. for an early guard statement), while allowing us to define - # an override that can provide the wrapped handling - # (e.g. assigning `@actual`, rescueing errors, etc) and - # can `super` to the user's definition. - def define_user_override(method_name, user_def, &our_def) - @user_method_defs.__send__(:define_method, method_name, &user_def) - our_def ||= lambda { super(*actual_arg_for(user_def)) } - define_method(method_name, &our_def) - end - - # Defines deprecated macro methods from RSpec 2 for backwards compatibility. - # @deprecated Use the methods from {Macros} instead. - module Deprecated - # @deprecated Use {Macros#match} instead. - def match_for_should(&definition) - RSpec.deprecate("`match_for_should`", :replacement => "`match`") - match(&definition) - end - - # @deprecated Use {Macros#match_when_negated} instead. - def match_for_should_not(&definition) - RSpec.deprecate("`match_for_should_not`", :replacement => "`match_when_negated`") - match_when_negated(&definition) - end - - # @deprecated Use {Macros#failure_message} instead. - def failure_message_for_should(&definition) - RSpec.deprecate("`failure_message_for_should`", :replacement => "`failure_message`") - failure_message(&definition) - end - - # @deprecated Use {Macros#failure_message_when_negated} instead. - def failure_message_for_should_not(&definition) - RSpec.deprecate("`failure_message_for_should_not`", :replacement => "`failure_message_when_negated`") - failure_message_when_negated(&definition) - end - end - end - - # Defines default implementations of the matcher - # protocol methods for custom matchers. You can - # override any of these using the {RSpec::Matchers::DSL::Macros Macros} methods - # from within an `RSpec::Matchers.define` block. - module DefaultImplementations - include BuiltIn::BaseMatcher::DefaultFailureMessages - - # @api private - # Used internally by objects returns by `should` and `should_not`. - def diffable? - false - end - - # The default description. - def description - english_name = EnglishPhrasing.split_words(name) - expected_list = EnglishPhrasing.list(expected) - "#{english_name}#{expected_list}#{chained_method_clause_sentences}" - end - - # Matchers do not support block expectations by default. You - # must opt-in. - def supports_block_expectations? - false - end - - def supports_value_expectations? - true - end - - # Most matchers do not expect call stack jumps. - def expects_call_stack_jump? - false - end - - private - - def chained_method_clause_sentences - return '' unless Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions? - - @chained_method_clauses.map do |(method_name, method_args)| - english_name = EnglishPhrasing.split_words(method_name) - arg_list = EnglishPhrasing.list(method_args) - " #{english_name}#{arg_list}" - end.join - end - end - - # The class used for custom matchers. The block passed to - # `RSpec::Matchers.define` will be evaluated in the context - # of the singleton class of an instance, and will have the - # {RSpec::Matchers::DSL::Macros Macros} methods available. - class Matcher - # Provides default implementations for the matcher protocol methods. - include DefaultImplementations - - # Allows expectation expressions to be used in the match block. - include RSpec::Matchers - - # Supports the matcher composability features of RSpec 3+. - include Composable - - # Makes the macro methods available to an `RSpec::Matchers.define` block. - extend Macros - extend Macros::Deprecated - - # Exposes the value being matched against -- generally the object - # object wrapped by `expect`. - attr_reader :actual - - # Exposes the exception raised during the matching by `match_unless_raises`. - # Could be useful to extract details for a failure message. - attr_reader :rescued_exception - - # The block parameter used in the expectation - attr_reader :block_arg - - # The name of the matcher. - attr_reader :name - - # @api private - def initialize(name, declarations, matcher_execution_context, *expected, &block_arg) - @name = name - @actual = nil - @expected_as_array = expected - @matcher_execution_context = matcher_execution_context - @chained_method_clauses = [] - @block_arg = block_arg - - klass = - class << self - # See `Macros#define_user_override` above, for an explanation. - include(@user_method_defs = Module.new) - self - end - RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *expected, &declarations) - end - - # Provides the expected value. This will return an array if - # multiple arguments were passed to the matcher; otherwise it - # will return a single value. - # @see #expected_as_array - def expected - if expected_as_array.size == 1 - expected_as_array[0] - else - expected_as_array - end - end - - # Returns the expected value as an an array. This exists primarily - # to aid in upgrading from RSpec 2.x, since in RSpec 2, `expected` - # always returned an array. - # @see #expected - attr_reader :expected_as_array - - # Adds the name (rather than a cryptic hex number) - # so we can identify an instance of - # the matcher in error messages (e.g. for `NoMethodError`) - def inspect - "#<#{self.class.name} #{name}>" - end - - if RUBY_VERSION.to_f >= 1.9 - # Indicates that this matcher responds to messages - # from the `@matcher_execution_context` as well. - # Also, supports getting a method object for such methods. - def respond_to_missing?(method, include_private=false) - super || @matcher_execution_context.respond_to?(method, include_private) - end - else # for 1.8.7 - # :nocov: - # Indicates that this matcher responds to messages - # from the `@matcher_execution_context` as well. - def respond_to?(method, include_private=false) - super || @matcher_execution_context.respond_to?(method, include_private) - end - # :nocov: - end - - private - - def actual_arg_for(block) - block.arity.zero? ? [] : [@actual] - end - - # Takes care of forwarding unhandled messages to the - # `@matcher_execution_context` (typically the current - # running `RSpec::Core::Example`). This is needed by - # rspec-rails so that it can define matchers that wrap - # Rails' test helper methods, but it's also a useful - # feature in its own right. - def method_missing(method, *args, &block) - if @matcher_execution_context.respond_to?(method) - @matcher_execution_context.__send__ method, *args, &block - else - super(method, *args, &block) - end - end - # The method_missing method should be refactored to pass kw args in RSpec 4 - # then this can be removed - ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb deleted file mode 100644 index 05b69bd..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb +++ /dev/null @@ -1,60 +0,0 @@ -module RSpec - module Matchers - # Facilitates converting ruby objects to English phrases. - module EnglishPhrasing - # Converts a symbol into an English expression. - # - # split_words(:banana_creme_pie) #=> "banana creme pie" - # - def self.split_words(sym) - sym.to_s.tr('_', ' ') - end - - # @note The returned string has a leading space except - # when given an empty list. - # - # Converts an object (often a collection of objects) - # into an English list. - # - # list(['banana', 'kiwi', 'mango']) - # #=> " \"banana\", \"kiwi\", and \"mango\"" - # - # Given an empty collection, returns the empty string. - # - # list([]) #=> "" - # - def self.list(obj) - return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj || Hash === obj - items = Array(obj).map { |w| RSpec::Support::ObjectFormatter.format(w) } - case items.length - when 0 - "" - when 1 - " #{items[0]}" - when 2 - " #{items[0]} and #{items[1]}" - else - " #{items[0...-1].join(', ')}, and #{items[-1]}" - end - end - - if RUBY_VERSION == '1.8.7' - # Not sure why, but on travis on 1.8.7 we have gotten these warnings: - # lib/rspec/matchers/english_phrasing.rb:28: warning: default `to_a' will be obsolete - # So it appears that `Array` can trigger that (e.g. by calling `to_a` on the passed object?) - # So here we replace `Kernel#Array` with our own warning-free implementation for 1.8.7. - # @private - # rubocop:disable Naming/MethodName - # :nocov: - def self.Array(obj) - case obj - when Array then obj - else [obj] - end - end - # :nocov: - # rubocop:enable Naming/MethodName - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb deleted file mode 100644 index bdd7cda..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'rspec/expectations' - -module RSpec - module Matchers - # Matchers for testing RSpec matchers. Include them with: - # - # require 'rspec/matchers/fail_matchers' - # RSpec.configure do |config| - # config.include RSpec::Matchers::FailMatchers - # end - # - module FailMatchers - # Matches if an expectation fails - # - # @example - # expect { some_expectation }.to fail - def fail(&block) - raise_error(RSpec::Expectations::ExpectationNotMetError, &block) - end - - # Matches if an expectation fails with the provided message - # - # @example - # expect { some_expectation }.to fail_with("some failure message") - # expect { some_expectation }.to fail_with(/some failure message/) - def fail_with(message) - raise_error(RSpec::Expectations::ExpectationNotMetError, message) - end - - # Matches if an expectation fails including the provided message - # - # @example - # expect { some_expectation }.to fail_including("portion of some failure message") - def fail_including(*snippets) - raise_error( - RSpec::Expectations::ExpectationNotMetError, - a_string_including(*snippets) - ) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb deleted file mode 100644 index cbf3751..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb +++ /dev/null @@ -1,41 +0,0 @@ -module RSpec - module Matchers - class << self - # @private - attr_accessor :last_matcher, :last_expectation_handler - end - - # @api private - # Used by rspec-core to clear the state used to generate - # descriptions after an example. - def self.clear_generated_description - self.last_matcher = nil - self.last_expectation_handler = nil - end - - # @api private - # Generates an an example description based on the last expectation. - # Used by rspec-core's one-liner syntax. - def self.generated_description - return nil if last_expectation_handler.nil? - "#{last_expectation_handler.verb} #{last_description}" - end - - # @private - def self.last_description - last_matcher.respond_to?(:description) ? last_matcher.description : <<-MESSAGE -When you call a matcher in an example without a String, like this: - -specify { expect(object).to matcher } - -or this: - -it { is_expected.to matcher } - -RSpec expects the matcher to have a #description method. You should either -add a String to the example this matcher is being used in, or give it a -description method. Then you won't have to suffer this lengthy warning again. -MESSAGE - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb deleted file mode 100644 index b957b4f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb +++ /dev/null @@ -1,61 +0,0 @@ -module RSpec - module Matchers - # Provides a base class with as little methods as possible, so that - # most methods can be delegated via `method_missing`. - # - # On Ruby 2.0+ BasicObject could be used for this purpose, but it - # introduce some extra complexity with constant resolution, so the - # BlankSlate pattern was prefered. - # @private - class BaseDelegator - kept_methods = [ - # Methods that raise warnings if removed. - :__id__, :__send__, :object_id, - - # Methods that are explicitly undefined in some subclasses. - :==, :===, - - # Methods we keep on purpose. - :class, :respond_to?, :__method__, :method, :dup, - :clone, :initialize_dup, :initialize_copy, :initialize_clone, - ] - instance_methods.each do |method| - unless kept_methods.include?(method.to_sym) - undef_method(method) - end - end - end - - # Provides the necessary plumbing to wrap a matcher with a decorator. - # @private - class MatcherDelegator < BaseDelegator - include Composable - attr_reader :base_matcher - - def initialize(base_matcher) - @base_matcher = base_matcher - end - - def method_missing(*args, &block) - base_matcher.__send__(*args, &block) - end - - if ::RUBY_VERSION.to_f > 1.8 - def respond_to_missing?(name, include_all=false) - super || base_matcher.respond_to?(name, include_all) - end - else - # :nocov: - def respond_to?(name, include_all=false) - super || base_matcher.respond_to?(name, include_all) - end - # :nocov: - end - - def initialize_copy(other) - @base_matcher = @base_matcher.clone - super - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb deleted file mode 100644 index 4a87f64..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb +++ /dev/null @@ -1,105 +0,0 @@ -module RSpec - module Matchers - # rspec-expectations can work with any matcher object that implements this protocol. - # - # @note This class is not loaded at runtime by rspec-expectations. It exists - # purely to provide documentation for the matcher protocol. - class MatcherProtocol - # @!group Required Methods - - # @!method matches?(actual) - # @param actual [Object] The object being matched against. - # @yield For an expression like `expect(x).to matcher do...end`, the `do/end` - # block binds to `to`. It passes that block, if there is one, on to this method. - # @return [Boolean] true if this matcher matches the provided object. - - # @!method failure_message - # This will only be called if {#matches?} returns false. - # @return [String] Explanation for the failure. - - # @!endgroup - - # @!group Optional Methods - - # @!method does_not_match?(actual) - # In a negative expectation such as `expect(x).not_to foo`, RSpec will - # call `foo.does_not_match?(x)` if this method is defined. If it's not - # defined it will fall back to using `!foo.matches?(x)`. This allows you - # to provide custom logic for the negative case. - # - # @param actual [Object] The object being matched against. - # @yield For an expression like `expect(x).not_to matcher do...end`, the `do/end` - # block binds to `not_to`. It passes that block, if there is one, on to this method. - # @return [Boolean] true if this matcher does not match the provided object. - - # @!method failure_message_when_negated - # This will only be called when a negative match fails. - # @return [String] Explanation for the failure. - # @note This method is listed as optional because matchers do not have to - # support negation. But if your matcher does support negation, this is a - # required method -- otherwise, you'll get a `NoMethodError`. - - # @!method description - # The description is used for two things: - # - # * When using RSpec's one-liner syntax - # (e.g. `it { is_expected.to matcher }`), the description - # is used to generate the example's doc string since you - # have not provided one. - # * In a composed matcher expression, the description is used - # as part of the failure message (and description) of the outer - # matcher. - # - # @return [String] Description of the matcher. - - # @!method supports_block_expectations? - # Indicates that this matcher can be used in a block expectation expression, - # such as `expect { foo }.to raise_error`. Generally speaking, this is - # only needed for matchers which operate on a side effect of a block, rather - # than on a particular object. - # @return [Boolean] true if this matcher can be used in block expressions. - # @note If not defined, RSpec assumes a value of `false` for this method. - - # @!method supports_value_expectations? - # Indicates that this matcher can be used in a value expectation expression, - # such as `expect(foo).to eq(bar)`. - # @return [Boolean] true if this matcher can be used in value expressions. - # @note If not defined, RSpec assumes a value of `true` for this method. - - # @!method expects_call_stack_jump? - # Indicates that when this matcher is used in a block expectation - # expression, it expects the block to use a ruby construct that causes - # a call stack jump (such as raising an error or throwing a symbol). - # - # This is used internally for compound block expressions, as matchers - # which expect call stack jumps must be treated with care to work properly. - # - # @return [Boolean] true if the matcher expects a call stack jump - # - # @note This method is very rarely used or needed. - # @note If not defined, RSpec assumes a value of `false` for this method. - - # @!method diffable? - # @return [Boolean] true if `actual` and `expected` can be diffed. - # Indicates that this matcher provides `actual` and `expected` attributes, - # and that the values returned by these can be usefully diffed, which can - # be included in the output. - - # @!method actual - # @return [String, Object] If an object (rather than a string) is provided, - # RSpec will use the `pp` library to convert it to multi-line output in - # order to diff. - # The actual value for the purposes of a diff. - # @note This method is required if `diffable?` returns true. - - # @!method expected - # @return [String, Object] If an object (rather than a string) is provided, - # RSpec will use the `pp` library to convert it to multi-line output in - # order to diff. - # The expected value for the purposes of a diff. - # @note This method is required if `diffable?` returns true. - - # @!endgroup - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb deleted file mode 100644 index cd2264e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb +++ /dev/null @@ -1,82 +0,0 @@ -module RSpec - module Matchers - # @api private - # Handles list of expected and actual value pairs when there is a need - # to render multiple diffs. Also can handle one pair. - class MultiMatcherDiff - # @private - # Default diff label when there is only one matcher in diff - # output - DEFAULT_DIFF_LABEL = "Diff:".freeze - - # @private - # Maximum readable matcher description length - DESCRIPTION_MAX_LENGTH = 65 - - def initialize(expected_list) - @expected_list = expected_list - end - - # @api private - # Wraps provided expected value in instance of - # MultiMatcherDiff. If provided value is already an - # MultiMatcherDiff then it just returns it. - # @param [Any] expected value to be wrapped - # @param [Any] actual value - # @return [RSpec::Matchers::MultiMatcherDiff] - def self.from(expected, actual) - return expected if self === expected - new([[expected, DEFAULT_DIFF_LABEL, actual]]) - end - - # @api private - # Wraps provided matcher list in instance of - # MultiMatcherDiff. - # @param [Array] matchers list of matchers to wrap - # @return [RSpec::Matchers::MultiMatcherDiff] - def self.for_many_matchers(matchers) - new(matchers.map { |m| [m.expected, diff_label_for(m), m.actual] }) - end - - # @api private - # Returns message with diff(s) appended for provided differ - # factory and actual value if there are any - # @param [String] message original failure message - # @param [Proc] differ - # @return [String] - def message_with_diff(message, differ) - diff = diffs(differ) - message = "#{message}\n#{diff}" unless diff.empty? - message - end - - private - - class << self - private - - def diff_label_for(matcher) - "Diff for (#{truncated(RSpec::Support::ObjectFormatter.format(matcher))}):" - end - - def truncated(description) - return description if description.length <= DESCRIPTION_MAX_LENGTH - description[0...DESCRIPTION_MAX_LENGTH - 3] << "..." - end - end - - def diffs(differ) - @expected_list.map do |(expected, diff_label, actual)| - diff = differ.diff(actual, expected) - next if diff.strip.empty? - if diff == "\e[0m\n\e[0m" - "#{diff_label}\n" \ - " " - else - "#{diff_label}#{diff}" - end - end.compact.join("\n") - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document deleted file mode 100644 index 52a564f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.document +++ /dev/null @@ -1,5 +0,0 @@ -lib/**/*.rb -- -README.md -LICENSE.md -Changelog.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts deleted file mode 100644 index 9555b8e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/.yardopts +++ /dev/null @@ -1,6 +0,0 @@ ---exclude features ---no-private ---markup markdown -- -Changelog.md -LICENSE.md diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md deleted file mode 100644 index 3925a20..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/Changelog.md +++ /dev/null @@ -1,1343 +0,0 @@ -### Development -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.7...3-13-maintenance) - -### 3.13.7 / 2025-10-31 -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.6...rspec-mocks-v3.13.7) - -Bug Fixes: - -* Special case `to_h`, `to_hash` responses on null objects, prevents an issue with Rails. (Jon Rowe, rspec/rspec#275) - -### 3.13.6 / 2025-10-14 -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.5...rspec-mocks-v3.13.6) - -Bug Fixes: - -* Work around possible infinite loop when stubbing `is_a?`. (Erin Paget, rspec/rspec#265) - -### 3.13.5 / 2025-05-27 -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.4...rspec-mocks-v3.13.5) - -Bug Fixes: - -* Fix regression where a previous fix (rspec/rspec#214) would leave behind thread data - between tests. (Jon Rowe, rspec/rspec#219) -* Fix links in gemspec to point to monorepo / homepage. (Jon Rowe) - -### 3.13.4 / 2025-05-05 -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.3...rspec-mocks-v3.13.4) - -Bug Fixes: - -* Fix regression where nested stubbed method calls would inadvertently not be counted. - (Jon Rowe, rspec/rspec#214) -* Fix regression where keyword arguments would not be passed through to nested stubbed - method calls. (Jon Rowe, rspec/rspec#214) - -### 3.13.3 / 2025-05-01 -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.2...rspec-mocks-v3.13.3) - -Bug Fixes: - -* When stubbing methods using the `expect_any_instance_of` or `allow_any_instance_of` - ensure the stubbed method has the same visibility as the real method. - (Jon Rowe, rspec/rspec-mocks#1596) -* Prevent recursive calls to stubbed methods during stub invocation. - (James Dabbs, rspec/rspec#116, rspec/rspec#156) - -### 3.13.2 / 2024-10-02 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.13.1...v3.13.2) - -Bug Fixes: - -* Support keyword arguments in callables passed to `and_invoke`. (Jon Rowe, rspec/rspec-mocks#1595) - -### 3.13.1 / 2024-05-08 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.13.0...v3.13.1) - -Bug Fixes: - -* Use `RSpec::Support::Mutex` in `RSpec::Mocks::Proxy` to avoid issues from - stubbing `::Mutex#new`. (Eric Mueller, rspec/rspec-mocks#1575) - -### 3.13.0 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.7...v3.13.0) - -Enhancements: - -* Add an `array_excluding` matcher for arguments. (Zane Wolfgang Pickett, rspec/rspec-mocks#1528) - -### 3.12.7 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.6...v3.12.7) - -Bug Fixes: - -* Reduce allocations from "any_instance" style mocks. (Carlos Palhares, rspec/rspec-mocks#1479) - -### 3.12.6 / 2023-07-11 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.5...v3.12.6) - -Bug Fixes: - -* Fix an issue with `and_call_original` when using the `method_missing` fallback - with keyword arguments. (Igor Drozdov, rspec/rspec-mocks#1552) - -### 3.12.5 / 2023-03-30 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.4...v3.12.5) - -Bug Fixes: - -* Fix compatibility issue with Rails where active_support monkey patches `with` - when using any instance. (Lachlan Sylvester, rspec/rspec-mocks#1540) - -### 3.12.4 / 2023-03-12 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.3...v3.12.4) - -Bug Fixes: - -* Fix an issue with asserting that Array#reverse is never called. (Brad Trick, rspec/rspec-mocks#1533) -* Fix compatibility issue with Rails where active_support monkey patches `with`. - (Jean Boussier, rspec/rspec-mocks#1531, rspec/rspec-mocks#1534) - -### 3.12.3 / 2023-01-17 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.2...v3.12.3) - -Bug Fixes: - -* Fix keyword delegation in `send` for verifying doubles on Ruby 3. - (Charlie Honig, rspec/rspec-mocks#1485) - -### 3.12.2 / 2023-01-07 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.1...v3.12.2) - -Bug Fixes: - -* Fix implementation blocks for mocks using keyword arguments on Ruby 3.2.0. - (Adam Steel, rspec/rspec-mocks#1508) -* Fix keyword argument assertions when mocking using `with` on Ruby 3.2.0. - (Slava Kardakov, Benoit Tigeot, Phil Pirozhkov, Benoit Daloze, rspec/rspec-mocks#1514) - -### 3.12.1 / 2022-12-10 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.0...v3.12.1) - -Bug Fixes: - -* Remove empty diff marker when a diff only contains console codes. (Jon Rowe, rspec/rspec-mocks#1506) -* Show keyword vs hash diff marker when arguments are not `==` (Jon Rowe, rspec/rspec-mocks#1506) -* Change check to detect frozen objects to rescue errors rather than - pre-empting by checking `frozen?` due to some objects mis-behaving. - (Keegan Roth, rspec/rspec-mocks#1401) -* Prevent unfulfilled expectations using `expect_any_instance_of` across a class - inheritance boundary from raising rather than failing. (Jon Rowe, rspec/rspec-mocks#1496) -* Prevent a misleading error message when using `allow(...).not_to` with - unsupported matchers. (Phil Pirozhkov, rspec/rspec-mocks#1503) - -### 3.12.0 / 2022-10-26 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.2...v3.12.0) - -Enhancements: - -* Improve diff output when diffing keyword arguments against hashes. - (Jean Boussier, rspec/rspec-mocks#1461) - -### 3.11.2 / 2022-10-25 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.1...v3.11.2) - -Bug Fixes: - -* Use the original implementation of `Class.new` to detect overridden definitions - of `new` rather than the owner, fixing detection of "double aliased" methods - in Ruby 3 and above. (Benoit Daloze, rspec/rspec-mocks#1470, rspec/rspec-mocks#1476) -* Support keyword argument semantics when constraining argument expectations using - `with` on Ruby 3.0+ with `instance_double` (Andrii Malyshko, rspec/rspec-mocks#1473) - -### 3.11.1 / 2022-03-31 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.0...v3.11.1) - -Bug Fixes: - -* Add extra `ruby2_keywords` calls to properly designate methods using - `*args` to pass keyword around, fixes an issue with TruffleRuby. - (Benoit Daloze, rspec/rspec-mocks#1464) - -### 3.11.0 / 2022-02-09 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.3...v3.11.0) - -Enhancements: - -* Add `and_invoke` implementation for configuring responses to `receive` - (and `receive_messages`) with multiple callable objects. (Kyle Smith, rspec/rspec-mocks#1411) - -### 3.10.3 / 2022-01-28 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.2...v3.10.3) - -Bug Fixes: - -* Suppress warning by setting `$VERBOSE` to nil. (Nobuyoshi Nakada, rspec/rspec-mocks#1414) -* Support keyword argument semantics when constraining argument expectations using - `with` on Ruby 3.0+ (Yusuke Endoh, rspec/rspec-mocks#1394) - -### 3.10.2 / 2021-01-27 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.1...v3.10.2) - -Bug Fixes: - -* Support keyword arguments with `and_call_original` on Ruby 3.0. - (Bryan Powell, rspec/rspec-mocks#1385) -* `RSpec::Mocks::Constant#previously_defined?` is now always a boolean. - (Phil Pirozhkov, rspec/rspec-mocks#1397) -* Support keyword arguments on Ruby 3.0 when used with `expect_any_instance_of` - or `allow_any_instance_of` with `and_call_original`. - (Jess Hottenstein, rspec/rspec-mocks#1407) - -### 3.10.1 / 2020-12-27 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.0...v3.10.1) - -Bug Fixes: - -* Issue `ArgumentError` rather than `TypeError` when unsupported methods on - unsupported objects are attempted to be stubbed. (@zhisme, rspec/rspec-mocks#1357) - -### 3.10.0 / 2020-10-30 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.1...v3.10.0) - -Enhancements: -* Add the ability to set a custom error generator in `MessageExpectation`. - This will allow rspec-expectations to inject a custom failure message. - (Benoit Tigeot and Nicolas Zermati, rspec/rspec-mocks#1312) -* Return the result of the block passed to `RSpec::Mocks.with_temporary_scope` - when block run. (@expeehaa, rspec/rspec-mocks#1329) - -### 3.9.1 / 2019-12-31 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.0...v3.9.1) - -Bug Fixes: - -* Trigger `RSpec::Mocks.configuration.verifying_double_callbacks` when using - `allow_any_instance_of` or `expect_any_instance_of` (Daniel Orner, rspec/rspec-mocks#1309) - -### 3.9.0 / 2019-10-07 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.2...v3.9.0) - -Enhancements: - -* Improve thread safety of message expectations by using Mutex to prevent - deadlocking errors. (Ry Biesemeyer, rspec/rspec-mocks#1236) -* Add the ability to use `time` as an alias for `times`. For example: - `expect(Class).to receive(:method).exactly(1).time`. - (Pistos, Benoit Tigeot, rspec/rspec-mocks#1271) - -### 3.8.2 / 2019-10-02 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.1...v3.8.2) - -* Allow `array_including` argument matchers to be nested. - (Emmanuel Delmas, rspec/rspec-mocks#1291) - -### 3.8.1 / 2019-06-13 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.0...v3.8.1) - -Bug Fixes: - -* Ensure stubbing methods does not change their visibility. - (Kevin Boschert, rspec/rspec-mocks#1277) - -### 3.8.0 / 2018-08-04 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.7.0...v3.8.0) - -Bug Fixes: - -* Issue error when encountering invalid "counted" negative message expectations. - (Sergiy Yarinovskiy, rspec/rspec-mocks#1212) -* Ensure `allow_any_instance_of` and `expect_any_instance_of` can be temporarily - supressed. (Jon Rowe, rspec/rspec-mocks#1228) -* Ensure `expect_any_instance_of(double).to_not have_received(:some_method)` - fails gracefully (as its not supported) rather than issuing a `NoMethodError`. - (Maxim Krizhanovsky, rspec/rspec-mocks#1231) - -### 3.7.0 / 2017-10-17 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0...v3.7.0) - -Enhancements: - -* Improve compatibility with `--enable-frozen-string-literal` option - on Ruby 2.3+. (Pat Allan, rspec/rspec-mocks#1165) - -Bug Fixes: - -* Fix `hash_including` and `hash_excluding` so that they work against - subclasses of `Hash`. (Aaron Rosenberg, rspec/rspec-mocks#1167) - -### 3.6.0 / 2017-05-04 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0.beta2...v3.6.0) - -Bug Fixes: - -* Fix "instance variable @color not initialized" warning when using - rspec-mocks without rspec-core. (Myron Marston, rspec/rspec-mocks#1142) -* Restore aliased module methods properly when stubbing on 1.8.7. - (Samuel Giddins, rspec/rspec-mocks#1144) -* Allow a message chain expectation to be constrained by argument(s). - (Jon Rowe, rspec/rspec-mocks#1156) - -### 3.6.0.beta2 / 2016-12-12 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0.beta1...v3.6.0.beta2) - -Enhancements: - -* Add new `without_partial_double_verification { }` API that lets you - temporarily turn off partial double verification for an example. - (Jon Rowe, rspec/rspec-mocks#1104) - -### 3.6.0.beta1 / 2016-10-09 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0...v3.6.0.beta1) - -Bug Fixes: - -* Return the test double instance form `#freeze` (Alessandro Berardi, rspec/rspec-mocks#1109) -* Allow the special logic for stubbing `new` to work when `.method` has - been redefined. (Proby, rspec/rspec-mocks#1119) - -### 3.5.0 / 2016-07-01 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta4...v3.5.0) - -Enhancements: - -* Provides a nice string representation of - `RSpec::Mocks::MessageExpectation` (Myron Marston, rspec/rspec-mocks#1095) - -### 3.5.0.beta4 / 2016-06-05 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta3...v3.5.0.beta4) - -Enhancements: - -* Add `and_throw` to any instance handling. (Tobias Bühlmann, rspec/rspec-mocks#1068) - -### 3.5.0.beta3 / 2016-04-02 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta2...v3.5.0.beta3) - -Enhancements: - -* Issue warning when attempting to use unsupported - `allow(...).to receive(...).ordered`. (Jon Rowe, rspec/rspec-mocks#1000) -* Add `rspec/mocks/minitest_integration`, to properly integrate rspec-mocks - with minitest. (Myron Marston, rspec/rspec-mocks#1065) - -### 3.5.0.beta2 / 2016-03-10 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta1...v3.5.0.beta2) - -Enhancements: - -* Improve error message displayed when using `and_wrap_original` on pure test - doubles. (betesh, rspec/rspec-mocks#1063) - -Bug Fixes: - -* Fix issue that prevented `receive_message_chain(...).with(...)` working - correctly on "any instance" mocks. (Jon Rowe, rspec/rspec-mocks#1061) - -### 3.5.0.beta1 / 2016-02-06 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.4.1...v3.5.0.beta1) - -Bug Fixes: - -* Allow `any_instance_of(...).to receive(...)` to use `and_yield` multiple - times. (Kilian Cirera Sant, rspec/rspec-mocks#1054) -* Allow matchers which inherit from `rspec-mocks` matchers to be used for - `allow`. (Andrew Kozin, rspec/rspec-mocks#1056) -* Prevent stubbing `respond_to?` on partial doubles from causing infinite - recursion. (Jon Rowe, rspec/rspec-mocks#1013) -* Prevent aliased methods from disapearing after being mocked with - `any_instance` (regression from rspec/rspec-mocks#1043). (Joe Rafaniello, rspec/rspec-mocks#1060) - -### 3.4.1 / 2016-01-10 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.4.0...v3.4.1) - -Bug Fixes: - -* Fix `any_instance` to work properly on Ruby 2.3. (Joe Rafaniello, rspec/rspec-mocks#1043) - -### 3.4.0 / 2015-11-11 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.2...v3.4.0) - -Enhancements: - -* Make `expect(...).to have_received` work without relying upon - rspec-expectations. (Myron Marston, rspec/rspec-mocks#978) -* Add option for failing tests when expectations are set on `nil`. - (Liz Rush, rspec/rspec-mocks#983) - -Bug Fixes: - -* Fix `have_received { ... }` so that any block passed when the message - was received is forwarded to the `have_received` block. (Myron Marston, rspec/rspec-mocks#1006) -* Fix infinite loop in error generator when stubbing `respond_to?`. - (Alex Dowad, rspec/rspec-mocks#1022) -* Fix issue with using `receive` on subclasses (at a class level) with 1.8.7. - (Alex Dowad, rspec/rspec-mocks#1026) - -### 3.3.2 / 2015-07-15 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.1...v3.3.2) - -Bug Fixes: - -* Prevent thread deadlock errors during proxy creation (e.g. when using - `before_verifying_doubles` callbacks). (Jon Rowe, rspec/rspec-mocks#980, rspec/rspec-mocks#979) - -### 3.3.1 / 2015-06-19 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.0...v3.3.1) - -Bug Fixes: - -* Fix bug in `before_verifying_double` callback logic that caused it to be called - once for each class in the ancestor list when mocking or stubbing a class. Now - it is only called for the mocked or stubbed class, as you would expect. (Sam - Phippen, rspec/rspec-mocks#974) - -### 3.3.0 / 2015-06-12 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.2.1...v3.3.0) - -Enhancements: - -* When stubbing `new` on `MyClass` or `class_double(MyClass)`, use the - method signature from `MyClass#initialize` to verify arguments. - (Myron Marston, rspec/rspec-mocks#886) -* Use matcher descriptions when generating description of received arguments - for mock expectation failures. (Tim Wade, rspec/rspec-mocks#891) -* Avoid loading `stringio` unnecessarily. (Myron Marston, rspec/rspec-mocks#894) -* Verifying doubles failure messages now distinguish between class and instance - level methods. (Tim Wade, rspec/rspec-mocks#896, rspec/rspec-mocks#908) -* Improve mock expectation failure messages so that it combines both - number of times and the received arguments in the output. (John Ceh, rspec/rspec-mocks#918) -* Improve how test doubles are represented in failure messages. - (Siva Gollapalli, Myron Marston, rspec/rspec-mocks#932) -* Rename `RSpec::Mocks::Configuration#when_declaring_verifying_double` to - `RSpec::Mocks::Configuration#before_verifying_doubles` and utilise when - verifying partial doubles. (Jon Rowe, rspec/rspec-mocks#940) -* Use rspec-support's `ObjectFormatter` for improved formatting of - arguments in failure messages so that, for example, full time - precisions is displayed for time objects. (Gavin Miller, Myron Marston, rspec/rspec-mocks#955) - -Bug Fixes: - -* Ensure expectations that raise eagerly also raise during RSpec verification. - This means that if exceptions are caught inside test execution the test will - still fail. (Sam Phippen, rspec/rspec-mocks#884) -* Fix `have_received(msg).with(args).exactly(n).times` and - `receive(msg).with(args).exactly(n).times` failure messages - for when the message was received the wrong number of times with - the specified args, and also received additional times with other - arguments. Previously it confusingly listed the arguments as being - mis-matched (even when the double was allowed to receive with any - args) rather than listing the count. (John Ceh, rspec/rspec-mocks#918) -* Fix `any_args`/`anything` support so that we avoid calling `obj == anything` - on user objects that may have improperly implemented `==` in a way that - raises errors. (Myron Marston, rspec/rspec-mocks#924) -* Fix edge case involving stubbing the same method on a class and a subclass - which previously hit a `NoMethodError` internally in RSpec. (Myron Marston rspec/rspec-mocks#954) -* Fix edge case where the message received count would be incremented multiple - times for one failure. (Myron Marston, rspec/rspec-mocks#957) -* Fix failure messages for when spies received the expected message with - different arguments and also received another message. (Maurício Linhares, rspec/rspec-mocks#960) -* Silence whitespace-only diffs. (Myron Marston, rspec/rspec-mocks#969) - -### 3.2.1 / 2015-02-23 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.2.0...v3.2.1) - -Bug Fixes: - -* Add missing `rspec/support/differ` require so that rspec-mocks can be - used w/o rspec-expectations (which also loads the differ and hided the - fact we forgot to require it). (Myron Marston, rspec/rspec-mocks#893) -* Revert tracking of received arg mutation (added in 3.2.0 to provide an - error in a situation we can't support) as our implementation has side - effects on non-standard objects and there's no solution we could come - up with that always works. (Myron Marston, rspec/rspec-mocks#900) - -### 3.2.0 / 2015-02-03 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.3...v3.2.0) - -Enhancements: - -* Treat `any_args` as an arg splat, allowing it to match an arbitrary - number of args at any point in an arg list. (Myron Marston, rspec/rspec-mocks#786) -* Print diffs when arguments in mock expectations are mismatched. - (Sam Phippen, rspec/rspec-mocks#751) -* Support names for verified doubles (`instance_double`, `instance_spy`, - `class_double`, `class_spy`, `object_double`, `object_spy`). (Cezary - Baginski, rspec/rspec-mocks#826) -* Make `array_including` and `hash_including` argument matchers composable. - (Sam Phippen, rspec/rspec-mocks#819) -* Make `allow_any_instance_of(...).to receive(...).and_wrap_original` - work. (Ryan Fitzgerald, rspec/rspec-mocks#869) - -Bug Fixes: - -* Provide a clear error when users wrongly combine `no_args` with - additional arguments (e.g. `expect().to receive().with(no_args, 1)`). - (Myron Marston, rspec/rspec-mocks#786) -* Provide a clear error when users wrongly use `any_args` multiple times in the - same argument list (e.g. `expect().to receive().with(any_args, 1, any_args)`. - (Myron Marston, rspec/rspec-mocks#786) -* Prevent the error generator from using user object #description methods. - See [rspec/rspec-mocks#685](https://github.com/rspec/rspec-mocks/issues/685). - (Sam Phippen, rspec/rspec-mocks#751) -* Make verified doubles declared as `(instance|class)_double(SomeConst)` - work properly when `SomeConst` has previously been stubbed. - `(instance|class)_double("SomeClass")` already worked properly. - (Myron Marston, rspec/rspec-mocks#824) -* Add a matcher description for `receive`, `receive_messages` and - `receive_message_chain`. (Myron Marston, rspec/rspec-mocks#828) -* Validate invocation args for null object verified doubles. - (Myron Marston, rspec/rspec-mocks#829) -* Fix `RSpec::Mocks::Constant.original` when called with an invalid - constant to return an object indicating the constant name is invalid, - rather than blowing up. (Myron Marston, rspec/rspec-mocks#833) -* Make `extend RSpec::Mocks::ExampleMethods` on any object work properly - to add the rspec-mocks API to that object. Previously, `expect` would - be undefined. (Myron Marston, rspec/rspec-mocks#846) -* Fix `require 'rspec/mocks/standalone'` so that it only affects `main` - and not every object. It's really only intended to be used in a REPL - like IRB, but some gems have loaded it, thinking it needs to be loaded - when using rspec-mocks outside the context of rspec-core. - (Myron Marston, rspec/rspec-mocks#846) -* Prevent message expectations from being modified by customization methods - (e.g. `with`) after they have been invoked. (Sam Phippen and Melanie Gilman, rspec/rspec-mocks#837) -* Handle cases where a method stub cannot be removed due to something - external to RSpec monkeying with the method definition. This can - happen, for example, when you `file.reopen(io)` after previously - stubbing a method on the `file` object. (Myron Marston, rspec/rspec-mocks#853) -* Provide a clear error when received message args are mutated before - a `have_received(...).with(...)` expectation. (Myron Marston, rspec/rspec-mocks#868) - -### 3.1.3 / 2014-10-08 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.2...v3.1.3) - -Bug Fixes: - -* Correct received messages count when used with `have_received` matcher. - (Jon Rowe, rspec/rspec-mocks#793) -* Provide a clear error message when you use `allow_any_instance_of(...)` or - `expect_any_instance_of(...)` with the `have_received` matcher (they are - not intended to be used together and previously caused an odd internal - failure in rspec-mocks). (Jon Rowe, rspec/rspec-mocks#799). -* Fix verified double `with` verification so that it applies to method - stubs. (Myron Marston, rspec/rspec-mocks#790) - -### 3.1.2 / 2014-09-26 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.1...v3.1.2) - -Bug Fixes: - -* Provide a clear error message when you use `allow(...)` with the - `have_received` matcher (they are not intended to be used together - and previously caused an odd internal failure in rspec-mocks). (Jon Rowe, rspec/rspec-mocks#788). - -### 3.1.1 / 2014-09-18 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.0...v3.1.1) - -Bug Fixes: - -* Prevent included modules being detected as prepended modules on Ruby 2.0 - when using `any_instance_of(...)`. (Tony Novak, rspec/rspec-mocks#781) - -### 3.1.0 / 2014-09-04 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.4...v3.1.0) - -Enhancements: - -* Add spying methods (`spy`, `ìnstance_spy`, `class_spy` and `object_spy`) - which create doubles as null objects for use with spying in testing. (Sam - Phippen, rspec/rspec-mocks#671) -* `have_received` matcher will raise "does not implement" errors correctly when - used with verifying doubles and partial doubles. (Xavier Shay, rspec/rspec-mocks#722) -* Allow matchers to be used in place of keyword arguments in `with` - expectations. (Xavier Shay, rspec/rspec-mocks#726) -* Add `thrice` modifier to message expectation interface as a synonym - for `exactly(3).times`. (Dennis Taylor, rspec/rspec-mocks#753) -* Add more `thrice` synonyms e.g. `.at_least(:thrice)`, `.at_most(:thrice)`, - `receive(...).thrice` and `have_received(...).thrice`. (Jon Rowe, rspec/rspec-mocks#754) -* Add `and_wrap_original` modifier for partial doubles to mutate the - response from a method. (Jon Rowe, rspec/rspec-mocks#762) - -Bug Fixes: - -* Remove `any_number_of_times` from `any_instance` recorders that were - erroneously causing mention of the method in documentation. (Jon Rowe, rspec/rspec-mocks#760) -* Prevent included modules being detected as prepended modules on Ruby 2.0. - (Eugene Kenny, rspec/rspec-mocks#771) - -### 3.0.4 / 2014-08-14 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.3...v3.0.4) - -Bug Fixes: - -* Restore `kind_of(x)` to match using `arg.kind_of?(x)` (like RSpec 2) - rather than `x === arg`. (Jon Rowe, rspec/rspec-mocks#750) - -### 3.0.3 / 2014-07-21 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.2...v3.0.3) - -Bug Fixes: - -* `have_received` matcher will raise "does not implement" errors correctly when - used with verifying doubles and partial doubles. (Xavier Shay, rspec/rspec-mocks#722) -* Make `double.as_null_object.dup` and `double.as_null_object.clone` - make the copies be null objects. (Myron Marston, rspec/rspec-mocks#732) -* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, rspec/rspec-mocks#739) - -### 3.0.2 / 2014-06-19 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.1...v3.0.2) - -Bug Fixes: - -* Fix edge case that triggered "can't add a new key into hash during - iteration" during mock verification. (Sam Phippen, Myron Marston, rspec/rspec-mocks#711) -* Fix verifying doubles so that when they accidentally leak into another - example, they provide the same clear error message that normal doubles - do. (Myron Marston, rspec/rspec-mocks#718) -* Make `ordered` work with exact receive counts. (Sam Phippen, rspec/rspec-mocks#713) - -### 3.0.1 / 2014-06-07 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0...v3.0.1) - -Bug Fixes: - -* Fix `receive_message_chain(...)` so that it supports `with` just like - `stub_chain` did. (Jon Rowe, rspec/rspec-mocks#697) -* Fix regression in `expect_any_instance_of` so that it expects the - message on _any_ instance rather than on _every_ instance. - (Myron Marston, rspec/rspec-mocks#699) - -### 3.0.0 / 2014-06-01 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.rc1...v3.0.0) - -Bug Fixes: - -* Fix module prepend detection to work properly on ruby 2.0 for a case - where a module is extended onto itself. (Myron Marston) -* Fix `transfer_nested_constants` option so that transferred constants - get properly reset at the end of the example. (Myron Marston) -* Fix `config.transfer_nested_constants = true` so that you don't - erroneously get errors when stubbing a constant that is not a module - or a class. (Myron Marston) -* Fix regression that caused `double(:class => SomeClass)` to later - trigger infinite recursion. (Myron Marston) -* Fix bug in `have_received(...).with(...).ordered` where it was not - taking the args into account when checking the order. (Myron Marston) -* Fix bug in `have_received(...).ordered` where it was wrongly - considering stubs when checking the order. (Myron Marston) -* Message expectation matchers now show descriptions from argument - matchers when their expectations aren't met. (Jon Rowe) -* Display warning when encountering `TypeError` during instance method - staging on 2.0.0-p195, suffers from https://bugs.ruby-lang.org/issues/8686 - too. (Cezar Halmagean). - -### 3.0.0.rc1 / 2014-05-18 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta2...v3.0.0.rc1) - -Breaking Changes for 3.0.0: - -* Remove `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston) -* Remove `RSpec::Mocks::ConstantStubber`. (Jon Rowe) -* Make monkey-patch of Marshal to support dumping of stubbed objects opt-in. - (Xavier Shay) - -Enhancements: - -* Instead of crashing when cleaning up stub methods on a frozen object, it now - issues a warning explaining that it's impossible to clean up the stubs. - (Justin Coyne and Sam Phippen) -* Add meaningful descriptions to `anything`, `duck_type` and `instance_of` argument - matchers. (Jon Rowe) - -Bug Fixes: - -* Fix regression introduced in 3.0.0.beta2 that caused - `double.as_null_object.to_str` to return the double rather - than a string. (Myron Marston) -* Fix bug in `expect(dbl).to receive_message_chain(:foo, :bar)` where it was - not setting an expectation for the last message in the chain. - (Jonathan del Strother) -* Allow verifying partial doubles to have private methods stubbed. (Xavier Shay) -* Fix bug with allowing/expecting messages on Class objects which have had - their singleton class prepended to. (Jon Rowe) -* Fix an issue with 1.8.7 not running implementation blocks on partial doubles. - (Maurício Linhares) -* Prevent `StackLevelTooDeep` errors when stubbing an `any_instance` method that's - accessed in `inspect` by providing our own inspect output. (Jon Rowe) -* Fix bug in `any_instance` logic that did not allow you to mock or stub - private methods if `verify_partial_doubles` was configured. (Oren Dobzinski) -* Include useful error message when trying to observe an unimplemented method - on an any instance. (Xavier Shay) -* Fix `and_call_original` to work properly when multiple classes in an - inheritance hierarchy have been stubbed with the same method. (Myron Marston) -* Fix `any_instance` so that it updates existing instances that have - already been stubbed. (Myron Marston) -* Fix verified doubles so that their class name is included in failure - messages. (Myron Marston) -* Fix `expect_any_instance_of` so that when the message is received - on an individual instance that has been directly stubbed, it still - satisfies the expectation. (Sam Phippen, Myron Marston) -* Explicitly disallow using `any_instance` to mock or stub a method - that is defined on a module prepended onto the class. This triggered - `SystemStackError` before and is very hard to support so we are not - supporting it at this time. (Myron Marston) - -### 3.0.0.beta2 / 2014-02-17 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta1...v3.0.0.beta2) - -Breaking Changes for 3.0.0: - -* Rename `RSpec::Mocks::Mock` to `RSpec::Mocks::Double`. (Myron Marston) -* Change how to integrate rspec-mocks in other test frameworks. You now - need to include `RSpec::Mocks::ExampleMethods` in your test context. - (Myron Marston) -* Prevent RSpec mocks' doubles and partial doubles from being used outside of - the per-test lifecycle (e.g. from a `before(:all)` hook). (Sam Phippen) -* Remove the `host` argument of `RSpec::Mocks.setup`. Instead - `RSpec::Mocks::ExampleMethods` should be included directly in the scope where - RSpec's mocking capabilities are used. (Sam Phippen) -* Make test doubles raise errors if you attempt to use them after they - get reset, to help surface issues when you accidentally retain - references to test doubles and attempt to reuse them in another - example. (Myron Marston) -* Remove support for `and_return { value }` and `and_return` without arguments. (Yuji Nakayama) - -Enhancements: - -* Add `receive_message_chain` which provides the functionality of the old - `stub_chain` for the new allow/expect syntax. Use it like so: `allow(...).to - receive_message_chain(:foo, :bar, :bazz)`. (Sam Phippen). -* Change argument matchers to use `===` as their primary matching - protocol, since their semantics mirror that of a case or rescue statement - (which uses `===` for matching). (Myron Marston) -* Add `RSpec::Mocks.with_temporary_scope`, which allows you to create - temporary rspec-mocks scopes in arbitrary places (such as a - `before(:all)` hook). (Myron Marston) -* Support keyword arguments when checking arity with verifying doubles. - (Xavier Shay) - -Bug Fixes: - -* Fix regression in 3.0.0.beta1 that caused `double("string_name" => :value)` - to stop working. (Xavier Shay) -* Fix the way rspec-mocks and rspec-core interact so that if users - define a `let` with the same name as one of the methods - from `RSpec::Mocks::ArgumentMatchers`, the user's `let` takes - precedence. (Michi Huber, Myron Marston) -* Fix verified doubles so that their methods match the visibility - (public, protected or private) of the interface they verify - against. (Myron Marston) -* Fix verified null object doubles so that they do not wrongly - report that they respond to anything. They only respond to methods - available on the interface they verify against. (Myron Marston) -* Fix deprecation warning for use of old `:should` syntax w/o explicit - config so that it no longer is silenced by an extension gem such - as rspec-rails when it calls `config.add_stub_and_should_receive_to`. - (Sam Phippen) -* Fix `expect` syntax so that it does not wrongly emit a "You're - overriding a previous implementation for this stub" warning when - you are not actually doing that. (Myron Marston) -* Fix `any_instance.unstub` when used on sub classes for whom the super - class has had `any_instance.stub` invoked on. (Jon Rowe) -* Fix regression in `stub_chain`/`receive_message_chain` that caused - it to raise an `ArgumentError` when passing args to the stubbed - methods. (Sam Phippen) -* Correct stub of undefined parent modules all the way down when stubbing a - nested constant. (Xavier Shay) -* Raise `VerifyingDoubleNotDefinedError` when a constant is not defined for - a verifying class double. (Maurício Linhares) -* Remove `Double#to_str`, which caused confusing `raise some_double` - behavior. (Maurício Linhares) - -### 3.0.0.beta1 / 2013-11-07 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.4...v3.0.0.beta1) - -Breaking Changes for 3.0.0: - -* Raise an explicit error if `should_not_receive(...).and_return` is used. (Sam - Phippen) -* Remove 1.8.6 workarounds. (Jon Rowe) -* Remove `stub!` and `unstub!`. (Sam Phippen) -* Remove `mock(name, methods)` and `stub(name, methods)`, leaving - `double(name, methods)` for creating test doubles. (Sam Phippen, Michi Huber) -* Remove `any_number_of_times` since `should_receive(:msg).any_number_of_times` - is really a stub in a mock's clothing. (Sam Phippen) -* Remove support for re-using the same null-object test double in multiple - examples. Test doubles are designed to only live for one example. - (Myron Marston) -* Make `at_least(0)` raise an error. (Sam Phippen) -* Remove support for `require 'spec/mocks'` which had been kept - in place for backwards compatibility with RSpec 1. (Myron Marston) -* Blocks provided to `with` are always used as implementation. (Xavier Shay) -* The config option (added in 2.99) to yield the receiver to - `any_instance` implementation blocks now defaults to "on". (Sam Phippen) - -Enhancements: - -* Allow the `have_received` matcher to use a block to set further expectations - on arguments. (Tim Cowlishaw) -* Provide `instance_double` and `class_double` to create verifying doubles, - ported from `rspec-fire`. (Xavier Shay) -* `as_null_object` on a verifying double only responds to defined methods. - (Xavier Shay) -* Provide `object_double` to create verified doubles of specific object - instances. (Xavier Shay) -* Provide `verify_partial_doubles` configuration that provides `object_double` - like verification behaviour on partial doubles. (Xavier Shay) -* Improved performance of double creation, particularly those with many - attributes. (Xavier Shay) -* Default value of `transfer_nested_constants` option for constant stubbing can - be configured. (Xavier Shay) -* Messages can be allowed or expected on in bulk via - `receive_messages(:message => :value)`. (Jon Rowe) -* `allow(Klass.any_instance)` and `expect(Klass.any_instance)` now print a - warning. This is usually a mistake, and users usually want - `allow_any_instance_of` or `expect_any_instance_of` instead. (Sam Phippen) -* `instance_double` and `class_double` raise `ArgumentError` if the underlying - module is loaded and the arity of the method being invoked does not match the - arity of the method as it is actually implemented. (Andy Lindeman) -* Spies can now check their invocation ordering is correct. (Jon Rowe) - -Deprecations: - -* Using the old `:should` syntax without explicitly configuring it - is deprecated. It will continue to work but will emit a deprecation - warning in RSpec 3 if you do not explicitly enable it. (Sam Phippen) - -Bug Fixes: - -* Fix `and_call_original` to handle a complex edge case involving - singleton class ancestors. (Marc-André Lafortune, Myron Marston) -* When generating an error message for unexpected arguments, - use `#inspect` rather than `#description` if `#description` - returns `nil` or `''` so that you still get a useful message. - (Nick DeLuca) - -### 2.99.4 / 2015-06-19 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.3...v2.99.4) - -Bug Fixes: - -* Add missing deprecation for using `with` with no arguments e.g. `with()`. (Yousuke, rspec/rspec-mocks#970) - -### 2.99.3 / 2015-01-09 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.2...v2.99.3) - -Bug Fixes: - -* Fix regression that caused an error when a test double was deserialized from YAML. (Yuji Nakayama, rspec/rspec-mocks#777) - -### 2.99.2 / 2014-07-21 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.1...v2.99.2) - -Enhancements: - -* Warn about upcoming change to `#===` matching and `DateTime#===` behaviour. - (Jon Rowe, rspec/rspec-mocks#735) - -### 2.99.1 / 2014-06-12 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0...v2.99.1) - -Bug Fixes: - -* Fix bug that caused errors at the end of each example - when a `double.as_null_object` had been frozen. (Yuji Nakayama, rspec/rspec-mocks#698) - -Deprecations: - -* Deprecate freezing a test double. (Yuji Nakayama, rspec/rspec-mocks#698) - -### 2.99.0 / 2014-06-01 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.rc1...v2.99.0) - -No changes. Just taking it out of pre-release. - -### 2.99.0.rc1 / 2014-05-18 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta2...v2.99.0.rc1) - -Deprecations: - -* Deprecate `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston) -* Deprecate `RSpec::Mocks::ConstantStubber`. (Jon Rowe) -* Deprecate `Marshal.dump` monkey-patch without opt-in. (Xavier Shay) - -### 2.99.0.beta2 / 2014-02-17 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta1...v2.99.0.beta2) - -Deprecations: - -* Deprecate `RSpec::Mocks::Mock` in favor of `RSpec::Mocks::Double`. - (Myron Marston) -* Deprecate the `host` argument of `RSpec::Mocks.setup`. Instead - `RSpec::Mocks::ExampleMethods` should be included directly in the scope where - RSpec's mocking capabilities are used. (Sam Phippen) -* Deprecate using any of rspec-mocks' features outside the per-test - lifecycle (e.g. from a `before(:all)` hook). (Myron Marston) -* Deprecate re-using a test double in another example. (Myron Marston) -* Deprecate `and_return { value }` and `and_return` without arguments. (Yuji Nakayama) - -### 2.99.0.beta1 / 2013-11-07 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.99.0.beta1) - -Deprecations - -* Expecting to use lambdas or other strong arity implementations for stub - methods with mis-matched arity is deprecated and support for them will be - removed in 3.0. Either provide the right amount of arguments or use a weak - arity implementation (methods with splats or procs). (Jon Rowe) -* Using the same test double instance in multiple examples is deprecated. Test - doubles are only meant to live for one example. The mocks and stubs have - always been reset between examples; however, in 2.x the `as_null_object` - state was not reset and some users relied on this to have a null object - double that is used for many examples. This behavior will be removed in 3.0. - (Myron Marston) -* Print a detailed warning when an `any_instance` implementation block is used - when the new `yield_receiver_to_any_instance_implementation_blocks` config - option is not explicitly set, as RSpec 3.0 will default to enabling this new - feature. (Sam Phippen) - -Enhancements: - -* Add a config option to yield the receiver to `any_instance` implementation - blocks. (Sam Phippen) - -### 2.14.6 / 2014-02-20 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.5...v2.14.6) - -Bug Fixes: - -* Ensure `any_instance` method stubs and expectations are torn down regardless of - expectation failures. (Sam Phippen) - -### 2.14.5 / 2014-02-01 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.14.5) - -Bug Fixes: - -* Fix regression that caused block implementations to not receive all - args on 1.8.7 if the block also receives a block, due to Proc#arity - reporting `1` no matter how many args the block receives if it - receives a block, too. (Myron Marston) - -### 2.14.4 / 2013-10-15 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.3...v2.14.4) - -Bug Fixes: - -* Fix issue where unstubing methods on "any instances" would not - remove stubs on existing instances (Jon Rowe) -* Fix issue with receive(:message) do ... end precedence preventing - the usage of modifications (`and_return` etc) (Jon Rowe) - -### 2.14.3 / 2013-08-08 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.2...v2.14.3) - -Bug Fixes: - -* Fix stubbing some instance methods for classes whose hierarchy includes - a prepended Module (Bradley Schaefer) - -### 2.14.2 / 2013-07-30 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.1...v2.14.2) - -Bug Fixes: - -* Fix `as_null_object` doubles so that they return `nil` from `to_ary` - (Jon Rowe). -* Fix regression in 2.14 that made `stub!` (with an implicit receiver) - return a test double rather than stub a method (Myron Marston). - -### 2.14.1 / 2013-07-07 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0...v2.14.1) - -Bug Fixes: - -* Restore `double.as_null_object` behavior from 2.13 and earlier: a - double's nullness persisted between examples in earlier examples. - While this is not an intended use case (test doubles are meant to live - for only one example), we don't want to break behavior users rely - on in a minor relase. This will be deprecated in 2.99 and removed - in 3.0. (Myron Marston) - -### 2.14.0 / 2013-07-06 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0.rc1...v2.14.0) - -Enhancements: - -* Document test spies in the readme. (Adarsh Pandit) -* Add an `array_including` matcher. (Sam Phippen) -* Add a syntax-agnostic API for mocking or stubbing a method. This is - intended for use by libraries such as rspec-rails that need to mock - or stub a method, and work regardless of the syntax the user has - configured (Paul Annesley, Myron Marston and Sam Phippen). - -Bug Fixes: - -* Fix `double` so that it sets up passed stubs correctly regardless of - the configured syntax (Paul Annesley). -* Allow a block implementation to be used in combination with - `and_yield`, `and_raise`, `and_return` or `and_throw`. This got fixed - in 2.13.1 but failed to get merged into master for the 2.14.0.rc1 - release (Myron Marston). -* `Marshal.dump` does not unnecessarily duplicate objects when rspec-mocks has - not been fully initialized. This could cause errors when using `spork` or - similar preloading gems (Andy Lindeman). - -### 2.14.0.rc1 / 2013-05-27 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.14.0.rc1) - -Enhancements: - -* Refactor internals so that the mock proxy methods and state are held - outside of the mocked object rather than inside it. This paves the way - for future syntax enhancements and removes the need for some hacky - work arounds for `any_instance` dup'ing and `YAML` serialization, - among other things. Note that the code now relies upon `__id__` - returning a unique, consistent value for any object you want to - mock or stub (Myron Marston). -* Add support for test spies. This allows you to verify a message - was received afterwards using the `have_received` matcher. - Note that you must first stub the method or use a null double. - (Joe Ferris and Joël Quenneville) -* Make `at_least` and `at_most` style receive expectations print that they were - expecting at least or at most some number of calls, rather than just the - number of calls given in the expectation (Sam Phippen) -* Make `with` style receive expectations print the args they were expecting, and - the args that they got (Sam Phippen) -* Fix some warnings seen under ruby 2.0.0p0 (Sam Phippen). -* Add a new `:expect` syntax for message expectations - (Myron Marston and Sam Phippen). - -Bug fixes - -* Fix `any_instance` so that a frozen object can be `dup`'d when methods - have been stubbed on that type using `any_instance` (Jon Rowe). -* Fix `and_call_original` so that it properly raises an `ArgumentError` - when the wrong number of args are passed (Jon Rowe). -* Fix `double` on 1.9.2 so you can wrap them in an Array - using `Array(my_double)` (Jon Rowe). -* Fix `stub_const` and `hide_const` to handle constants that redefine `send` - (Sam Phippen). -* Fix `Marshal.dump` extension so that it correctly handles nil. - (Luke Imhoff, Jon Rowe) -* Fix isolation of `allow_message_expectations_on_nil` (Jon Rowe) -* Use inspect to format actual arguments on expectations in failure messages (rspec/rspec-mocks#280, Ben Langfeld) -* Protect against improperly initialised test doubles (rspec/rspec-mocks#293) (Joseph Shraibman and Jon Rowe) - -Deprecations - -* Deprecate `stub` and `mock` as aliases for `double`. `double` is the - best term for creating a test double, and it reduces confusion to - have only one term (Michi Huber). -* Deprecate `stub!` and `unstub!` in favor of `stub` and `unstub` - (Jon Rowe). -* Deprecate `at_least(0).times` and `any_number_of_times` (Michi Huber). - -### 2.13.1 / 2013-04-06 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.13.1) - -Bug fixes - -* Allow a block implementation to be used in combination with - `and_yield`, `and_raise`, `and_return` or `and_throw` (Myron Marston). - -### 2.13.0 / 2013-02-23 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.2...v2.13.0) - -Bug fixes - -* Fix bug that caused weird behavior when a method that had - previously been stubbed with multiple return values (e.g. - `obj.stub(:foo).and_return(1, 2)`) was later mocked with a - single return value (e.g. `obj.should_receive(:foo).once.and_return(1)`). - (Myron Marston) -* Fix bug related to a mock expectation for a method that already had - multiple stubs with different `with` constraints. Previously, the - first stub was used, even though it may not have matched the passed - args. The fix defers this decision until the message is received so - that the proper stub response can be chosen based on the passed - arguments (Myron Marston). -* Do not call `nil?` extra times on a mocked object, in case `nil?` - itself is expected a set number of times (Myron Marston). -* Fix `missing_default_stub_error` message so array args are handled - properly (Myron Marston). -* Explicitly disallow `any_instance.unstub!` (Ryan Jones). -* Fix `any_instance` stubbing so that it works with `Delegator` - subclasses (Myron Marston). -* Fix `and_call_original` so that it works with `Delegator` subclasses - (Myron Marston). -* Fix `any_instance.should_not_receive` when `any_instance.should_receive` - is used on the same class in the same example. Previously it would - wrongly report a failure even when the message was not received - (Myron Marston). - -### 2.12.2 / 2013-01-27 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.1...v.2.12.2) - -Bug fixes - -* Fix `and_call_original` to work properly for methods defined - on a module extended onto an object instance (Myron Marston). -* Fix `stub_const` with an undefined constnat name to work properly - with constant strings that are prefixed with `::` -- and edge case - I missed in the bug fix in the 2.12.1 release (Myron Marston). -* Ensure method visibility on a partial mock is restored after reseting - method stubs, even on a singleton module (created via `extend self`) - when the method visibility differs between the instance and singleton - versions (Andy Lindeman). - -### 2.12.1 / 2012-12-21 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.0...v2.12.1) - -Bug fixes - -* Fix `any_instance` to support `and_call_original`. - (Myron Marston) -* Properly restore stubbed aliased methods on rubies - that report the incorrect owner (Myron Marston and Andy Lindeman). -* Fix `hide_const` and `stub_const` with a defined constnat name to - work properly with constant strings that are prefixed with `::` (Myron Marston). - -### 2.12.0 / 2012-11-12 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.3...v2.12.0) - -Enhancements - -* `and_raise` can accept an exception class and message, more closely - matching `Kernel#raise` (e.g., `foo.stub(:bar).and_raise(RuntimeError, "message")`) - (Bas Vodde) -* Add `and_call_original`, which will delegate the message to the - original method (Myron Marston). - -Deprecations: - -* Add deprecation warning when using `and_return` with `should_not_receive` - (Neha Kumari) - -### 2.11.3 / 2012-09-19 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.2...v2.11.3) - -Bug fixes - -* Fix `:transfer_nested_constants` option of `stub_const` so that it - doesn't blow up when there are inherited constants. (Myron Marston) -* `any_instance` stubs can be used on classes that override `Object#method`. - (Andy Lindeman) -* Methods stubbed with `any_instance` are unstubbed after the test finishes. - (Andy Lindeman) -* Fix confusing error message when calling a mocked class method an - extra time with the wrong arguments (Myron Marston). - -### 2.11.2 / 2012-08-11 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.1...v2.11.2) - -Bug fixes - -* Don't modify `dup` on classes that don't support `dup` (David Chelimsky) -* Fix `any_instance` so that it works properly with methods defined on - a superclass. (Daniel Eguzkiza) -* Fix `stub_const` so that it works properly for nested constants that - share a name with a top-level constant (e.g. "MyGem::Hash"). (Myron - Marston) - -### 2.11.1 / 2012-07-09 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.0...v2.11.1) - -Bug fixes - -* Fix `should_receive` so that when it is called on an `as_null_object` - double with no implementation, and there is a previous explicit stub - for the same method, the explicit stub remains (rather than being - overridden with the null object implementation--`return self`). (Myron - Marston) - -### 2.11.0 / 2012-07-07 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.1...v2.11.0) - -Enhancements - -* Expose ArgumentListMatcher as a formal API - * supports use by 3rd party mock frameworks like Surrogate -* Add `stub_const` API to stub constants for the duration of an - example (Myron Marston). - -Bug fixes - -* Fix regression of edge case behavior. `double.should_receive(:foo) { a }` - was causing a NoMethodError when `double.stub(:foo).and_return(a, b)` - had been setup before (Myron Marston). -* Infinite loop generated by using `any_instance` and `dup`. (Sidu Ponnappa @kaiwren) -* `double.should_receive(:foo).at_least(:once).and_return(a)` always returns a - even if `:foo` is already stubbed. -* Prevent infinite loop when interpolating a null double into a string - as an integer (`"%i" % double.as_null_object`). (Myron Marston) -* Fix `should_receive` so that null object behavior (e.g. returning - self) is preserved if no implementation is given (Myron Marston). -* Fix `and_raise` so that it raises `RuntimeError` rather than - `Exception` by default, just like ruby does. (Andrew Marshall) - -### 2.10.1 / 2012-05-05 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.0...v2.10.1) - -Bug fixes - -* fix regression of edge case behavior - (https://github.com/rspec/rspec-mocks/issues/132) - * fixed failure of `object.should_receive(:message).at_least(0).times.and_return value` - * fixed failure of `object.should_not_receive(:message).and_return value` - -### 2.10.0 / 2012-05-03 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.9.0...v2.10.0) - -Bug fixes - -* fail fast when an `exactly` or `at_most` expectation is exceeded - -### 2.9.0 / 2012-03-17 -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0...v2.9.0) - -Enhancements - -* Support order constraints across objects (preethiramdev) - -Bug fixes - -* Allow a `as_null_object` to be passed to `with` -* Pass proc to block passed to stub (Aubrey Rhodes) -* Initialize child message expectation args to match any args (rspec/rspec-mocks#109 - - preethiramdev) - -### 2.8.0 / 2012-01-04 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc2...v2.8.0) - -No changes for this release. Just releasing with the other rspec gems. - -### 2.8.0.rc2 / 2011-12-19 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc1...v2.8.0.rc2) - -No changes for this release. Just releasing with the other rspec gems. - -### 2.8.0.rc1 / 2011-11-06 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.7.0...v2.8.0.rc1) - -Enhancements - -* Eliminate Ruby warnings (Matijs van Zuijlen) - -### 2.7.0 / 2011-10-16 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.6.0...v2.7.0) - -Enhancements - -* Use `__send__` rather than `send` (alextk) -* Add support for `any_instance.stub_chain` (Sidu Ponnappa) -* Add support for `any_instance` argument matching based on `with` (Sidu - Ponnappa and Andy Lindeman) - -Changes - -* Check for `failure_message_for_should` or `failure_message` instead of - `description` to detect a matcher (Tibor Claassen) - -Bug fixes - -* pass a hash to `any_instance.stub`. (Justin Ko) -* allow `to_ary` to be called without raising `NoMethodError` (Mikhail - Dieterle) -* `any_instance` properly restores private methods (Sidu Ponnappa) - -### 2.6.0 / 2011-05-12 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.5.0...v2.6.0) - -Enhancements - -* Add support for `any_instance.stub` and `any_instance.should_receive` (Sidu - Ponnappa and Andy Lindeman) - -Bug fixes - -* fix bug in which multiple chains with shared messages ending in hashes failed - to return the correct value - -### 2.5.0 / 2011-02-05 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.4.0...v2.5.0) - -Bug fixes - -* message expectation counts now work in combination with a stub (Damian - Nurzynski) -* fix failure message when message received with incorrect args (Josep M. - Bach) - -### 2.4.0 / 2011-01-02 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.3.0...v2.4.0) - -No functional changes in this release, which was made to align with the -rspec-core-2.4.0 release. - -### 2.3.0 / 2010-12-12 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.2.0...v2.3.0) - -Bug fixes - -* Fix our Marshal extension so that it does not interfere with objects that - have their own `@mock_proxy` instance variable. (Myron Marston) - -### 2.2.0 / 2010-11-28 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.1.0...v2.2.0) - -Enhancements - -* Added "rspec/mocks/standalone" for exploring the rspec-mocks in irb. - -Bug fix - -* Eliminate warning on splat args without parens (Gioele Barabucci) -* Fix bug where `obj.should_receive(:foo).with(stub.as_null_object)` would pass - with a false positive. - -### 2.1.0 / 2010-11-07 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.1...v2.1.0) - -Bug fixes - -* Fix serialization of stubbed object (Josep M Bach) - -### 2.0.0 / 2010-10-10 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0) - -### 2.0.0.rc / 2010-10-05 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0.rc) - -Enhancements - -* support passing a block to an expectation block (Nicolas Braem) - * `obj.should_receive(:msg) {|&block| ... }` - -Bug fixes - -* Fix YAML serialization of stub (Myron Marston) -* Fix rdoc rake task (Hans de Graaff) - -### 2.0.0.beta.22 / 2010-09-12 - -[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.20...v2.0.0.beta.22) - -Bug fixes - -* fixed regression that broke `obj.stub_chain(:a, :b => :c)` -* fixed regression that broke `obj.stub_chain(:a, :b) { :c }` -* `respond_to?` always returns true when using `as_null_object` diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md deleted file mode 100644 index dae02d8..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/LICENSE.md +++ /dev/null @@ -1,25 +0,0 @@ -The MIT License (MIT) -===================== - -* Copyright © 2012 David Chelimsky, Myron Marston -* Copyright © 2006 David Chelimsky, The RSpec Development Team -* Copyright © 2005 Steven Baker - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md deleted file mode 100644 index e569fee..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/README.md +++ /dev/null @@ -1,465 +0,0 @@ -# RSpec Mocks [![Build Status](https://github.com/rspec/rspec-mocks/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-mocks/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.svg)](https://codeclimate.com/github/rspec/rspec-mocks) -rspec-mocks is a test-double framework for rspec with support for method stubs, -fakes, and message expectations on generated test-doubles and real objects -alike. - -## Install - - gem install rspec # for rspec-core, rspec-expectations, rspec-mocks - gem install rspec-mocks # for rspec-mocks only - -Want to run against the `main` branch? You'll need to include the dependent -RSpec repos as well. Add the following to your `Gemfile`: - -```ruby -%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| - gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' -end -``` -## Contributing - -Once you've set up the environment, you'll need to cd into the working -directory of whichever repo you want to work in. From there you can run the -specs and cucumber features, and make patches. - -NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You -can treat each RSpec repo as an independent project. - -For information about contributing to RSpec, please refer to the following markdown files: -* [Build details](BUILD_DETAIL.md) -* [Code of Conduct](CODE_OF_CONDUCT.md) -* [Detailed contributing guide](CONTRIBUTING.md) -* [Development setup guide](DEVELOPMENT.md) - -## Test Doubles - -A test double is an object that stands in for another object in your system -during a code example. Use the `double` method, passing in an optional identifier, to create one: - -```ruby -book = double("book") -``` - -Most of the time you will want some confidence that your doubles resemble an -existing object in your system. Verifying doubles are provided for this -purpose. If the existing object is available, they will prevent you from adding -stubs and expectations for methods that do not exist or that have an invalid -number of parameters. - -```ruby -book = instance_double("Book", :pages => 250) -``` - -Verifying doubles have some clever tricks to enable you to both test in -isolation without your dependencies loaded while still being able to validate -them against real objects. More detail is available in [their -documentation](https://github.com/rspec/rspec-mocks/blob/main/features/verifying_doubles). - -Verifying doubles can also accept custom identifiers, just like double(), e.g.: - -```ruby -books = [] -books << instance_double("Book", :rspec_book, :pages => 250) -books << instance_double("Book", "(Untitled)", :pages => 5000) - -puts books.inspect # with names, it's clearer which were actually added -``` - -## Method Stubs - -A method stub is an implementation that returns a pre-determined value. Method -stubs can be declared on test doubles or real objects using the same syntax. -rspec-mocks supports 3 forms for declaring method stubs: - -```ruby -allow(book).to receive(:title) { "The RSpec Book" } -allow(book).to receive(:title).and_return("The RSpec Book") -allow(book).to receive_messages( - :title => "The RSpec Book", - :subtitle => "Behaviour-Driven Development with RSpec, Cucumber, and Friends") -``` - -You can also use this shortcut, which creates a test double and declares a -method stub in one statement: - -```ruby -book = double("book", :title => "The RSpec Book") -``` - -The first argument is a name, which is used for documentation and appears in -failure messages. If you don't care about the name, you can leave it out, -making the combined instantiation/stub declaration very terse: - -```ruby -double(:foo => 'bar') -``` - -This is particularly nice when providing a list of test doubles to a method -that iterates through them: - -```ruby -order.calculate_total_price(double(:price => 1.99), double(:price => 2.99)) -``` - -### Stubbing a chain of methods - -You can use `receive_message_chain` in place of `receive` to stub a chain of messages: - -```ruby -allow(double).to receive_message_chain("foo.bar") { :baz } -allow(double).to receive_message_chain(:foo, :bar => :baz) -allow(double).to receive_message_chain(:foo, :bar) { :baz } - -# Given any of the above forms: -double.foo.bar # => :baz -``` - -Chains can be arbitrarily long, which makes it quite painless to violate the Law of Demeter in violent ways, so you should consider any use of `receive_message_chain` a code smell. Even though not all code smells indicate real problems (think fluent interfaces), `receive_message_chain` still results in brittle examples. For example, if you write `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the implementation calls `foo.baz.bar`, the stub will not work. - -## Consecutive return values - -When a stub might be invoked more than once, you can provide additional -arguments to `and_return`. The invocations cycle through the list. The last -value is returned for any subsequent invocations: - -```ruby -allow(die).to receive(:roll).and_return(1, 2, 3) -die.roll # => 1 -die.roll # => 2 -die.roll # => 3 -die.roll # => 3 -die.roll # => 3 -``` - -To return an array in a single invocation, declare an array: - -```ruby -allow(team).to receive(:players).and_return([double(:name => "David")]) -``` - -## Message Expectations - -A message expectation is an expectation that the test double will receive a -message some time before the example ends. If the message is received, the -expectation is satisfied. If not, the example fails. - -```ruby -validator = double("validator") -expect(validator).to receive(:validate) { "02134" } -zipcode = Zipcode.new("02134", validator) -zipcode.valid? -``` - -## Test Spies - -Verifies the given object received the expected message during the course of -the test. For a message to be verified, the given object must be setup to spy -on it, either by having it explicitly stubbed or by being a null object double -(e.g. `double(...).as_null_object`). Convenience methods are provided to easily -create null object doubles for this purpose: - -```ruby -spy("invitation") # => same as `double("invitation").as_null_object` -instance_spy("Invitation") # => same as `instance_double("Invitation").as_null_object` -class_spy("Invitation") # => same as `class_double("Invitation").as_null_object` -object_spy("Invitation") # => same as `object_double("Invitation").as_null_object` -``` - -Verifying messages received in this way implements the Test Spy pattern. - -```ruby -invitation = spy('invitation') - -user.accept_invitation(invitation) - -expect(invitation).to have_received(:accept) - -# You can also use other common message expectations. For example: -expect(invitation).to have_received(:accept).with(mailer) -expect(invitation).to have_received(:accept).twice -expect(invitation).to_not have_received(:accept).with(mailer) - -# One can specify a return value on the spy the same way one would a double. -invitation = spy('invitation', :accept => true) -expect(invitation).to have_received(:accept).with(mailer) -expect(invitation.accept).to eq(true) -``` - -Note that `have_received(...).with(...)` is unable to work properly when -passed arguments are mutated after the spy records the received message. -For example, this does not work properly: - -```ruby -greeter = spy("greeter") - -message = "Hello" -greeter.greet_with(message) -message << ", World" - -expect(greeter).to have_received(:greet_with).with("Hello") -``` - -## Nomenclature - -### Mock Objects and Test Stubs - -The names Mock Object and Test Stub suggest specialized Test Doubles. i.e. -a Test Stub is a Test Double that only supports method stubs, and a Mock -Object is a Test Double that supports message expectations and method -stubs. - -There is a lot of overlapping nomenclature here, and there are many -variations of these patterns (fakes, spies, etc). Keep in mind that most of -the time we're talking about method-level concepts that are variations of -method stubs and message expectations, and we're applying to them to _one_ -generic kind of object: a Test Double. - -### Test-Specific Extension - -a.k.a. Partial Double, a Test-Specific Extension is an extension of a -real object in a system that is instrumented with test-double like -behaviour in the context of a test. This technique is very common in Ruby -because we often see class objects acting as global namespaces for methods. -For example, in Rails: - -```ruby -person = double("person") -allow(Person).to receive(:find) { person } -``` - -In this case we're instrumenting Person to return the person object we've -defined whenever it receives the `find` message. We can also set a message -expectation so that the example fails if `find` is not called: - -```ruby -person = double("person") -expect(Person).to receive(:find) { person } -``` - -RSpec replaces the method we're stubbing or mocking with its own -test-double-like method. At the end of the example, RSpec verifies any message -expectations, and then restores the original methods. - -## Expecting Arguments - -```ruby -expect(double).to receive(:msg).with(*args) -expect(double).to_not receive(:msg).with(*args) -``` - -You can set multiple expectations for the same message if you need to: - -```ruby -expect(double).to receive(:msg).with("A", 1, 3) -expect(double).to receive(:msg).with("B", 2, 4) -``` - -## Argument Matchers - -Arguments that are passed to `with` are compared with actual arguments -received using ===. In cases in which you want to specify things about the -arguments rather than the arguments themselves, you can use any of the -matchers that ship with rspec-expectations. They don't all make syntactic -sense (they were primarily designed for use with RSpec::Expectations), but -you are free to create your own custom RSpec::Matchers. - -rspec-mocks also adds some keyword Symbols that you can use to -specify certain kinds of arguments: - -```ruby -expect(double).to receive(:msg).with(no_args) -expect(double).to receive(:msg).with(any_args) -expect(double).to receive(:msg).with(1, any_args) # any args acts like an arg splat and can go anywhere -expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric -expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false -expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp -expect(double).to receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all -expect(double).to receive(:msg).with(1, duck_type(:abs, :div), "b") #2nd argument can be object that responds to #abs and #div -expect(double).to receive(:msg).with(hash_including(:a => 5)) # first arg is a hash with a: 5 as one of the key-values -expect(double).to receive(:msg).with(array_including(5)) # first arg is an array with 5 as one of the key-values -expect(double).to receive(:msg).with(hash_excluding(:a => 5)) # first arg is a hash without a: 5 as one of the key-values -expect(double).to receive(:msg).with(start_with('a')) # any matcher, custom or from rspec-expectations -expect(double).to receive(:msg).with(satisfy { |data| data.dig(:a, :b, :c) == 5 }) # assert anything you want -``` - -## Receive Counts - -```ruby -expect(double).to receive(:msg).once -expect(double).to receive(:msg).twice -expect(double).to receive(:msg).exactly(n).time -expect(double).to receive(:msg).exactly(n).times -expect(double).to receive(:msg).at_least(:once) -expect(double).to receive(:msg).at_least(:twice) -expect(double).to receive(:msg).at_least(n).time -expect(double).to receive(:msg).at_least(n).times -expect(double).to receive(:msg).at_most(:once) -expect(double).to receive(:msg).at_most(:twice) -expect(double).to receive(:msg).at_most(n).time -expect(double).to receive(:msg).at_most(n).times -``` - -## Ordering - -```ruby -expect(double).to receive(:msg).ordered -expect(double).to receive(:other_msg).ordered - # This will fail if the messages are received out of order -``` - -This can include the same message with different arguments: - -```ruby -expect(double).to receive(:msg).with("A", 1, 3).ordered -expect(double).to receive(:msg).with("B", 2, 4).ordered -``` - -## Setting Responses - -Whether you are setting a message expectation or a method stub, you can -tell the object precisely how to respond. The most generic way is to pass -a block to `receive`: - -```ruby -expect(double).to receive(:msg) { value } -``` - -When the double receives the `msg` message, it evaluates the block and returns -the result. - -```ruby -expect(double).to receive(:msg).and_return(value) -expect(double).to receive(:msg).exactly(3).times.and_return(value1, value2, value3) - # returns value1 the first time, value2 the second, etc -expect(double).to receive(:msg).and_raise(error) - # `error` can be an instantiated object (e.g. `StandardError.new(some_arg)`) or a class (e.g. `StandardError`) - # if it is a class, it must be instantiable with no args -expect(double).to receive(:msg).and_throw(:msg) -expect(double).to receive(:msg).and_yield(values, to, yield) -expect(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time) - # for methods that yield to a block multiple times -``` - -Any of these responses can be applied to a stub as well - -```ruby -allow(double).to receive(:msg).and_return(value) -allow(double).to receive(:msg).and_return(value1, value2, value3) -allow(double).to receive(:msg).and_raise(error) -allow(double).to receive(:msg).and_throw(:msg) -allow(double).to receive(:msg).and_yield(values, to, yield) -allow(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time) -``` - -## Arbitrary Handling - -Once in a while you'll find that the available expectations don't solve the -particular problem you are trying to solve. Imagine that you expect the message -to come with an Array argument that has a specific length, but you don't care -what is in it. You could do this: - -```ruby -expect(double).to receive(:msg) do |arg| - expect(arg.size).to eq 7 -end -``` - -If the method being stubbed itself takes a block, and you need to yield to it -in some special way, you can use this: - -```ruby -expect(double).to receive(:msg) do |&arg| - begin - arg.call - ensure - # cleanup - end -end -``` - -## Delegating to the Original Implementation - -When working with a partial mock object, you may occasionally -want to set a message expectation without interfering with how -the object responds to the message. You can use `and_call_original` -to achieve this: - -```ruby -expect(Person).to receive(:find).and_call_original -Person.find # => executes the original find method and returns the result -``` - -## Combining Expectation Details - -Combining the message name with specific arguments, receive counts and responses -you can get quite a bit of detail in your expectations: - -```ruby -expect(double).to receive(:<<).with("illegal value").once.and_raise(ArgumentError) -``` - -While this is a good thing when you really need it, you probably don't really -need it! Take care to specify only the things that matter to the behavior of -your code. - -## Stubbing and Hiding Constants - -See the [mutating constants -README](https://github.com/rspec/rspec-mocks/blob/main/features/mutating_constants/README.md) -for info on this feature. - -## Use `before(:example)`, not `before(:context)` - -Stubs in `before(:context)` are not supported. The reason is that all stubs and mocks get cleared out after each example, so any stub that is set in `before(:context)` would work in the first example that happens to run in that group, but not for any others. - -Instead of `before(:context)`, use `before(:example)`. - -## Settings mocks or stubs on any instance of a class - -rspec-mocks provides two methods, `allow_any_instance_of` and -`expect_any_instance_of`, that will allow you to stub or mock any instance -of a class. They are used in place of `allow` or `expect`: - -```ruby -allow_any_instance_of(Widget).to receive(:name).and_return("Wibble") -expect_any_instance_of(Widget).to receive(:name).and_return("Wobble") -``` - -These methods add the appropriate stub or expectation to all instances of -`Widget`. - -This feature is sometimes useful when working with legacy code, though in -general we discourage its use for a number of reasons: - -* The `rspec-mocks` API is designed for individual object instances, but this - feature operates on entire classes of objects. As a result there are some - semantically confusing edge cases. For example in - `expect_any_instance_of(Widget).to receive(:name).twice` it isn't clear - whether each specific instance is expected to receive `name` twice, or if two - receives total are expected. (It's the former.) -* Using this feature is often a design smell. It may be - that your test is trying to do too much or that the object under test is too - complex. -* It is the most complicated feature of `rspec-mocks`, and has historically - received the most bug reports. (None of the core team actively use it, - which doesn't help.) - - -## Further Reading - -There are many different viewpoints about the meaning of mocks and stubs. If -you are interested in learning more, here is some recommended reading: - -* Mock Objects: http://www.mockobjects.com/ -* Endo-Testing: http://www.ccs.neu.edu/research/demeter/related-work/extreme-programming/MockObjectsFinal.PDF -* Mock Roles, Not Objects: http://www.jmock.org/oopsla2004.pdf -* Test Double: http://www.martinfowler.com/bliki/TestDouble.html -* Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html -* Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html - -## Also see - -* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) -* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) -* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations) -* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb deleted file mode 100644 index 297779e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks.rb +++ /dev/null @@ -1,133 +0,0 @@ -require 'rspec/support' -RSpec::Support.require_rspec_support 'caller_filter' -RSpec::Support.require_rspec_support 'warnings' -RSpec::Support.require_rspec_support 'ruby_features' - -RSpec::Support.define_optimized_require_for_rspec(:mocks) { |f| require_relative f } - -%w[ - instance_method_stasher - method_double - argument_matchers - example_methods - proxy - test_double - argument_list_matcher - message_expectation - order_group - error_generator - space - mutate_const - targets - syntax - configuration - verifying_double - version -].each { |name| RSpec::Support.require_rspec_mocks name } - -# Share the top-level RSpec namespace, because we are a core supported -# extension. -module RSpec - # Contains top-level utility methods. While this contains a few - # public methods, these are not generally meant to be called from - # a test or example. They exist primarily for integration with - # test frameworks (such as rspec-core). - module Mocks - # Performs per-test/example setup. This should be called before - # an test or example begins. - def self.setup - @space_stack << (@space = space.new_scope) - end - - # Verifies any message expectations that were set during the - # test or example. This should be called at the end of an example. - def self.verify - space.verify_all - end - - # Cleans up all test double state (including any methods that were - # redefined on partial doubles). This _must_ be called after - # each example, even if an error was raised during the example. - def self.teardown - space.reset_all - @space_stack.pop - @space = @space_stack.last || @root_space - end - - # Adds an allowance (stub) on `subject` - # - # @param subject the subject to which the message will be added - # @param message a symbol, representing the message that will be - # added. - # @param opts a hash of options, :expected_from is used to set the - # original call site - # @yield an optional implementation for the allowance - # - # @example Defines the implementation of `foo` on `bar`, using the passed block - # x = 0 - # RSpec::Mocks.allow_message(bar, :foo) { x += 1 } - def self.allow_message(subject, message, opts={}, &block) - space.proxy_for(subject).add_stub(message, opts, &block) - end - - # Sets a message expectation on `subject`. - # @param subject the subject on which the message will be expected - # @param message a symbol, representing the message that will be - # expected. - # @param opts a hash of options, :expected_from is used to set the - # original call site - # @yield an optional implementation for the expectation - # - # @example Expect the message `foo` to receive `bar`, then call it - # RSpec::Mocks.expect_message(bar, :foo) - # bar.foo - def self.expect_message(subject, message, opts={}, &block) - space.proxy_for(subject).add_message_expectation(message, opts, &block) - end - - # Call the passed block and verify mocks after it has executed. This allows - # mock usage in arbitrary places, such as a `before(:all)` hook. - # - # @return [Object] the return value from the block - def self.with_temporary_scope - setup - - begin - result = yield - verify - result - ensure - teardown - end - end - - class << self - # @private - attr_reader :space - end - @space_stack = [] - @root_space = @space = RSpec::Mocks::RootSpace.new - - # @private - IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored' - - # To speed up boot time a bit, delay loading optional or rarely - # used features until their first use. - autoload :AnyInstance, "rspec/mocks/any_instance" - autoload :ExpectChain, "rspec/mocks/message_chain" - autoload :StubChain, "rspec/mocks/message_chain" - autoload :MarshalExtension, "rspec/mocks/marshal_extension" - - # Namespace for mock-related matchers. - module Matchers - # @private - # just a "tag" for rspec-mock matchers detection - module Matcher; end - - autoload :HaveReceived, "rspec/mocks/matchers/have_received" - autoload :Receive, "rspec/mocks/matchers/receive" - autoload :ReceiveMessageChain, "rspec/mocks/matchers/receive_message_chain" - autoload :ReceiveMessages, "rspec/mocks/matchers/receive_messages" - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb deleted file mode 100644 index 41eae81..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance.rb +++ /dev/null @@ -1,11 +0,0 @@ -%w[ - any_instance/chain - any_instance/error_generator - any_instance/stub_chain - any_instance/stub_chain_chain - any_instance/expect_chain_chain - any_instance/expectation_chain - any_instance/message_chains - any_instance/recorder - any_instance/proxy -].each { |f| RSpec::Support.require_rspec_mocks(f) } diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb deleted file mode 100644 index 74d864b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/chain.rb +++ /dev/null @@ -1,111 +0,0 @@ -module RSpec - module Mocks - # @private - module AnyInstance - # @private - class Chain - def initialize(recorder, *args, &block) - @recorder = recorder - @expectation_args = args - @expectation_block = block - @argument_list_matcher = ArgumentListMatcher::MATCH_ALL - end - - # @private - # - # Provides convenience methods for recording customizations on message - # expectations. - module Customizations - # @macro [attach] record - # @method $1(*args, &block) - # Records the `$1` message for playback against an instance that - # invokes a method stubbed or mocked using `any_instance`. - # - # @see RSpec::Mocks::MessageExpectation#$1 - # - def self.record(method_name) - define_method(method_name) do |*args, &block| - record(method_name, *args, &block) - end - end - - record :and_return - record :and_raise - record :and_throw - record :and_yield - record :and_call_original - record :and_wrap_original - record :with - record :once - record :twice - record :thrice - record :exactly - record :times - record :time - record :never - record :at_least - record :at_most - end - - include Customizations - - # @private - def playback!(instance) - message_expectation = create_message_expectation_on(instance) - messages.inject(message_expectation) do |object, message| - object.__send__(*message.first, &message.last) - end - end - - # @private - def constrained_to_any_of?(*constraints) - constraints.any? do |constraint| - messages.any? do |message| - message.first.first == constraint - end - end - end - - # @private - def matches_args?(*args) - @argument_list_matcher.args_match?(*args) - end - - # @private - def expectation_fulfilled! - @expectation_fulfilled = true - end - - def never - AnyInstance.error_generator.raise_double_negation_error("expect_any_instance_of(MyClass)") if negated? - super - end - - def with(*args, &block) - @argument_list_matcher = ArgumentListMatcher.new(*args) - super - end - - private - - def negated? - messages.any? { |(message, *_), _| message == :never } - end - - def messages - @messages ||= [] - end - - def last_message - messages.last.first.first unless messages.empty? - end - - def record(rspec_method_name, *args, &block) - verify_invocation_order(rspec_method_name, *args, &block) - messages << [args.unshift(rspec_method_name), block] - self - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb deleted file mode 100644 index d1046cb..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/error_generator.rb +++ /dev/null @@ -1,31 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # @private - class ErrorGenerator < ::RSpec::Mocks::ErrorGenerator - def raise_second_instance_received_message_error(unfulfilled_expectations) - __raise "Exactly one instance should have received the following " \ - "message(s) but didn't: #{unfulfilled_expectations.sort.join(', ')}" - end - - def raise_does_not_implement_error(klass, method_name) - __raise "#{klass} does not implement ##{method_name}" - end - - def raise_message_already_received_by_other_instance_error(method_name, object_inspect, invoked_instance) - __raise "The message '#{method_name}' was received by #{object_inspect} " \ - "but has already been received by #{invoked_instance}" - end - - def raise_not_supported_with_prepend_error(method_name, problem_mod) - __raise "Using `any_instance` to stub a method (#{method_name}) that has been " \ - "defined on a prepended module (#{problem_mod}) is not supported." - end - end - - def self.error_generator - @error_generator ||= ErrorGenerator.new - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb deleted file mode 100644 index c467ba9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expect_chain_chain.rb +++ /dev/null @@ -1,31 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # @private - class ExpectChainChain < StubChain - def initialize(*args) - super - @expectation_fulfilled = false - end - - def expectation_fulfilled? - @expectation_fulfilled - end - - def playback!(instance) - super.tap { @expectation_fulfilled = true } - end - - private - - def create_message_expectation_on(instance) - ::RSpec::Mocks::ExpectChain.expect_chain_on(instance, *@expectation_args, &@expectation_block) - end - - def invocation_order - EmptyInvocationOrder - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb deleted file mode 100644 index edf8548..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/expectation_chain.rb +++ /dev/null @@ -1,50 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # @private - class ExpectationChain < Chain - def expectation_fulfilled? - @expectation_fulfilled || constrained_to_any_of?(:never) - end - - def initialize(*args, &block) - @expectation_fulfilled = false - super - end - - private - - def verify_invocation_order(_rspec_method_name, *_args, &_block) - end - end - - # @private - class PositiveExpectationChain < ExpectationChain - private - - def create_message_expectation_on(instance) - proxy = ::RSpec::Mocks.space.proxy_for(instance) - method_name, opts = @expectation_args - opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE) - - me = proxy.add_message_expectation(method_name, opts, &@expectation_block) - if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks? - me.and_yield_receiver_to_implementation - end - - me - end - - ExpectationInvocationOrder = - { - :and_return => [:with, nil], - :and_raise => [:with, nil], - }.freeze - - def invocation_order - ExpectationInvocationOrder - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb deleted file mode 100644 index 7f4d770..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/message_chains.rb +++ /dev/null @@ -1,83 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # @private - class MessageChains - def initialize - @chains_by_method_name = Hash.new { |h, k| h[k] = [] } - end - - # @private - def [](method_name) - @chains_by_method_name[method_name] - end - - # @private - def add(method_name, chain) - @chains_by_method_name[method_name] << chain - chain - end - - # @private - def remove_stub_chains_for!(method_name) - @chains_by_method_name[method_name].reject! do |chain| - StubChain === chain - end - end - - # @private - def has_expectation?(method_name) - @chains_by_method_name[method_name].find do |chain| - ExpectationChain === chain - end - end - - # @private - def each_unfulfilled_expectation_matching(method_name, *args) - @chains_by_method_name[method_name].each do |chain| - yield chain if !chain.expectation_fulfilled? && chain.matches_args?(*args) - end - end - - # @private - def all_expectations_fulfilled? - @chains_by_method_name.all? do |_method_name, chains| - chains.all? { |chain| chain.expectation_fulfilled? } - end - end - - # @private - def unfulfilled_expectations - @chains_by_method_name.map do |method_name, chains| - method_name.to_s if ExpectationChain === chains.last && !chains.last.expectation_fulfilled? - end.compact - end - - # @private - def received_expected_message!(method_name) - @chains_by_method_name[method_name].each do |chain| - chain.expectation_fulfilled! - end - end - - # @private - def playback!(instance, method_name) - raise_if_second_instance_to_receive_message(instance) - @chains_by_method_name[method_name].each do |chain| - chain.playback!(instance) - end - end - - private - - def raise_if_second_instance_to_receive_message(instance) - @instance_with_expectation ||= instance if ExpectationChain === instance - return unless ExpectationChain === instance - return if @instance_with_expectation.equal?(instance) - - AnyInstance.error_generator.raise_second_instance_received_message_error(unfulfilled_expectations) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb deleted file mode 100644 index 54ded05..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/proxy.rb +++ /dev/null @@ -1,125 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # @private - # The `AnyInstance::Recorder` is responsible for redefining the klass's - # instance method in order to add any stubs/expectations the first time - # the method is called. It's not capable of updating a stub on an instance - # that's already been previously stubbed (either directly, or via - # `any_instance`). - # - # This proxy sits in front of the recorder and delegates both to it - # and to the `RSpec::Mocks::Proxy` for each already mocked or stubbed - # instance of the class, in order to propagates changes to the instances. - # - # Note that unlike `RSpec::Mocks::Proxy`, this proxy class is stateless - # and is not persisted in `RSpec::Mocks.space`. - # - # Proxying for the message expectation fluent interface (typically chained - # off of the return value of one of these methods) is provided by the - # `FluentInterfaceProxy` class below. - class Proxy - def initialize(recorder, target_proxies) - @recorder = recorder - @target_proxies = target_proxies - end - - def klass - @recorder.klass - end - - def stub(method_name_or_method_map, &block) - if Hash === method_name_or_method_map - method_name_or_method_map.each do |method_name, return_value| - stub(method_name).and_return(return_value) - end - else - perform_proxying(__method__, [method_name_or_method_map], block) do |proxy| - proxy.add_stub(method_name_or_method_map, &block) - end - end - end - - def unstub(method_name) - perform_proxying(__method__, [method_name], nil) do |proxy| - proxy.remove_stub_if_present(method_name) - end - end - - def stub_chain(*chain, &block) - perform_proxying(__method__, chain, block) do |proxy| - Mocks::StubChain.stub_chain_on(proxy.object, *chain, &block) - end - end - - def expect_chain(*chain, &block) - perform_proxying(__method__, chain, block) do |proxy| - Mocks::ExpectChain.expect_chain_on(proxy.object, *chain, &block) - end - end - - def should_receive(method_name, &block) - perform_proxying(__method__, [method_name], block) do |proxy| - # Yeah, this is a bit odd...but if we used `add_message_expectation` - # then it would act like `expect_every_instance_of(klass).to receive`. - # The any_instance recorder takes care of validating that an instance - # received the message. - proxy.add_stub(method_name, &block) - end - end - - def should_not_receive(method_name, &block) - perform_proxying(__method__, [method_name], block) do |proxy| - proxy.add_message_expectation(method_name, &block).never - end - end - - private - - def perform_proxying(method_name, args, block, &target_proxy_block) - recorder_value = @recorder.__send__(method_name, *args, &block) - proxy_values = @target_proxies.map(&target_proxy_block) - FluentInterfaceProxy.new([recorder_value] + proxy_values) - end - end - - unless defined?(BasicObject) - class BasicObject - # Remove all methods except those expected to be defined on BasicObject - (instance_methods.map(&:to_sym) - [:__send__, :"!", :instance_eval, :==, :instance_exec, :"!=", :equal?, :__id__, :__binding__, :object_id]).each do |method| - undef_method method - end - end - end - - # @private - # Delegates messages to each of the given targets in order to - # provide the fluent interface that is available off of message - # expectations when dealing with `any_instance`. - # - # `targets` will typically contain 1 of the `AnyInstance::Recorder` - # return values and N `MessageExpectation` instances (one per instance - # of the `any_instance` klass). - class FluentInterfaceProxy < BasicObject - def initialize(targets) - @targets = targets - end - - if ::RUBY_VERSION.to_f > 1.8 - def respond_to_missing?(method_name, include_private=false) - super || @targets.first.respond_to?(method_name, include_private) - end - else - def respond_to?(method_name, include_private=false) - super || @targets.first.respond_to?(method_name, include_private) - end - end - - def method_missing(*args, &block) - return_values = @targets.map { |t| t.__send__(*args, &block) } - FluentInterfaceProxy.new(return_values) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb deleted file mode 100644 index 0eb8245..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/recorder.rb +++ /dev/null @@ -1,299 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # Given a class `TheClass`, `TheClass.any_instance` returns a `Recorder`, - # which records stubs and message expectations for later playback on - # instances of `TheClass`. - # - # Further constraints are stored in instances of [Chain](Chain). - # - # @see AnyInstance - # @see Chain - class Recorder - # @private - attr_reader :message_chains, :stubs, :klass - - def initialize(klass) - @message_chains = MessageChains.new - @stubs = Hash.new { |hash, key| hash[key] = [] } - @observed_methods = [] - @played_methods = {} - @backed_up_method_owner = {} - @klass = klass - @expectation_set = false - - return unless RSpec::Mocks.configuration.verify_partial_doubles? - RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| - block.call(ObjectReference.for(klass)) - end - end - - # Initializes the recording a stub to be played back against any - # instance of this object that invokes the submitted method. - # - # @see Methods#stub - def stub(method_name, &block) - observe!(method_name) - message_chains.add(method_name, StubChain.new(self, method_name, &block)) - end - - # Initializes the recording a stub chain to be played back against any - # instance of this object that invokes the method matching the first - # argument. - # - # @see Methods#stub_chain - def stub_chain(*method_names_and_optional_return_values, &block) - normalize_chain(*method_names_and_optional_return_values) do |method_name, args| - observe!(method_name) - message_chains.add(method_name, StubChainChain.new(self, *args, &block)) - end - end - - # @private - def expect_chain(*method_names_and_optional_return_values, &block) - @expectation_set = true - normalize_chain(*method_names_and_optional_return_values) do |method_name, args| - observe!(method_name) - message_chains.add(method_name, ExpectChainChain.new(self, *args, &block)) - end - end - - # Initializes the recording a message expectation to be played back - # against any instance of this object that invokes the submitted - # method. - # - # @see Methods#should_receive - def should_receive(method_name, &block) - @expectation_set = true - observe!(method_name) - message_chains.add(method_name, PositiveExpectationChain.new(self, method_name, &block)) - end - - # The opposite of `should_receive` - # - # @see Methods#should_not_receive - def should_not_receive(method_name, &block) - should_receive(method_name, &block).never - end - - # Removes any previously recorded stubs, stub_chains or message - # expectations that use `method_name`. - # - # @see Methods#unstub - def unstub(method_name) - unless @observed_methods.include?(method_name.to_sym) - AnyInstance.error_generator.raise_method_not_stubbed_error(method_name) - end - message_chains.remove_stub_chains_for!(method_name) - stubs[method_name].clear - stop_observing!(method_name) unless message_chains.has_expectation?(method_name) - end - - # @api private - # - # Used internally to verify that message expectations have been - # fulfilled. - def verify - return unless @expectation_set - return if message_chains.all_expectations_fulfilled? - - AnyInstance.error_generator.raise_second_instance_received_message_error(message_chains.unfulfilled_expectations) - end - - # @private - def stop_all_observation! - @observed_methods.each { |method_name| restore_method!(method_name) } - end - - # @private - def playback!(instance, method_name) - RSpec::Mocks.space.ensure_registered(instance) - message_chains.playback!(instance, method_name) - @played_methods[method_name] = instance - received_expected_message!(method_name) if message_chains.has_expectation?(method_name) - end - - # @private - def instance_that_received(method_name) - @played_methods[method_name] - end - - # @private - def build_alias_method_name(method_name) - "__#{method_name}_without_any_instance__" - end - - # @private - def already_observing?(method_name) - @observed_methods.include?(method_name) || super_class_observing?(method_name) - end - - # @private - def notify_received_message(_object, message, args, _blk) - has_expectation = false - - message_chains.each_unfulfilled_expectation_matching(message, *args) do |expectation| - has_expectation = true - expectation.expectation_fulfilled! - end - - return unless has_expectation - - restore_method!(message) - mark_invoked!(message) - end - - protected - - def stop_observing!(method_name) - restore_method!(method_name) - @observed_methods.delete(method_name) - super_class_observers_for(method_name).each do |ancestor| - ::RSpec::Mocks.space. - any_instance_recorder_for(ancestor).stop_observing!(method_name) - end - end - - private - - def ancestor_is_an_observer?(ancestor, method_name) - return if ancestor == @klass - - ::RSpec::Mocks.space. - any_instance_recorder_for(ancestor).already_observing?(method_name) - end - - def super_class_observers_for(method_name) - @klass.ancestors.select do |ancestor| - ancestor_is_an_observer?(ancestor, method_name) - end - end - - def super_class_observing?(method_name) - @klass.ancestors.any? do |ancestor| - ancestor_is_an_observer?(ancestor, method_name) - end - end - - def normalize_chain(*args) - args.shift.to_s.split('.').map { |s| s.to_sym }.reverse.each { |a| args.unshift a } - yield args.first, args - end - - def received_expected_message!(method_name) - message_chains.received_expected_message!(method_name) - restore_method!(method_name) - mark_invoked!(method_name) - end - - def restore_method!(method_name) - if public_protected_or_private_method_defined?(build_alias_method_name(method_name)) - restore_original_method!(method_name) - else - remove_dummy_method!(method_name) - end - end - - def restore_original_method!(method_name) - return unless @klass.instance_method(method_name).owner == @klass - - alias_method_name = build_alias_method_name(method_name) - @klass.class_exec(@backed_up_method_owner) do |backed_up_method_owner| - remove_method method_name - - # A @klass can have methods implemented (see Method#owner) in @klass - # or inherited from a superclass. In ruby 2.2 and earlier, we can copy - # a method regardless of the 'owner' and restore it to @klass after - # because a call to 'super' from @klass's copied method would end up - # calling the original class's superclass's method. - # - # With the commit below, available starting in 2.3.0, ruby changed - # this behavior and a call to 'super' from the method copied to @klass - # will call @klass's superclass method, which is the original - # implementer of this method! This leads to very strange errors - # if @klass's copied method calls 'super', since it would end up - # calling itself, the original method implemented in @klass's - # superclass. - # - # For ruby 2.3 and above, we need to only restore methods that - # @klass originally owned. - # - # https://github.com/ruby/ruby/commit/c8854d2ca4be9ee6946e6d17b0e17d9ef130ee81 - if RUBY_VERSION < "2.3" || backed_up_method_owner[method_name.to_sym] == self - alias_method method_name, alias_method_name - end - remove_method alias_method_name - end - end - - def remove_dummy_method!(method_name) - @klass.class_exec do - remove_method method_name - end - end - - def backup_method!(method_name) - return unless public_protected_or_private_method_defined?(method_name) - - alias_method_name = build_alias_method_name(method_name) - @backed_up_method_owner[method_name.to_sym] ||= @klass.instance_method(method_name).owner - @klass.class_exec do - alias_method alias_method_name, method_name - end - end - - def public_protected_or_private_method_defined?(method_name) - MethodReference.method_defined_at_any_visibility?(@klass, method_name) - end - - def observe!(method_name) - allow_no_prepended_module_definition_of(method_name) - - if RSpec::Mocks.configuration.verify_partial_doubles? && !Mocks.configuration.temporarily_suppress_partial_double_verification - unless public_protected_or_private_method_defined?(method_name) - AnyInstance.error_generator.raise_does_not_implement_error(@klass, method_name) - end - end - - stop_observing!(method_name) if already_observing?(method_name) - @observed_methods << method_name - backup_method!(method_name) - recorder = self - method_was_private = @klass.private_method_defined?(method_name) - @klass.__send__(:define_method, method_name) do |*args, &blk| - recorder.playback!(self, method_name) - __send__(method_name, *args, &blk) - end - @klass.__send__(:private, method_name) if method_was_private - @klass.__send__(:ruby2_keywords, method_name) if @klass.respond_to?(:ruby2_keywords, true) - end - - def mark_invoked!(method_name) - backup_method!(method_name) - recorder = self - @klass.__send__(:define_method, method_name) do |*_args, &_blk| - invoked_instance = recorder.instance_that_received(method_name) - inspect = "#<#{self.class}:#{object_id} #{instance_variables.map { |name| "#{name}=#{instance_variable_get name}" }.join(', ')}>" - AnyInstance.error_generator.raise_message_already_received_by_other_instance_error( - method_name, inspect, invoked_instance - ) - end - end - - if Support::RubyFeatures.module_prepends_supported? - def allow_no_prepended_module_definition_of(method_name) - prepended_modules = RSpec::Mocks::Proxy.prepended_modules_of(@klass) - problem_mod = prepended_modules.find { |mod| mod.method_defined?(method_name) } - return unless problem_mod - - AnyInstance.error_generator.raise_not_supported_with_prepend_error(method_name, problem_mod) - end - else - def allow_no_prepended_module_definition_of(_method_name) - # nothing to do; prepends aren't supported on this version of ruby - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb deleted file mode 100644 index c4c0ab7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain.rb +++ /dev/null @@ -1,51 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # @private - class StubChain < Chain - # @private - def expectation_fulfilled? - true - end - - private - - def create_message_expectation_on(instance) - proxy = ::RSpec::Mocks.space.proxy_for(instance) - method_name, opts = @expectation_args - opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE) - - stub = proxy.add_stub(method_name, opts, &@expectation_block) - @recorder.stubs[stub.message] << stub - - if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks? - stub.and_yield_receiver_to_implementation - end - - stub - end - - InvocationOrder = - { - :and_return => [:with, nil], - :and_raise => [:with, nil], - :and_yield => [:with, :and_yield, nil], - :and_throw => [:with, nil], - :and_call_original => [:with, nil], - :and_wrap_original => [:with, nil] - }.freeze - - EmptyInvocationOrder = {}.freeze - - def invocation_order - InvocationOrder - end - - def verify_invocation_order(rspec_method_name, *_args, &_block) - return if invocation_order.fetch(rspec_method_name, [nil]).include?(last_message) - raise NoMethodError, "Undefined method #{rspec_method_name}" - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb deleted file mode 100644 index 495511c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/any_instance/stub_chain_chain.rb +++ /dev/null @@ -1,23 +0,0 @@ -module RSpec - module Mocks - module AnyInstance - # @private - class StubChainChain < StubChain - def initialize(*args) - super - @expectation_fulfilled = false - end - - private - - def create_message_expectation_on(instance) - ::RSpec::Mocks::StubChain.stub_chain_on(instance, *@expectation_args, &@expectation_block) - end - - def invocation_order - EmptyInvocationOrder - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb deleted file mode 100644 index f8adcd9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_list_matcher.rb +++ /dev/null @@ -1,117 +0,0 @@ -# We intentionally do not use the `RSpec::Support.require...` methods -# here so that this file can be loaded individually, as documented -# below. -require 'rspec/mocks/argument_matchers' -require 'rspec/support/fuzzy_matcher' - -module RSpec - module Mocks - # Wrapper for matching arguments against a list of expected values. Used by - # the `with` method on a `MessageExpectation`: - # - # expect(object).to receive(:message).with(:a, 'b', 3) - # object.message(:a, 'b', 3) - # - # Values passed to `with` can be literal values or argument matchers that - # match against the real objects .e.g. - # - # expect(object).to receive(:message).with(hash_including(:a => 'b')) - # - # Can also be used directly to match the contents of any `Array`. This - # enables 3rd party mocking libs to take advantage of rspec's argument - # matching without using the rest of rspec-mocks. - # - # require 'rspec/mocks/argument_list_matcher' - # include RSpec::Mocks::ArgumentMatchers - # - # arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b')) - # arg_list_matcher.args_match?(123, :a => 'b') - # - # This class is immutable. - # - # @see ArgumentMatchers - class ArgumentListMatcher - # @private - attr_reader :expected_args - - # @api public - # @param [Array] expected_args a list of expected literals and/or argument matchers - # - # Initializes an `ArgumentListMatcher` with a collection of literal - # values and/or argument matchers. - # - # @see ArgumentMatchers - # @see #args_match? - def initialize(*expected_args) - @expected_args = expected_args - ensure_expected_args_valid! - end - ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true) - - # @api public - # @param [Array] actual_args - # - # Matches each element in the `expected_args` against the element in the same - # position of the arguments passed to `new`. - # - # @see #initialize - def args_match?(*actual_args) - expected_args = resolve_expected_args_based_on(actual_args) - - return false if expected_args.size != actual_args.size - - if RUBY_VERSION >= "3" - # If the expectation was set with keywords, while the actual method was called with a positional hash argument, they don't match. - # If the expectation was set without keywords, e.g., with({a: 1}), then it fine to call it with either foo(a: 1) or foo({a: 1}). - # This corresponds to Ruby semantics, as if the method was def foo(options). - if Hash === expected_args.last && Hash === actual_args.last - if !Hash.ruby2_keywords_hash?(actual_args.last) && Hash.ruby2_keywords_hash?(expected_args.last) - return false - end - end - end - - Support::FuzzyMatcher.values_match?(expected_args, actual_args) - end - ruby2_keywords :args_match? if respond_to?(:ruby2_keywords, true) - - # @private - # Resolves abstract arg placeholders like `no_args` and `any_args` into - # a more concrete arg list based on the provided `actual_args`. - def resolve_expected_args_based_on(actual_args) - return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args - - any_args_index = expected_args.index { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } - return expected_args unless any_args_index - - replace_any_args_with_splat_of_anything(any_args_index, actual_args.count) - end - - private - - def replace_any_args_with_splat_of_anything(before_count, actual_args_count) - any_args_count = actual_args_count - expected_args.count + 1 - after_count = expected_args.count - before_count - 1 - - any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE } - expected_args.first(before_count) + any_args + expected_args.last(after_count) - end - - def ensure_expected_args_valid! - if expected_args.count { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } > 1 - raise ArgumentError, "`any_args` can only be passed to " \ - "`with` once but you have passed it multiple times." - elsif expected_args.count > 1 && expected_args.any? { |a| ArgumentMatchers::NoArgsMatcher::INSTANCE == a } - raise ArgumentError, "`no_args` can only be passed as a " \ - "singleton argument to `with` (i.e. `with(no_args)`), " \ - "but you have passed additional arguments." - end - end - - # Value that will match all argument lists. - # - # @private - MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE) - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb deleted file mode 100644 index 5452508..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/argument_matchers.rb +++ /dev/null @@ -1,366 +0,0 @@ -# This cannot take advantage of our relative requires, since this file is a -# dependency of `rspec/mocks/argument_list_matcher.rb`. See comment there for -# details. -require 'rspec/support/matcher_definition' - -module RSpec - module Mocks - # ArgumentMatchers are placeholders that you can include in message - # expectations to match arguments against a broader check than simple - # equality. - # - # With the exception of `any_args` and `no_args`, they all match against - # the arg in same position in the argument list. - # - # @see ArgumentListMatcher - module ArgumentMatchers - # Acts like an arg splat, matching any number of args at any point in an arg list. - # - # @example - # expect(object).to receive(:message).with(1, 2, any_args) - # - # # matches any of these: - # object.message(1, 2) - # object.message(1, 2, 3) - # object.message(1, 2, 3, 4) - def any_args - AnyArgsMatcher::INSTANCE - end - - # Matches any argument at all. - # - # @example - # expect(object).to receive(:message).with(anything) - def anything - AnyArgMatcher::INSTANCE - end - - # Matches no arguments. - # - # @example - # expect(object).to receive(:message).with(no_args) - def no_args - NoArgsMatcher::INSTANCE - end - - # Matches if the actual argument responds to the specified messages. - # - # @example - # expect(object).to receive(:message).with(duck_type(:hello)) - # expect(object).to receive(:message).with(duck_type(:hello, :goodbye)) - def duck_type(*args) - DuckTypeMatcher.new(*args) - end - - # Matches a boolean value. - # - # @example - # expect(object).to receive(:message).with(boolean()) - def boolean - BooleanMatcher::INSTANCE - end - - # Matches a hash that includes the specified key(s) or key/value pairs. - # Ignores any additional keys. - # - # @example - # expect(object).to receive(:message).with(hash_including(:key => val)) - # expect(object).to receive(:message).with(hash_including(:key)) - # expect(object).to receive(:message).with(hash_including(:key, :key2 => val2)) - def hash_including(*args) - HashIncludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args)) - end - - # Matches a hash that doesn't include the specified key(s) or key/value. - # - # @example - # expect(object).to receive(:message).with(hash_excluding(:key => val)) - # expect(object).to receive(:message).with(hash_excluding(:key)) - # expect(object).to receive(:message).with(hash_excluding(:key, :key2 => :val2)) - def hash_excluding(*args) - HashExcludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args)) - end - - # Matches an array that includes the specified items at least once. - # Ignores duplicates and additional values - # - # @example - # expect(object).to receive(:message).with(array_including(1,2,3)) - # expect(object).to receive(:message).with(array_including([1,2,3])) - def array_including(*args) - actually_an_array = Array === args.first && args.count == 1 ? args.first : args - ArrayIncludingMatcher.new(actually_an_array) - end - - # Matches an array that excludes the specified items. - # - # @example - # expect(object).to receive(:message).with(array_excluding(1,2,3)) - # expect(object).to receive(:message).with(array_excluding([1,2,3])) - def array_excluding(*args) - actually_an_array = Array === args.first && args.count == 1 ? args.first : args - ArrayExcludingMatcher.new(actually_an_array) - end - - alias_method :hash_not_including, :hash_excluding - - # Matches if `arg.instance_of?(klass)` - # - # @example - # expect(object).to receive(:message).with(instance_of(Thing)) - def instance_of(klass) - InstanceOf.new(klass) - end - - alias_method :an_instance_of, :instance_of - - # Matches if `arg.kind_of?(klass)` - # - # @example - # expect(object).to receive(:message).with(kind_of(Thing)) - def kind_of(klass) - KindOf.new(klass) - end - - alias_method :a_kind_of, :kind_of - - # @private - def self.anythingize_lonely_keys(*args) - hash = Hash === args.last ? args.delete_at(-1) : {} - args.each { | arg | hash[arg] = AnyArgMatcher::INSTANCE } - hash - end - - # Intended to be subclassed by stateless, immutable argument matchers. - # Provides a `::INSTANCE` constant for accessing a global - # singleton instance of the matcher. There is no need to construct - # multiple instance since there is no state. It also facilities the - # special case logic we need for some of these matchers, by making it - # easy to do comparisons like: `[klass::INSTANCE] == args` rather than - # `args.count == 1 && klass === args.first`. - # - # @private - class SingletonMatcher - private_class_method :new - - def self.inherited(subklass) - subklass.const_set(:INSTANCE, subklass.send(:new)) - end - end - - # @private - class AnyArgsMatcher < SingletonMatcher - def description - "*(any args)" - end - end - - # @private - class AnyArgMatcher < SingletonMatcher - def ===(_other) - true - end - - def description - "anything" - end - end - - # @private - class NoArgsMatcher < SingletonMatcher - def description - "no args" - end - end - - # @private - class BooleanMatcher < SingletonMatcher - def ===(value) - true == value || false == value - end - - def description - "boolean" - end - end - - # @private - class BaseHashMatcher - def initialize(expected) - @expected = expected - end - - def ===(predicate, actual) - @expected.__send__(predicate) do |k, v| - actual.key?(k) && Support::FuzzyMatcher.values_match?(v, actual[k]) - end - rescue NoMethodError - false - end - - def description(name) - "#{name}(#{formatted_expected_hash.inspect.sub(/^\{/, "").sub(/\}$/, "")})" - end - - private - - def formatted_expected_hash - Hash[ - @expected.map do |k, v| - k = RSpec::Support.rspec_description_for_object(k) - v = RSpec::Support.rspec_description_for_object(v) - - [k, v] - end - ] - end - end - - # @private - class HashIncludingMatcher < BaseHashMatcher - def ===(actual) - super(:all?, actual) - end - - def description - super("hash_including") - end - end - - # @private - class HashExcludingMatcher < BaseHashMatcher - def ===(actual) - super(:none?, actual) - end - - def description - super("hash_not_including") - end - end - - # @private - class ArrayIncludingMatcher - def initialize(expected) - @expected = expected - end - - def ===(actual) - actual = actual.uniq - return true if (actual & @expected).count >= @expected.count - - @expected.uniq.all? do |expected_element| - actual.any? do |actual_element| - RSpec::Support::FuzzyMatcher.values_match?(expected_element, actual_element) - end - end - rescue NoMethodError - false - end - - def description - "array_including(#{formatted_expected_values})" - end - - private - - def formatted_expected_values - @expected.map do |x| - RSpec::Support.rspec_description_for_object(x) - end.join(", ") - end - end - - # @private - class ArrayExcludingMatcher - def initialize(unexpected) - @unexpected = unexpected.uniq - end - - def ===(actual) - actual = actual.uniq - return false unless (actual & @unexpected).empty? - - actual.none? do |actual_element| - @unexpected.any? do |unexpected_element| - RSpec::Support::FuzzyMatcher.values_match?(unexpected_element, actual_element) - end - end - rescue NoMethodError - false - end - - def description - "array_excluding(#{formatted_unexpected_values})" - end - - private - - def formatted_unexpected_values - @unexpected.map do |x| - RSpec::Support.rspec_description_for_object(x) - end.join(", ") - end - end - - # @private - class DuckTypeMatcher - def initialize(*methods_to_respond_to) - @methods_to_respond_to = methods_to_respond_to - end - - def ===(value) - @methods_to_respond_to.all? { |message| value.respond_to?(message) } - end - - def description - "duck_type(#{@methods_to_respond_to.map(&:inspect).join(', ')})" - end - end - - # @private - class InstanceOf - def initialize(klass) - @klass = klass - end - - def ===(actual) - actual.instance_of?(@klass) - end - - def description - "an_instance_of(#{@klass.name})" - end - end - - # @private - class KindOf - def initialize(klass) - @klass = klass - end - - def ===(actual) - actual.kind_of?(@klass) - end - - def description - "kind of #{@klass.name}" - end - end - - matcher_namespace = name + '::' - ::RSpec::Support.register_matcher_definition do |object| - # This is the best we have for now. We should tag all of our matchers - # with a module or something so we can test for it directly. - # - # (Note Module#parent in ActiveSupport is defined in a similar way.) - begin - object.class.name.include?(matcher_namespace) - rescue NoMethodError - # Some objects, like BasicObject, don't implement standard - # reflection methods. - false - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb deleted file mode 100644 index 8496bdc..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/configuration.rb +++ /dev/null @@ -1,212 +0,0 @@ -module RSpec - module Mocks - # Provides configuration options for rspec-mocks. - class Configuration - def initialize - @allow_message_expectations_on_nil = nil - @yield_receiver_to_any_instance_implementation_blocks = true - @verify_doubled_constant_names = false - @transfer_nested_constants = false - @verify_partial_doubles = false - @temporarily_suppress_partial_double_verification = false - @color = false - end - - # Sets whether RSpec will warn, ignore, or fail a test when - # expectations are set on nil. - # By default, when this flag is not set, warning messages are issued when - # expectations are set on nil. This is to prevent false-positives and to - # catch potential bugs early on. - # When set to `true`, warning messages are suppressed. - # When set to `false`, it will raise an error. - # - # @example - # RSpec.configure do |config| - # config.mock_with :rspec do |mocks| - # mocks.allow_message_expectations_on_nil = false - # end - # end - attr_accessor :allow_message_expectations_on_nil - - def yield_receiver_to_any_instance_implementation_blocks? - @yield_receiver_to_any_instance_implementation_blocks - end - - # Sets whether or not RSpec will yield the receiving instance of a - # message to blocks that are used for any_instance stub implementations. - # When set, the first yielded argument will be the receiving instance. - # Defaults to `true`. - # - # @example - # RSpec.configure do |rspec| - # rspec.mock_with :rspec do |mocks| - # mocks.yield_receiver_to_any_instance_implementation_blocks = false - # end - # end - attr_writer :yield_receiver_to_any_instance_implementation_blocks - - # Adds `stub` and `should_receive` to the given - # modules or classes. This is usually only necessary - # if you application uses some proxy classes that - # "strip themselves down" to a bare minimum set of - # methods and remove `stub` and `should_receive` in - # the process. - # - # @example - # RSpec.configure do |rspec| - # rspec.mock_with :rspec do |mocks| - # mocks.add_stub_and_should_receive_to Delegator - # end - # end - # - def add_stub_and_should_receive_to(*modules) - modules.each do |mod| - Syntax.enable_should(mod) - end - end - - # Provides the ability to set either `expect`, - # `should` or both syntaxes. RSpec uses `expect` - # syntax by default. This is needed if you want to - # explicitly enable `should` syntax and/or explicitly - # disable `expect` syntax. - # - # @example - # RSpec.configure do |rspec| - # rspec.mock_with :rspec do |mocks| - # mocks.syntax = [:expect, :should] - # end - # end - # - def syntax=(*values) - syntaxes = values.flatten - if syntaxes.include?(:expect) - Syntax.enable_expect - else - Syntax.disable_expect - end - - if syntaxes.include?(:should) - Syntax.enable_should - else - Syntax.disable_should - end - end - - # Returns an array with a list of syntaxes - # that are enabled. - # - # @example - # unless RSpec::Mocks.configuration.syntax.include?(:expect) - # raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax" - # end - # - def syntax - syntaxes = [] - syntaxes << :should if Syntax.should_enabled? - syntaxes << :expect if Syntax.expect_enabled? - syntaxes - end - - def verify_doubled_constant_names? - !!@verify_doubled_constant_names - end - - # When this is set to true, an error will be raised when - # `instance_double` or `class_double` is given the name of an undefined - # constant. You probably only want to set this when running your entire - # test suite, with all production code loaded. Setting this for an - # isolated unit test will prevent you from being able to isolate it! - attr_writer :verify_doubled_constant_names - - # Provides a way to perform customisations when verifying doubles. - # - # @example - # RSpec::Mocks.configuration.before_verifying_doubles do |ref| - # ref.some_method! - # end - def before_verifying_doubles(&block) - verifying_double_callbacks << block - end - alias :when_declaring_verifying_double :before_verifying_doubles - - # @api private - # Returns an array of blocks to call when verifying doubles - def verifying_double_callbacks - @verifying_double_callbacks ||= [] - end - - def transfer_nested_constants? - !!@transfer_nested_constants - end - - # Sets the default for the `transfer_nested_constants` option when - # stubbing constants. - attr_writer :transfer_nested_constants - - # When set to true, partial mocks will be verified the same as object - # doubles. Any stubs will have their arguments checked against the original - # method, and methods that do not exist cannot be stubbed. - def verify_partial_doubles=(val) - @verify_partial_doubles = !!val - end - - def verify_partial_doubles? - @verify_partial_doubles - end - - # @private - # Used to track whether we are temporarily suppressing verifying partial - # doubles with `without_partial_double_verification { ... }` - attr_accessor :temporarily_suppress_partial_double_verification - - if ::RSpec.respond_to?(:configuration) - def color? - ::RSpec.configuration.color_enabled? - end - else - # Indicates whether or not diffs should be colored. - # Delegates to rspec-core's color option if rspec-core - # is loaded; otherwise you can set it here. - attr_writer :color - - # Indicates whether or not diffs should be colored. - # Delegates to rspec-core's color option if rspec-core - # is loaded; otherwise you can set it here. - def color? - @color - end - end - - # Monkey-patch `Marshal.dump` to enable dumping of mocked or stubbed - # objects. By default this will not work since RSpec mocks works by - # adding singleton methods that cannot be serialized. This patch removes - # these singleton methods before serialization. Setting to falsey removes - # the patch. - # - # This method is idempotent. - def patch_marshal_to_support_partial_doubles=(val) - if val - RSpec::Mocks::MarshalExtension.patch! - else - RSpec::Mocks::MarshalExtension.unpatch! - end - end - - # @api private - # Resets the configured syntax to the default. - def reset_syntaxes_to_default - self.syntax = [:should, :expect] - RSpec::Mocks::Syntax.warn_about_should! - end - end - - # Mocks specific configuration, as distinct from `RSpec.configuration` - # which is core RSpec configuration. - def self.configuration - @configuration ||= Configuration.new - end - - configuration.reset_syntaxes_to_default - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb deleted file mode 100644 index 44d2e63..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/error_generator.rb +++ /dev/null @@ -1,390 +0,0 @@ -RSpec::Support.require_rspec_support "object_formatter" - -module RSpec - module Mocks - # Raised when a message expectation is not satisfied. - MockExpectationError = Class.new(Exception) - - # Raised when a test double is used after it has been torn - # down (typically at the end of an rspec-core example). - ExpiredTestDoubleError = Class.new(MockExpectationError) - - # Raised when doubles or partial doubles are used outside of the per-test lifecycle. - OutsideOfExampleError = Class.new(StandardError) - - # Raised when an expectation customization method (e.g. `with`, - # `and_return`) is called on a message expectation which has already been - # invoked. - MockExpectationAlreadyInvokedError = Class.new(Exception) - - # Raised for situations that RSpec cannot support due to mutations made - # externally on arguments that RSpec is holding onto to use for later - # comparisons. - # - # @deprecated We no longer raise this error but the constant remains until - # RSpec 4 for SemVer reasons. - CannotSupportArgMutationsError = Class.new(StandardError) - - # @private - UnsupportedMatcherError = Class.new(StandardError) - # @private - NegationUnsupportedError = Class.new(StandardError) - # @private - VerifyingDoubleNotDefinedError = Class.new(StandardError) - - # @private - class ErrorGenerator - attr_writer :opts - - def initialize(target=nil) - @target = target - end - - # @private - def opts - @opts ||= {} - end - - # @private - def raise_unexpected_message_error(message, args) - __raise "#{intro} received unexpected message :#{message} with #{format_args(args)}" - end - - # @private - def raise_unexpected_message_args_error(expectation, args_for_multiple_calls, source_id=nil) - __raise error_message(expectation, args_for_multiple_calls), nil, source_id - end - - # @private - def raise_missing_default_stub_error(expectation, args_for_multiple_calls) - __raise( - error_message(expectation, args_for_multiple_calls) + - "\n Please stub a default value first if message might be received with other args as well. \n" - ) - end - - # @private - def raise_similar_message_args_error(expectation, args_for_multiple_calls, backtrace_line=nil) - __raise error_message(expectation, args_for_multiple_calls), backtrace_line - end - - def default_error_message(expectation, expected_args, actual_args) - "#{intro} received #{expectation.message.inspect} #{unexpected_arguments_message(expected_args, actual_args)}".dup - end - - # rubocop:disable Metrics/ParameterLists - # @private - def raise_expectation_error(message, expected_received_count, argument_list_matcher, - actual_received_count, expectation_count_type, args, - backtrace_line=nil, source_id=nil) - expected_part = expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) - received_part = received_part_of_expectation_error(actual_received_count, args) - __raise "(#{intro(:unwrapped)}).#{message}#{format_args(args)}\n #{expected_part}\n #{received_part}", backtrace_line, source_id - end - # rubocop:enable Metrics/ParameterLists - - # @private - def raise_unimplemented_error(doubled_module, method_name, object) - message = case object - when InstanceVerifyingDouble - "the %s class does not implement the instance method: %s".dup << - if ObjectMethodReference.for(doubled_module, method_name).implemented? - ". Perhaps you meant to use `class_double` instead?" - else - "" - end - when ClassVerifyingDouble - "the %s class does not implement the class method: %s".dup << - if InstanceMethodReference.for(doubled_module, method_name).implemented? - ". Perhaps you meant to use `instance_double` instead?" - else - "" - end - else - "%s does not implement: %s" - end - - __raise message % [doubled_module.description, method_name] - end - - # @private - def raise_non_public_error(method_name, visibility) - raise NoMethodError, "%s method `%s' called on %s" % [ - visibility, method_name, intro - ] - end - - # @private - def raise_invalid_arguments_error(verifier) - __raise verifier.error_message - end - - # @private - def raise_expired_test_double_error - raise ExpiredTestDoubleError, - "#{intro} was originally created in one example but has leaked into " \ - "another example and can no longer be used. rspec-mocks' doubles are " \ - "designed to only last for one example, and you need to create a new " \ - "one in each example you wish to use it for." - end - - # @private - def describe_expectation(verb, message, expected_received_count, _actual_received_count, args) - "#{verb} #{message}#{format_args(args)} #{count_message(expected_received_count)}" - end - - # @private - def raise_out_of_order_error(message) - __raise "#{intro} received :#{message} out of order" - end - - # @private - def raise_missing_block_error(args_to_yield) - __raise "#{intro} asked to yield |#{arg_list(args_to_yield)}| but no block was passed" - end - - # @private - def raise_wrong_arity_error(args_to_yield, signature) - __raise "#{intro} yielded |#{arg_list(args_to_yield)}| to block with #{signature.description}" - end - - # @private - def raise_only_valid_on_a_partial_double(method) - __raise "#{intro} is a pure test double. `#{method}` is only " \ - "available on a partial double." - end - - # @private - def raise_expectation_on_unstubbed_method(method) - __raise "#{intro} expected to have received #{method}, but that " \ - "object is not a spy or method has not been stubbed." - end - - # @private - def raise_expectation_on_mocked_method(method) - __raise "#{intro} expected to have received #{method}, but that " \ - "method has been mocked instead of stubbed or spied." - end - - # @private - def raise_double_negation_error(wrapped_expression) - __raise "Isn't life confusing enough? You've already set a " \ - "negative message expectation and now you are trying to " \ - "negate it again with `never`. What does an expression like " \ - "`#{wrapped_expression}.not_to receive(:msg).never` even mean?" - end - - # @private - def raise_verifying_double_not_defined_error(ref) - notify(VerifyingDoubleNotDefinedError.new( - "#{ref.description.inspect} is not a defined constant. " \ - "Perhaps you misspelt it? " \ - "Disable check with `verify_doubled_constant_names` configuration option." - )) - end - - # @private - def raise_have_received_disallowed(type, reason) - __raise "Using #{type}(...) with the `have_received` " \ - "matcher is not supported#{reason}." - end - - # @private - def raise_cant_constrain_count_for_negated_have_received_error(count_constraint) - __raise "can't use #{count_constraint} when negative" - end - - # @private - def raise_method_not_stubbed_error(method_name) - __raise "The method `#{method_name}` was not stubbed or was already unstubbed" - end - - # @private - def raise_already_invoked_error(message, calling_customization) - error_message = "The message expectation for #{intro}.#{message} has already been invoked " \ - "and cannot be modified further (e.g. using `#{calling_customization}`). All message expectation " \ - "customizations must be applied before it is used for the first time." - - notify MockExpectationAlreadyInvokedError.new(error_message) - end - - def raise_expectation_on_nil_error(method_name) - __raise expectation_on_nil_message(method_name) - end - - def expectation_on_nil_message(method_name) - "An expectation of `:#{method_name}` was set on `nil`. " \ - "To allow expectations on `nil` and suppress this message, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `true`. " \ - "To disallow expectations on `nil`, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `false`" - end - - # @private - def intro(unwrapped=false) - case @target - when TestDouble then TestDoubleFormatter.format(@target, unwrapped) - when Class then - formatted = "#{@target.inspect} (class)" - return formatted if unwrapped - "#<#{formatted}>" - when NilClass then "nil" - else @target.inspect - end - end - - # @private - def method_call_args_description(args, generic_prefix=" with arguments: ", matcher_prefix=" with ") - case args.first - when ArgumentMatchers::AnyArgsMatcher then "#{matcher_prefix}any arguments" - when ArgumentMatchers::NoArgsMatcher then "#{matcher_prefix}no arguments" - else - if yield - "#{generic_prefix}#{format_args(args)}" - else - "" - end - end - end - - private - - def received_part_of_expectation_error(actual_received_count, args) - "received: #{count_message(actual_received_count)}" + - method_call_args_description(args) do - actual_received_count > 0 && args.length > 0 - end - end - - def expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) - "expected: #{count_message(expected_received_count, expectation_count_type)}" + - method_call_args_description(argument_list_matcher.expected_args) do - argument_list_matcher.expected_args.length > 0 - end - end - - def unexpected_arguments_message(expected_args_string, actual_args_string) - "with unexpected arguments\n expected: #{expected_args_string}\n got: #{actual_args_string}" - end - - def error_message(expectation, args_for_multiple_calls) - expected_args = format_args(expectation.expected_args) - actual_args = format_received_args(args_for_multiple_calls) - - if RSpec::Support::RubyFeatures.distincts_kw_args_from_positional_hash? - expected_hash = expectation.expected_args.last - actual_hash = args_for_multiple_calls.last.last - if Hash === expected_hash && Hash === actual_hash && - (Hash.ruby2_keywords_hash?(expected_hash) != Hash.ruby2_keywords_hash?(actual_hash)) - - actual_description = Hash.ruby2_keywords_hash?(actual_hash) ? " (keyword arguments)" : " (options hash)" - expected_description = Hash.ruby2_keywords_hash?(expected_hash) ? " (keyword arguments)" : " (options hash)" - - if actual_description != expected_description - actual_args += actual_description - expected_args += expected_description - end - end - end - - message = default_error_message(expectation, expected_args, actual_args) - - if args_for_multiple_calls.one? - diff = diff_message(expectation.expected_args, args_for_multiple_calls.first) - if RSpec::Mocks.configuration.color? - message << "\nDiff:#{diff}" unless diff.gsub(/\e\[\d+m/, '').strip.empty? - else - message << "\nDiff:#{diff}" unless diff.strip.empty? - end - end - - message - end - - def diff_message(expected_args, actual_args) - formatted_expected_args = expected_args.map do |x| - RSpec::Support.rspec_description_for_object(x) - end - - formatted_expected_args, actual_args = unpack_string_args(formatted_expected_args, actual_args) - - differ.diff(actual_args, formatted_expected_args) - end - - def unpack_string_args(formatted_expected_args, actual_args) - if [formatted_expected_args, actual_args].all? { |x| list_of_exactly_one_string?(x) } - [formatted_expected_args.first, actual_args.first] - else - [formatted_expected_args, actual_args] - end - end - - def list_of_exactly_one_string?(args) - Array === args && args.count == 1 && String === args.first - end - - def differ - RSpec::Support::Differ.new(:color => RSpec::Mocks.configuration.color?) - end - - def __raise(message, backtrace_line=nil, source_id=nil) - message = opts[:message] unless opts[:message].nil? - exception = RSpec::Mocks::MockExpectationError.new(message) - prepend_to_backtrace(exception, backtrace_line) if backtrace_line - notify exception, :source_id => source_id - end - - if RSpec::Support::Ruby.jruby? - def prepend_to_backtrace(exception, line) - raise exception - rescue RSpec::Mocks::MockExpectationError => with_backtrace - with_backtrace.backtrace.unshift(line) - end - else - def prepend_to_backtrace(exception, line) - exception.set_backtrace(caller.unshift line) - end - end - - def notify(*args) - RSpec::Support.notify_failure(*args) - end - - def format_args(args) - return "(no args)" if args.empty? - "(#{arg_list(args)})" - end - - def arg_list(args) - args.map { |arg| RSpec::Support::ObjectFormatter.format(arg) }.join(", ") - end - - def format_received_args(args_for_multiple_calls) - grouped_args(args_for_multiple_calls).map do |args_for_one_call, index| - "#{format_args(args_for_one_call)}#{group_count(index, args_for_multiple_calls)}" - end.join("\n ") - end - - def count_message(count, expectation_count_type=nil) - return "at least #{times(count.abs)}" if count < 0 || expectation_count_type == :at_least - return "at most #{times(count)}" if expectation_count_type == :at_most - times(count) - end - - def times(count) - "#{count} time#{'s' unless count == 1}" - end - - def grouped_args(args) - Hash[args.group_by { |x| x }.map { |k, v| [k, v.count] }] - end - - def group_count(index, args) - " (#{times(index)})" if args.size > 1 || index > 1 - end - end - - # @private - def self.error_generator - @error_generator ||= ErrorGenerator.new - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb deleted file mode 100644 index 5531b28..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/example_methods.rb +++ /dev/null @@ -1,434 +0,0 @@ -RSpec::Support.require_rspec_mocks 'object_reference' - -module RSpec - module Mocks - # Contains methods intended to be used from within code examples. - # Mix this in to your test context (such as a test framework base class) - # to use rspec-mocks with your test framework. If you're using rspec-core, - # it'll take care of doing this for you. - module ExampleMethods - include RSpec::Mocks::ArgumentMatchers - - # @overload double() - # @overload double(name) - # @param name [String/Symbol] name or description to be used in failure messages - # @overload double(stubs) - # @param stubs (Hash) hash of message/return-value pairs - # @overload double(name, stubs) - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs (Hash) hash of message/return-value pairs - # @return (Double) - # - # Constructs an instance of [RSpec::Mocks::Double](RSpec::Mocks::Double) configured - # with an optional name, used for reporting in failure messages, and an optional - # hash of message/return-value pairs. - # - # @example - # book = double("book", :title => "The RSpec Book") - # book.title #=> "The RSpec Book" - # - # card = double("card", :suit => "Spades", :rank => "A") - # card.suit #=> "Spades" - # card.rank #=> "A" - # - def double(*args) - ExampleMethods.declare_double(Double, *args) - end - - # @overload instance_double(doubled_class) - # @param doubled_class [String, Class] - # @overload instance_double(doubled_class, name) - # @param doubled_class [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @overload instance_double(doubled_class, stubs) - # @param doubled_class [String, Class] - # @param stubs [Hash] hash of message/return-value pairs - # @overload instance_double(doubled_class, name, stubs) - # @param doubled_class [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs [Hash] hash of message/return-value pairs - # @return InstanceVerifyingDouble - # - # Constructs a test double against a specific class. If the given class - # name has been loaded, only instance methods defined on the class are - # allowed to be stubbed. In all other ways it behaves like a - # [double](double). - def instance_double(doubled_class, *args) - ref = ObjectReference.for(doubled_class) - ExampleMethods.declare_verifying_double(InstanceVerifyingDouble, ref, *args) - end - - # @overload class_double(doubled_class) - # @param doubled_class [String, Module] - # @overload class_double(doubled_class, name) - # @param doubled_class [String, Module] - # @param name [String/Symbol] name or description to be used in failure messages - # @overload class_double(doubled_class, stubs) - # @param doubled_class [String, Module] - # @param stubs [Hash] hash of message/return-value pairs - # @overload class_double(doubled_class, name, stubs) - # @param doubled_class [String, Module] - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs [Hash] hash of message/return-value pairs - # @return ClassVerifyingDouble - # - # Constructs a test double against a specific class. If the given class - # name has been loaded, only class methods defined on the class are - # allowed to be stubbed. In all other ways it behaves like a - # [double](double). - def class_double(doubled_class, *args) - ref = ObjectReference.for(doubled_class) - ExampleMethods.declare_verifying_double(ClassVerifyingDouble, ref, *args) - end - - # @overload object_double(object_or_name) - # @param object_or_name [String, Object] - # @overload object_double(object_or_name, name) - # @param object_or_name [String, Object] - # @param name [String/Symbol] name or description to be used in failure messages - # @overload object_double(object_or_name, stubs) - # @param object_or_name [String, Object] - # @param stubs [Hash] hash of message/return-value pairs - # @overload object_double(object_or_name, name, stubs) - # @param object_or_name [String, Object] - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs [Hash] hash of message/return-value pairs - # @return ObjectVerifyingDouble - # - # Constructs a test double against a specific object. Only the methods - # the object responds to are allowed to be stubbed. If a String argument - # is provided, it is assumed to reference a constant object which is used - # for verification. In all other ways it behaves like a [double](double). - def object_double(object_or_name, *args) - ref = ObjectReference.for(object_or_name, :allow_direct_object_refs) - ExampleMethods.declare_verifying_double(ObjectVerifyingDouble, ref, *args) - end - - # @overload spy() - # @overload spy(name) - # @param name [String/Symbol] name or description to be used in failure messages - # @overload spy(stubs) - # @param stubs (Hash) hash of message/return-value pairs - # @overload spy(name, stubs) - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs (Hash) hash of message/return-value pairs - # @return (Double) - # - # Constructs a test double that is optimized for use with - # `have_received`. With a normal double one has to stub methods in order - # to be able to spy them. A spy automatically spies on all methods. - def spy(*args) - double(*args).as_null_object - end - - # @overload instance_spy(doubled_class) - # @param doubled_class [String, Class] - # @overload instance_spy(doubled_class, name) - # @param doubled_class [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @overload instance_spy(doubled_class, stubs) - # @param doubled_class [String, Class] - # @param stubs [Hash] hash of message/return-value pairs - # @overload instance_spy(doubled_class, name, stubs) - # @param doubled_class [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs [Hash] hash of message/return-value pairs - # @return InstanceVerifyingDouble - # - # Constructs a test double that is optimized for use with `have_received` - # against a specific class. If the given class name has been loaded, only - # instance methods defined on the class are allowed to be stubbed. With - # a normal double one has to stub methods in order to be able to spy - # them. An instance_spy automatically spies on all instance methods to - # which the class responds. - def instance_spy(*args) - instance_double(*args).as_null_object - end - - # @overload object_spy(object_or_name) - # @param object_or_name [String, Object] - # @overload object_spy(object_or_name, name) - # @param object_or_name [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @overload object_spy(object_or_name, stubs) - # @param object_or_name [String, Object] - # @param stubs [Hash] hash of message/return-value pairs - # @overload object_spy(object_or_name, name, stubs) - # @param object_or_name [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs [Hash] hash of message/return-value pairs - # @return ObjectVerifyingDouble - # - # Constructs a test double that is optimized for use with `have_received` - # against a specific object. Only instance methods defined on the object - # are allowed to be stubbed. With a normal double one has to stub - # methods in order to be able to spy them. An object_spy automatically - # spies on all methods to which the object responds. - def object_spy(*args) - object_double(*args).as_null_object - end - - # @overload class_spy(doubled_class) - # @param doubled_class [String, Module] - # @overload class_spy(doubled_class, name) - # @param doubled_class [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @overload class_spy(doubled_class, stubs) - # @param doubled_class [String, Module] - # @param stubs [Hash] hash of message/return-value pairs - # @overload class_spy(doubled_class, name, stubs) - # @param doubled_class [String, Class] - # @param name [String/Symbol] name or description to be used in failure messages - # @param stubs [Hash] hash of message/return-value pairs - # @return ClassVerifyingDouble - # - # Constructs a test double that is optimized for use with `have_received` - # against a specific class. If the given class name has been loaded, - # only class methods defined on the class are allowed to be stubbed. - # With a normal double one has to stub methods in order to be able to spy - # them. An class_spy automatically spies on all class methods to which the - # class responds. - def class_spy(*args) - class_double(*args).as_null_object - end - - # Disables warning messages about expectations being set on nil. - # - # By default warning messages are issued when expectations are set on - # nil. This is to prevent false-positives and to catch potential bugs - # early on. - # @deprecated Use {RSpec::Mocks::Configuration#allow_message_expectations_on_nil} instead. - def allow_message_expectations_on_nil - RSpec::Mocks.space.proxy_for(nil).warn_about_expectations = false - end - - # Stubs the named constant with the given value. - # Like method stubs, the constant will be restored - # to its original value (or lack of one, if it was - # undefined) when the example completes. - # - # @param constant_name [String] The fully qualified name of the constant. The current - # constant scoping at the point of call is not considered. - # @param value [Object] The value to make the constant refer to. When the - # example completes, the constant will be restored to its prior state. - # @param options [Hash] Stubbing options. - # @option options :transfer_nested_constants [Boolean, Array] Determines - # what nested constants, if any, will be transferred from the original value - # of the constant to the new value of the constant. This only works if both - # the original and new values are modules (or classes). - # @return [Object] the stubbed value of the constant - # - # @example - # stub_const("MyClass", Class.new) # => Replaces (or defines) MyClass with a new class object. - # stub_const("SomeModel::PER_PAGE", 5) # => Sets SomeModel::PER_PAGE to 5. - # - # class CardDeck - # SUITS = [:Spades, :Diamonds, :Clubs, :Hearts] - # NUM_CARDS = 52 - # end - # - # stub_const("CardDeck", Class.new) - # CardDeck::SUITS # => uninitialized constant error - # CardDeck::NUM_CARDS # => uninitialized constant error - # - # stub_const("CardDeck", Class.new, :transfer_nested_constants => true) - # CardDeck::SUITS # => our suits array - # CardDeck::NUM_CARDS # => 52 - # - # stub_const("CardDeck", Class.new, :transfer_nested_constants => [:SUITS]) - # CardDeck::SUITS # => our suits array - # CardDeck::NUM_CARDS # => uninitialized constant error - def stub_const(constant_name, value, options={}) - ConstantMutator.stub(constant_name, value, options) - end - - # Hides the named constant with the given value. The constant will be - # undefined for the duration of the test. - # - # Like method stubs, the constant will be restored to its original value - # when the example completes. - # - # @param constant_name [String] The fully qualified name of the constant. - # The current constant scoping at the point of call is not considered. - # - # @example - # hide_const("MyClass") # => MyClass is now an undefined constant - def hide_const(constant_name) - ConstantMutator.hide(constant_name) - end - - # Verifies that the given object received the expected message during the - # course of the test. On a spy objects or as null object doubles this - # works for any method, on other objects the method must have - # been stubbed beforehand in order for messages to be verified. - # - # Stubbing and verifying messages received in this way implements the - # Test Spy pattern. - # - # @param method_name [Symbol] name of the method expected to have been - # called. - # - # @example - # invitation = double('invitation', accept: true) - # user.accept_invitation(invitation) - # expect(invitation).to have_received(:accept) - # - # # You can also use most message expectations: - # expect(invitation).to have_received(:accept).with(mailer).once - # - # @note `have_received(...).with(...)` is unable to work properly when - # passed arguments are mutated after the spy records the received message. - def have_received(method_name, &block) - Matchers::HaveReceived.new(method_name, &block) - end - - # Turns off the verifying of partial doubles for the duration of the - # block, this is useful in situations where methods are defined at run - # time and you wish to define stubs for them but not turn off partial - # doubles for the entire run suite. (e.g. view specs in rspec-rails). - def without_partial_double_verification - original_state = Mocks.configuration.temporarily_suppress_partial_double_verification - Mocks.configuration.temporarily_suppress_partial_double_verification = true - yield - ensure - Mocks.configuration.temporarily_suppress_partial_double_verification = original_state - end - - # @method expect - # Used to wrap an object in preparation for setting a mock expectation - # on it. - # - # @example - # expect(obj).to receive(:foo).with(5).and_return(:return_value) - # - # @note This method is usually provided by rspec-expectations. However, - # if you use rspec-mocks without rspec-expectations, there's a definition - # of it that is made available here. If you disable the `:expect` syntax - # this method will be undefined. - - # @method allow - # Used to wrap an object in preparation for stubbing a method - # on it. - # - # @example - # allow(dbl).to receive(:foo).with(5).and_return(:return_value) - # - # @note If you disable the `:expect` syntax this method will be undefined. - - # @method expect_any_instance_of - # Used to wrap a class in preparation for setting a mock expectation - # on instances of it. - # - # @example - # expect_any_instance_of(MyClass).to receive(:foo) - # - # @note If you disable the `:expect` syntax this method will be undefined. - - # @method allow_any_instance_of - # Used to wrap a class in preparation for stubbing a method - # on instances of it. - # - # @example - # allow_any_instance_of(MyClass).to receive(:foo) - # - # @note This is only available when you have enabled the `expect` syntax. - - # @method receive - # Used to specify a message that you expect or allow an object - # to receive. The object returned by `receive` supports the same - # fluent interface that `should_receive` and `stub` have always - # supported, allowing you to constrain the arguments or number of - # times, and configure how the object should respond to the message. - # - # @example - # expect(obj).to receive(:hello).with("world").exactly(3).times - # - # @note If you disable the `:expect` syntax this method will be undefined. - - # @method receive_messages - # Shorthand syntax used to setup message(s), and their return value(s), - # that you expect or allow an object to receive. The method takes a hash - # of messages and their respective return values. Unlike with `receive`, - # you cannot apply further customizations using a block or the fluent - # interface. - # - # @example - # allow(obj).to receive_messages(:speak => "Hello World") - # allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow") - # - # @note If you disable the `:expect` syntax this method will be undefined. - - # @method receive_message_chain - # @overload receive_message_chain(method1, method2) - # @overload receive_message_chain("method1.method2") - # @overload receive_message_chain(method1, method_to_value_hash) - # - # stubs/mocks a chain of messages on an object or test double. - # - # ## Warning: - # - # Chains can be arbitrarily long, which makes it quite painless to - # violate the Law of Demeter in violent ways, so you should consider any - # use of `receive_message_chain` a code smell. Even though not all code smells - # indicate real problems (think fluent interfaces), `receive_message_chain` still - # results in brittle examples. For example, if you write - # `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the - # implementation calls `foo.baz.bar`, the stub will not work. - # - # @example - # allow(double).to receive_message_chain("foo.bar") { :baz } - # allow(double).to receive_message_chain(:foo, :bar => :baz) - # allow(double).to receive_message_chain(:foo, :bar) { :baz } - # - # # Given any of ^^ these three forms ^^: - # double.foo.bar # => :baz - # - # # Common use in Rails/ActiveRecord: - # allow(Article).to receive_message_chain("recent.published") { [Article.new] } - # - # @note If you disable the `:expect` syntax this method will be undefined. - - # @private - def self.included(klass) - klass.class_exec do - # This gets mixed in so that if `RSpec::Matchers` is included in - # `klass` later, its definition of `expect` will take precedence. - include ExpectHost unless method_defined?(:expect) - end - end - - # @private - def self.extended(object) - # This gets extended in so that if `RSpec::Matchers` is included in - # `klass` later, its definition of `expect` will take precedence. - object.extend ExpectHost unless object.respond_to?(:expect) - end - - # @private - def self.declare_verifying_double(type, ref, *args) - if RSpec::Mocks.configuration.verify_doubled_constant_names? && - !ref.defined? - - RSpec::Mocks.error_generator.raise_verifying_double_not_defined_error(ref) - end - - RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| - block.call(ref) - end - - declare_double(type, ref, *args) - end - - # @private - def self.declare_double(type, *args) - args << {} unless Hash === args.last - type.new(*args) - end - - # This module exists to host the `expect` method for cases where - # rspec-mocks is used w/o rspec-expectations. - module ExpectHost - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb deleted file mode 100644 index 12edec2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/instance_method_stasher.rb +++ /dev/null @@ -1,146 +0,0 @@ -module RSpec - module Mocks - # @private - class InstanceMethodStasher - def initialize(object, method) - @object = object - @method = method - @klass = (class << object; self; end) - - @original_method = nil - @method_is_stashed = false - end - - attr_reader :original_method - - if RUBY_VERSION.to_f < 1.9 - # @private - def method_is_stashed? - @method_is_stashed - end - - # @private - def stash - return if !method_defined_directly_on_klass? || @method_is_stashed - - @klass.__send__(:alias_method, stashed_method_name, @method) - @method_is_stashed = true - end - - # @private - def stashed_method_name - "obfuscated_by_rspec_mocks__#{@method}" - end - - # @private - def restore - return unless @method_is_stashed - - if @klass.__send__(:method_defined?, @method) - @klass.__send__(:undef_method, @method) - end - @klass.__send__(:alias_method, @method, stashed_method_name) - @klass.__send__(:remove_method, stashed_method_name) - @method_is_stashed = false - end - else - - # @private - def method_is_stashed? - !!@original_method - end - - # @private - def stash - return unless method_defined_directly_on_klass? - @original_method ||= ::RSpec::Support.method_handle_for(@object, @method) - @klass.__send__(:undef_method, @method) - end - - # @private - def restore - return unless @original_method - - if @klass.__send__(:method_defined?, @method) - @klass.__send__(:undef_method, @method) - end - - handle_restoration_failures do - @klass.__send__(:define_method, @method, @original_method) - end - - @original_method = nil - end - end - - if RUBY_DESCRIPTION.include?('2.0.0p247') || RUBY_DESCRIPTION.include?('2.0.0p195') - # ruby 2.0.0-p247 and 2.0.0-p195 both have a bug that we can't work around :(. - # https://bugs.ruby-lang.org/issues/8686 - def handle_restoration_failures - yield - rescue TypeError - RSpec.warn_with( - "RSpec failed to properly restore a partial double (#{@object.inspect}) " \ - "to its original state due to a known bug in MRI 2.0.0-p195 & p247 " \ - "(https://bugs.ruby-lang.org/issues/8686). This object may remain " \ - "screwed up for the rest of this process. Please upgrade to 2.0.0-p353 or above.", - :call_site => nil, :use_spec_location_as_call_site => true - ) - end - else - def handle_restoration_failures - # No known reasons for restoration to fail on other rubies. - yield - end - end - - private - - # @private - def method_defined_directly_on_klass? - method_defined_on_klass? && method_owned_by_klass? - end - - # @private - def method_defined_on_klass?(klass=@klass) - MethodReference.method_defined_at_any_visibility?(klass, @method) - end - - def method_owned_by_klass? - owner = @klass.instance_method(@method).owner - - # On Ruby 2.0.0+ the owner of a method on a class which has been - # `prepend`ed may actually be an instance, e.g. - # `#`, rather than the expected `MyClass`. - owner = owner.class unless Module === owner - - # On some 1.9s (e.g. rubinius) aliased methods - # can report the wrong owner. Example: - # class MyClass - # class << self - # alias alternate_new new - # end - # end - # - # MyClass.owner(:alternate_new) returns `Class` when incorrect, - # but we need to consider the owner to be `MyClass` because - # it is not actually available on `Class` but is on `MyClass`. - # Hence, we verify that the owner actually has the method defined. - # If the given owner does not have the method defined, we assume - # that the method is actually owned by @klass. - # - # On 1.8, aliased methods can also report the wrong owner. Example: - # module M - # def a; end - # module_function :a - # alias b a - # module_function :b - # end - # The owner of M.b is the raw Module object, instead of the expected - # singleton class of the module - return true if RUBY_VERSION < '1.9' && owner == @object - owner == @klass || !(method_defined_on_klass?(owner)) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb deleted file mode 100644 index cfa9c1a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/marshal_extension.rb +++ /dev/null @@ -1,41 +0,0 @@ -module RSpec - module Mocks - # Support for `patch_marshal_to_support_partial_doubles` configuration. - # - # @private - class MarshalExtension - def self.patch! - return if Marshal.respond_to?(:dump_with_rspec_mocks) - - Marshal.instance_eval do - class << self - def dump_with_rspec_mocks(object, *rest) - if !::RSpec::Mocks.space.registered?(object) || NilClass === object - dump_without_rspec_mocks(object, *rest) - else - dump_without_rspec_mocks(object.dup, *rest) - end - end - - alias_method :dump_without_rspec_mocks, :dump - undef_method :dump - alias_method :dump, :dump_with_rspec_mocks - end - end - end - - def self.unpatch! - return unless Marshal.respond_to?(:dump_with_rspec_mocks) - - Marshal.instance_eval do - class << self - undef_method :dump_with_rspec_mocks - undef_method :dump - alias_method :dump, :dump_without_rspec_mocks - undef_method :dump_without_rspec_mocks - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb deleted file mode 100644 index 81e6427..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/expectation_customization.rb +++ /dev/null @@ -1,20 +0,0 @@ -module RSpec - module Mocks - module Matchers - # @private - class ExpectationCustomization - attr_accessor :block - - def initialize(method_name, args, block) - @method_name = method_name - @args = args - @block = block - end - - def playback_onto(expectation) - expectation.__send__(@method_name, *@args, &@block) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb deleted file mode 100644 index cf4852b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/have_received.rb +++ /dev/null @@ -1,134 +0,0 @@ -module RSpec - module Mocks - module Matchers - # @private - class HaveReceived - include Matcher - - COUNT_CONSTRAINTS = %w[exactly at_least at_most times time once twice thrice] - ARGS_CONSTRAINTS = %w[with] - CONSTRAINTS = COUNT_CONSTRAINTS + ARGS_CONSTRAINTS + %w[ordered] - - def initialize(method_name, &block) - @method_name = method_name - @block = block - @constraints = [] - @subject = nil - end - - def matcher_name - "have_received" - end - - def matches?(subject, &block) - @block ||= block - @subject = subject - @expectation = expect - mock_proxy.ensure_implemented(@method_name) - - expected_messages_received_in_order? - end - - def does_not_match?(subject) - @subject = subject - ensure_count_unconstrained - @expectation = expect.never - mock_proxy.ensure_implemented(@method_name) - expected_messages_received_in_order? - end - - def failure_message - capture_failure_message - end - - def failure_message_when_negated - capture_failure_message - end - - def description - (@expectation ||= expect).description_for("have received") - end - - CONSTRAINTS.each do |expectation| - define_method expectation do |*args| - @constraints << [expectation, *args] - self - end - end - - def setup_expectation(subject, &block) - notify_failure_message unless matches?(subject, &block) - end - - def setup_negative_expectation(subject, &block) - notify_failure_message unless does_not_match?(subject, &block) - end - - def setup_allowance(_subject, &_block) - disallow("allow", " as it would have no effect") - end - - def setup_any_instance_allowance(_subject, &_block) - disallow("allow_any_instance_of") - end - - def setup_any_instance_expectation(_subject, &_block) - disallow("expect_any_instance_of") - end - - def setup_any_instance_negative_expectation(_subject, &_block) - disallow("expect_any_instance_of") - end - - private - - def disallow(type, reason="") - RSpec::Mocks.error_generator.raise_have_received_disallowed(type, reason) - end - - def expect - expectation = mock_proxy.build_expectation(@method_name) - apply_constraints_to expectation - expectation - end - - def apply_constraints_to(expectation) - @constraints.each do |constraint| - expectation.send(*constraint) - end - end - - def ensure_count_unconstrained - return unless count_constraint - RSpec::Mocks.error_generator.raise_cant_constrain_count_for_negated_have_received_error(count_constraint) - end - - def count_constraint - @constraints.map(&:first).find do |constraint| - COUNT_CONSTRAINTS.include?(constraint) - end - end - - def capture_failure_message - RSpec::Support.with_failure_notifier(Proc.new { |err, _opt| return err.message }) do - notify_failure_message - end - end - - def notify_failure_message - mock_proxy.check_for_unexpected_arguments(@expectation) - @expectation.generate_error - end - - def expected_messages_received_in_order? - mock_proxy.replay_received_message_on @expectation, &@block - @expectation.expected_messages_received? && @expectation.ensure_expected_ordering_received! - end - - def mock_proxy - RSpec::Mocks.space.proxy_for(@subject) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb deleted file mode 100644 index ee95830..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive.rb +++ /dev/null @@ -1,134 +0,0 @@ -RSpec::Support.require_rspec_mocks 'matchers/expectation_customization' - -module RSpec - module Mocks - module Matchers - # @private - class Receive - include Matcher - - def initialize(message, block) - @message = message - @block = block - @recorded_customizations = [] - end - - def matcher_name - "receive" - end - - def description - describable.description_for("receive") - end - - def setup_expectation(subject, &block) - warn_if_any_instance("expect", subject) - @describable = setup_mock_proxy_method_substitute(subject, :add_message_expectation, block) - end - alias matches? setup_expectation - - def setup_negative_expectation(subject, &block) - # ensure `never` goes first for cases like `never.and_return(5)`, - # where `and_return` is meant to raise an error - @recorded_customizations.unshift ExpectationCustomization.new(:never, [], nil) - - warn_if_any_instance("expect", subject) - - setup_expectation(subject, &block) - end - alias does_not_match? setup_negative_expectation - - def setup_allowance(subject, &block) - warn_if_any_instance("allow", subject) - setup_mock_proxy_method_substitute(subject, :add_stub, block) - end - - def setup_any_instance_expectation(subject, &block) - setup_any_instance_method_substitute(subject, :should_receive, block) - end - - def setup_any_instance_negative_expectation(subject, &block) - setup_any_instance_method_substitute(subject, :should_not_receive, block) - end - - def setup_any_instance_allowance(subject, &block) - setup_any_instance_method_substitute(subject, :stub, block) - end - - own_methods = (instance_methods - superclass.instance_methods) - MessageExpectation.public_instance_methods(false).each do |method| - next if own_methods.include?(method) - - define_method(method) do |*args, &block| - @recorded_customizations << ExpectationCustomization.new(method, args, block) - self - end - ruby2_keywords(method) if respond_to?(:ruby2_keywords, true) - end - - private - - def describable - @describable ||= DefaultDescribable.new(@message) - end - - def warn_if_any_instance(expression, subject) - return unless AnyInstance::Proxy === subject - - RSpec.warning( - "`#{expression}(#{subject.klass}.any_instance).to` " \ - "is probably not what you meant, it does not operate on " \ - "any instance of `#{subject.klass}`. " \ - "Use `#{expression}_any_instance_of(#{subject.klass}).to` instead." - ) - end - - def setup_mock_proxy_method_substitute(subject, method, block) - proxy = ::RSpec::Mocks.space.proxy_for(subject) - setup_method_substitute(proxy, method, block) - end - - def setup_any_instance_method_substitute(subject, method, block) - proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) - setup_method_substitute(proxy, method, block) - end - - def setup_method_substitute(host, method, block, *args) - args << @message.to_sym - block = move_block_to_last_customization(block) - - expectation = host.__send__(method, *args, &(@block || block)) - - @recorded_customizations.each do |customization| - customization.playback_onto(expectation) - end - expectation - end - - def move_block_to_last_customization(block) - last = @recorded_customizations.last - return block unless last - - last.block ||= block - nil - end - - # MessageExpectation objects are able to describe themselves in detail. - # We use this as a fall back when a MessageExpectation is not available. - # @private - class DefaultDescribable - def initialize(message) - @message = message - end - - # This is much simpler for the `any_instance` case than what the - # user may want, but I'm not up for putting a bunch of effort - # into full descriptions for `any_instance` expectations at this point :(. - def description_for(verb) - "#{verb} #{@message}" - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb deleted file mode 100644 index fdc89f9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_message_chain.rb +++ /dev/null @@ -1,82 +0,0 @@ -RSpec::Support.require_rspec_mocks 'matchers/expectation_customization' - -module RSpec - module Mocks - module Matchers - # @private - class ReceiveMessageChain - include Matcher - - def initialize(chain, &block) - @chain = chain - @block = block - @recorded_customizations = [] - end - - [:with, :and_return, :and_invoke, :and_throw, :and_raise, :and_yield, :and_call_original].each do |msg| - define_method(msg) do |*args, &block| - @recorded_customizations << ExpectationCustomization.new(msg, args, block) - self - end - end - - def matcher_name - "receive_message_chain" - end - - def description - "receive message chain #{formatted_chain}" - end - - def setup_allowance(subject, &block) - chain = StubChain.stub_chain_on(subject, *@chain, &(@block || block)) - replay_customizations(chain) - end - - def setup_any_instance_allowance(subject, &block) - proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) - chain = proxy.stub_chain(*@chain, &(@block || block)) - replay_customizations(chain) - end - - def setup_any_instance_expectation(subject, &block) - proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) - chain = proxy.expect_chain(*@chain, &(@block || block)) - replay_customizations(chain) - end - - def setup_expectation(subject, &block) - chain = ExpectChain.expect_chain_on(subject, *@chain, &(@block || block)) - replay_customizations(chain) - end - - def setup_negative_expectation(*_args) - raise NegationUnsupportedError, - "`expect(...).not_to receive_message_chain` is not supported " \ - "since it doesn't really make sense. What would it even mean?" - end - - alias matches? setup_expectation - alias does_not_match? setup_negative_expectation - - private - - def replay_customizations(chain) - @recorded_customizations.each do |customization| - customization.playback_onto(chain) - end - end - - def formatted_chain - @formatted_chain ||= @chain.map do |part| - if Hash === part - part.keys.first.to_s - else - part.to_s - end - end.join(".") - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb deleted file mode 100644 index 6bf9047..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/matchers/receive_messages.rb +++ /dev/null @@ -1,77 +0,0 @@ -module RSpec - module Mocks - module Matchers - # @private - class ReceiveMessages - include Matcher - - def initialize(message_return_value_hash) - @message_return_value_hash = message_return_value_hash - @backtrace_line = CallerFilter.first_non_rspec_line - end - - def matcher_name - "receive_messages" - end - - def description - "receive messages: #{@message_return_value_hash.inspect}" - end - - def setup_expectation(subject) - warn_about_block if block_given? - each_message_on(proxy_on(subject)) do |host, message, return_value| - host.add_simple_expectation(message, return_value, @backtrace_line) - end - end - alias matches? setup_expectation - - def setup_negative_expectation(_subject) - raise NegationUnsupportedError, - "`expect(...).to_not receive_messages` is not supported since it " \ - "doesn't really make sense. What would it even mean?" - end - alias does_not_match? setup_negative_expectation - - def setup_allowance(subject) - warn_about_block if block_given? - each_message_on(proxy_on(subject)) do |host, message, return_value| - host.add_simple_stub(message, return_value) - end - end - - def setup_any_instance_expectation(subject) - warn_about_block if block_given? - each_message_on(any_instance_of(subject)) do |host, message, return_value| - host.should_receive(message).and_return(return_value) - end - end - - def setup_any_instance_allowance(subject) - warn_about_block if block_given? - any_instance_of(subject).stub(@message_return_value_hash) - end - - def warn_about_block - raise "Implementation blocks aren't supported with `receive_messages`" - end - - private - - def proxy_on(subject) - ::RSpec::Mocks.space.proxy_for(subject) - end - - def any_instance_of(subject) - ::RSpec::Mocks.space.any_instance_proxy_for(subject) - end - - def each_message_on(host) - @message_return_value_hash.each do |message, value| - yield host, message, value - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb deleted file mode 100644 index 907d14b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_chain.rb +++ /dev/null @@ -1,87 +0,0 @@ -module RSpec - module Mocks - # @private - class MessageChain - attr_reader :object, :chain, :block - - def initialize(object, *chain, &blk) - @object = object - @chain, @block = format_chain(*chain, &blk) - end - - # @api private - def setup_chain - if chain.length > 1 - if (matching_stub = find_matching_stub) - chain.shift - chain_on(matching_stub.invoke(nil), *chain, &@block) - elsif (matching_expectation = find_matching_expectation) - chain.shift - chain_on(matching_expectation.invoke_without_incrementing_received_count(nil), *chain, &@block) - else - next_in_chain = Double.new - expectation(object, chain.shift) { next_in_chain } - chain_on(next_in_chain, *chain, &@block) - end - else - expectation(object, chain.shift, &@block) - end - end - - private - - def chain_on(object, *chain, &block) - initialize(object, *chain, &block) - setup_chain - end - - def format_chain(*chain, &blk) - if Hash === chain.last - hash = chain.pop - hash.each do |k, v| - chain << k - blk = Proc.new { v } - end - end - return chain.join('.').split('.'), blk - end - - def find_matching_stub - ::RSpec::Mocks.space.proxy_for(object). - __send__(:find_matching_method_stub, chain.first.to_sym) - end - - def find_matching_expectation - ::RSpec::Mocks.space.proxy_for(object). - __send__(:find_matching_expectation, chain.first.to_sym) - end - end - - # @private - class ExpectChain < MessageChain - # @api private - def self.expect_chain_on(object, *chain, &blk) - new(object, *chain, &blk).setup_chain - end - - private - - def expectation(object, message, &return_block) - ::RSpec::Mocks.expect_message(object, message, {}, &return_block) - end - end - - # @private - class StubChain < MessageChain - def self.stub_chain_on(object, *chain, &blk) - new(object, *chain, &blk).setup_chain - end - - private - - def expectation(object, message, &return_block) - ::RSpec::Mocks.allow_message(object, message, {}, &return_block) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb deleted file mode 100644 index a478db7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/message_expectation.rb +++ /dev/null @@ -1,856 +0,0 @@ -RSpec::Support.require_rspec_support 'mutex' - -module RSpec - module Mocks - # A message expectation that only allows concrete return values to be set - # for a message. While this same effect can be achieved using a standard - # MessageExpectation, this version is much faster and so can be used as an - # optimization. - # - # @private - class SimpleMessageExpectation - def initialize(message, response, error_generator, backtrace_line=nil) - @message, @response, @error_generator, @backtrace_line = message.to_sym, response, error_generator, backtrace_line - @received = false - end - - def invoke(*_) - @received = true - @response - end - - def matches?(message, *_) - @message == message.to_sym - end - - def called_max_times? - false - end - - def verify_messages_received - return if @received - @error_generator.raise_expectation_error( - @message, 1, ArgumentListMatcher::MATCH_ALL, 0, nil, [], @backtrace_line - ) - end - - def unadvise(_) - end - end - - # Represents an individual method stub or message expectation. The methods - # defined here can be used to configure how it behaves. The methods return - # `self` so that they can be chained together to form a fluent interface. - class MessageExpectation - # @!group Configuring Responses - - # @overload and_return(value) - # @overload and_return(first_value, second_value) - # - # Tells the object to return a value when it receives the message. Given - # more than one value, the first value is returned the first time the - # message is received, the second value is returned the next time, etc, - # etc. - # - # If the message is received more times than there are values, the last - # value is returned for every subsequent call. - # - # @return [nil] No further chaining is supported after this. - # @example - # allow(counter).to receive(:count).and_return(1) - # counter.count # => 1 - # counter.count # => 1 - # - # allow(counter).to receive(:count).and_return(1,2,3) - # counter.count # => 1 - # counter.count # => 2 - # counter.count # => 3 - # counter.count # => 3 - # counter.count # => 3 - # # etc - def and_return(first_value, *values, &_block) - raise_already_invoked_error_if_necessary(__method__) - if negative? - raise "`and_return` is not supported with negative message expectations" - end - - if block_given? - raise ArgumentError, "Implementation blocks aren't supported with `and_return`" - end - - values.unshift(first_value) - @expected_received_count = [@expected_received_count, values.size].max unless ignoring_args? || (@expected_received_count == 0 && @at_least) - self.terminal_implementation_action = AndReturnImplementation.new(values) - - nil - end - - # Tells the object to invoke a Proc when it receives the message. Given - # more than one value, the result of the first Proc is returned the first - # time the message is received, the result of the second Proc is returned - # the next time, etc, etc. - # - # If the message is received more times than there are Procs, the result of - # the last Proc is returned for every subsequent call. - # - # @return [nil] No further chaining is supported after this. - # @example - # allow(api).to receive(:get_foo).and_invoke(-> { raise ApiTimeout }) - # api.get_foo # => raises ApiTimeout - # api.get_foo # => raises ApiTimeout - # - # allow(api).to receive(:get_foo).and_invoke(-> { raise ApiTimeout }, -> { raise ApiTimeout }, -> { :a_foo }) - # api.get_foo # => raises ApiTimeout - # api.get_foo # => raises ApiTimeout - # api.get_foo # => :a_foo - # api.get_foo # => :a_foo - # api.get_foo # => :a_foo - # # etc - def and_invoke(first_proc, *procs, &_block) - raise_already_invoked_error_if_necessary(__method__) - if negative? - raise "`and_invoke` is not supported with negative message expectations" - end - - if block_given? - raise ArgumentError, "Implementation blocks aren't supported with `and_invoke`" - end - - procs.unshift(first_proc) - if procs.any? { |p| !p.respond_to?(:call) } - raise ArgumentError, "Arguments to `and_invoke` must be callable." - end - - @expected_received_count = [@expected_received_count, procs.size].max unless ignoring_args? || (@expected_received_count == 0 && @at_least) - self.terminal_implementation_action = AndInvokeImplementation.new(procs) - - nil - end - - # Tells the object to delegate to the original unmodified method - # when it receives the message. - # - # @note This is only available on partial doubles. - # - # @return [nil] No further chaining is supported after this. - # @example - # expect(counter).to receive(:increment).and_call_original - # original_count = counter.count - # counter.increment - # expect(counter.count).to eq(original_count + 1) - def and_call_original - block = lambda do |original, *args, &b| - original.call(*args, &b) - end - block = block.ruby2_keywords if block.respond_to?(:ruby2_keywords) - - wrap_original(__method__, &block) - end - - # Decorates the stubbed method with the supplied block. The original - # unmodified method is passed to the block along with any method call - # arguments so you can delegate to it, whilst still being able to - # change what args are passed to it and/or change the return value. - # - # @note This is only available on partial doubles. - # - # @return [nil] No further chaining is supported after this. - # @example - # expect(api).to receive(:large_list).and_wrap_original do |original_method, *args, &block| - # original_method.call(*args, &block).first(10) - # end - def and_wrap_original(&block) - wrap_original(__method__, &block) - end - - # @overload and_raise - # @overload and_raise(ExceptionClass) - # @overload and_raise(ExceptionClass, message) - # @overload and_raise(exception_instance) - # - # Tells the object to raise an exception when the message is received. - # - # @return [nil] No further chaining is supported after this. - # @note - # When you pass an exception class, the MessageExpectation will raise - # an instance of it, creating it with `exception` and passing `message` - # if specified. If the exception class initializer requires more than - # one parameters, you must pass in an instance and not the class, - # otherwise this method will raise an ArgumentError exception. - # - # @example - # allow(car).to receive(:go).and_raise - # allow(car).to receive(:go).and_raise(OutOfGas) - # allow(car).to receive(:go).and_raise(OutOfGas, "At least 2 oz of gas needed to drive") - # allow(car).to receive(:go).and_raise(OutOfGas.new(2, :oz)) - def and_raise(*args) - raise_already_invoked_error_if_necessary(__method__) - self.terminal_implementation_action = Proc.new { raise(*args) } - nil - end - - # @overload and_throw(symbol) - # @overload and_throw(symbol, object) - # - # Tells the object to throw a symbol (with the object if that form is - # used) when the message is received. - # - # @return [nil] No further chaining is supported after this. - # @example - # allow(car).to receive(:go).and_throw(:out_of_gas) - # allow(car).to receive(:go).and_throw(:out_of_gas, :level => 0.1) - def and_throw(*args) - raise_already_invoked_error_if_necessary(__method__) - self.terminal_implementation_action = Proc.new { throw(*args) } - nil - end - - # Tells the object to yield one or more args to a block when the message - # is received. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # stream.stub(:open).and_yield(StringIO.new) - def and_yield(*args, &block) - raise_already_invoked_error_if_necessary(__method__) - yield @eval_context = Object.new if block - - # Initialize args to yield now that it's being used, see also: comment - # in constructor. - @args_to_yield ||= [] - - @args_to_yield << args - self.initial_implementation_action = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator) - self - end - # @!endgroup - - # @!group Constraining Receive Counts - - # Constrain a message expectation to be received a specific number of - # times. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(dealer).to receive(:deal_card).exactly(10).times - def exactly(n, &block) - raise_already_invoked_error_if_necessary(__method__) - self.inner_implementation_action = block - set_expected_received_count :exactly, n - self - end - - # Constrain a message expectation to be received at least a specific - # number of times. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(dealer).to receive(:deal_card).at_least(9).times - def at_least(n, &block) - raise_already_invoked_error_if_necessary(__method__) - set_expected_received_count :at_least, n - - if n == 0 - raise "at_least(0) has been removed, use allow(...).to receive(:message) instead" - end - - self.inner_implementation_action = block - - self - end - - # Constrain a message expectation to be received at most a specific - # number of times. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(dealer).to receive(:deal_card).at_most(10).times - def at_most(n, &block) - raise_already_invoked_error_if_necessary(__method__) - self.inner_implementation_action = block - set_expected_received_count :at_most, n - self - end - - # Syntactic sugar for `exactly`, `at_least` and `at_most` - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(dealer).to receive(:deal_card).exactly(10).times - # expect(dealer).to receive(:deal_card).at_least(10).times - # expect(dealer).to receive(:deal_card).at_most(10).times - def times(&block) - self.inner_implementation_action = block - self - end - alias time times - - # Expect a message not to be received at all. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(car).to receive(:stop).never - def never - error_generator.raise_double_negation_error("expect(obj)") if negative? - @expected_received_count = 0 - self - end - - # Expect a message to be received exactly one time. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(car).to receive(:go).once - def once(&block) - self.inner_implementation_action = block - set_expected_received_count :exactly, 1 - self - end - - # Expect a message to be received exactly two times. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(car).to receive(:go).twice - def twice(&block) - self.inner_implementation_action = block - set_expected_received_count :exactly, 2 - self - end - - # Expect a message to be received exactly three times. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(car).to receive(:go).thrice - def thrice(&block) - self.inner_implementation_action = block - set_expected_received_count :exactly, 3 - self - end - # @!endgroup - - # @!group Other Constraints - - # Constrains a stub or message expectation to invocations with specific - # arguments. - # - # With a stub, if the message might be received with other args as well, - # you should stub a default value first, and then stub or mock the same - # message using `with` to constrain to specific arguments. - # - # A message expectation will fail if the message is received with different - # arguments. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # allow(cart).to receive(:add) { :failure } - # allow(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success } - # cart.add(Book.new(:isbn => 1234567890)) - # # => :failure - # cart.add(Book.new(:isbn => 1934356379)) - # # => :success - # - # expect(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success } - # cart.add(Book.new(:isbn => 1234567890)) - # # => failed expectation - # cart.add(Book.new(:isbn => 1934356379)) - # # => passes - def with(*args, &block) - raise_already_invoked_error_if_necessary(__method__) - if args.empty? - raise ArgumentError, - "`with` must have at least one argument. Use `no_args` matcher to set the expectation of receiving no arguments." - end - - self.inner_implementation_action = block - @argument_list_matcher = ArgumentListMatcher.new(*args) - self - end - ruby2_keywords(:with) if respond_to?(:ruby2_keywords, true) - - # Expect messages to be received in a specific order. - # - # @return [MessageExpectation] self, to support further chaining. - # @example - # expect(api).to receive(:prepare).ordered - # expect(api).to receive(:run).ordered - # expect(api).to receive(:finish).ordered - def ordered(&block) - if type == :stub - RSpec.warning( - "`allow(...).to receive(..).ordered` is not supported and will " \ - "have no effect, use `and_return(*ordered_values)` instead." - ) - end - - self.inner_implementation_action = block - additional_expected_calls.times do - @order_group.register(self) - end - @ordered = true - self - end - - # @return [String] a nice representation of the message expectation - def to_s - args_description = error_generator.method_call_args_description(@argument_list_matcher.expected_args, "", "") { true } - args_description = "(#{args_description})" unless args_description.start_with?("(") - "#<#{self.class} #{error_generator.intro}.#{message}#{args_description}>" - end - alias inspect to_s - - # Implementation details is a long module - # rubocop:disable Metrics/ModuleLength - - # @private - # Contains the parts of `MessageExpectation` that aren't part of - # rspec-mocks' public API. The class is very big and could really use - # some collaborators it delegates to for this stuff but for now this was - # the simplest way to split the public from private stuff to make it - # easier to publish the docs for the APIs we want published. - module ImplementationDetails - attr_accessor :error_generator, :implementation - attr_reader :message - attr_reader :orig_object - attr_writer :expected_received_count, :expected_from, :argument_list_matcher - protected :expected_received_count=, :expected_from=, :error_generator=, :implementation= - - # @private - attr_reader :type - - # rubocop:disable Metrics/ParameterLists - def initialize(error_generator, expectation_ordering, expected_from, method_double, - type=:expectation, opts={}, &implementation_block) - @type = type - @error_generator = error_generator - @error_generator.opts = error_generator.opts.merge(opts) - @expected_from = expected_from - @method_double = method_double - @orig_object = @method_double.object - @message = @method_double.method_name - @actual_received_count = 0 - @actual_received_count_write_mutex = Support::Mutex.new - @expected_received_count = type == :expectation ? 1 : :any - @argument_list_matcher = ArgumentListMatcher::MATCH_ALL - @order_group = expectation_ordering - @order_group.register(self) unless type == :stub - @expectation_type = type - @ordered = false - @at_least = @at_most = @exactly = nil - - self.invoking_internals = false - - # Initialized to nil so that we don't allocate an array for every - # mock or stub. See also comment in `and_yield`. - @args_to_yield = nil - @eval_context = nil - @yield_receiver_to_implementation_block = false - - @implementation = Implementation.new - self.inner_implementation_action = implementation_block - end - # rubocop:enable Metrics/ParameterLists - - def expected_args - @argument_list_matcher.expected_args - end - - def and_yield_receiver_to_implementation - @yield_receiver_to_implementation_block = true - self - end - - def yield_receiver_to_implementation_block? - @yield_receiver_to_implementation_block - end - - def matches?(message, *args) - @message == message && @argument_list_matcher.args_match?(*args) - end - ruby2_keywords :matches? if respond_to?(:ruby2_keywords, true) - - def safe_invoke(parent_stub, *args, &block) - invoke_incrementing_actual_calls_by(1, false, parent_stub, *args, &block) - end - ruby2_keywords :safe_invoke if respond_to?(:ruby2_keywords, true) - - def invoke(parent_stub, *args, &block) - if invoking_internals - safe_invoke_without_incrementing_received_count(parent_stub, *args, &block) - else - invoke_incrementing_actual_calls_by(1, true, parent_stub, *args, &block) - end - end - ruby2_keywords :invoke if respond_to?(:ruby2_keywords, true) - - def safe_invoke_without_incrementing_received_count(parent_stub, *args, &block) - invoke_incrementing_actual_calls_by(0, false, parent_stub, *args, &block) - end - ruby2_keywords :safe_invoke_without_incrementing_received_count if respond_to?(:ruby2_keywords, true) - - def invoke_without_incrementing_received_count(parent_stub, *args, &block) - invoke_incrementing_actual_calls_by(0, true, parent_stub, *args, &block) - end - ruby2_keywords :invoke_without_incrementing_received_count if respond_to?(:ruby2_keywords, true) - - def negative? - @expected_received_count == 0 && !@at_least - end - - def called_max_times? - @expected_received_count != :any && - !@at_least && - @expected_received_count > 0 && - @actual_received_count >= @expected_received_count - end - - def matches_name_but_not_args(message, *args) - @message == message && !@argument_list_matcher.args_match?(*args) - end - - def verify_messages_received - return if expected_messages_received? - generate_error - end - - def expected_messages_received? - ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count? - end - - def ensure_expected_ordering_received! - @order_group.verify_invocation_order(self) if @ordered - true - end - - def ignoring_args? - @expected_received_count == :any - end - - def matches_at_least_count? - @at_least && @actual_received_count >= @expected_received_count - end - - def matches_at_most_count? - @at_most && @actual_received_count <= @expected_received_count - end - - def matches_exact_count? - @expected_received_count == @actual_received_count - end - - def similar_messages - @similar_messages ||= [] - end - - def advise(*args) - similar_messages << args - end - - def unadvise(args) - similar_messages.delete_if { |message| args.include?(message) } - end - - def generate_error - if similar_messages.empty? - @error_generator.raise_expectation_error( - @message, @expected_received_count, @argument_list_matcher, - @actual_received_count, expectation_count_type, expected_args, - @expected_from, exception_source_id - ) - else - @error_generator.raise_similar_message_args_error( - self, @similar_messages, @expected_from - ) - end - end - - def raise_unexpected_message_args_error(args_for_multiple_calls) - @error_generator.raise_unexpected_message_args_error(self, args_for_multiple_calls, exception_source_id) - end - - def expectation_count_type - return :at_least if @at_least - return :at_most if @at_most - nil - end - - def description_for(verb) - @error_generator.describe_expectation( - verb, @message, @expected_received_count, - @actual_received_count, expected_args - ) - end - - def raise_out_of_order_error - @error_generator.raise_out_of_order_error @message - end - - def additional_expected_calls - return 0 if @expectation_type == :stub || !@exactly - @expected_received_count - 1 - end - - def ordered? - @ordered - end - - def negative_expectation_for?(message) - @message == message && negative? - end - - def actual_received_count_matters? - @at_least || @at_most || @exactly - end - - def increase_actual_received_count! - @actual_received_count_write_mutex.synchronize do - @actual_received_count += 1 - end - end - - private - - def exception_source_id - @exception_source_id ||= "#{self.class.name} #{__id__}" - end - - def invoking_internals - RSpec::Support.thread_local_data[:"__rspec_#{object_id}_invoking_internals"] - end - - def invoking_internals=(value) - # We clear the key for this rather than setting to false because otherwise the amount of - # thread local data will keep growing over the lifetime of the thread (which is a long - # time on a single threaded spec run e.g standard MRI) - if value - RSpec::Support.thread_local_data[:"__rspec_#{object_id}_invoking_internals"] = true - else - RSpec::Support.thread_local_data.delete(:"__rspec_#{object_id}_invoking_internals") - end - end - - def invoke_incrementing_actual_calls_by(increment, allowed_to_fail, parent_stub, *args, &block) - self.invoking_internals = true - - args.unshift(orig_object) if yield_receiver_to_implementation_block? - - if negative? || (allowed_to_fail && (@exactly || @at_most) && (@actual_received_count == @expected_received_count)) - # args are the args we actually received, @argument_list_matcher is the - # list of args we were expecting - @error_generator.raise_expectation_error( - @message, @expected_received_count, - @argument_list_matcher, - @actual_received_count + increment, - expectation_count_type, args, nil, exception_source_id - ) - end - - @order_group.handle_order_constraint self - - self.invoking_internals = false - - if implementation.present? - implementation.call(*args, &block) - elsif parent_stub - parent_stub.invoke(nil, *args, &block) - end - ensure - self.invoking_internals = false - @actual_received_count_write_mutex.synchronize do - @actual_received_count += increment - end - end - ruby2_keywords :invoke_incrementing_actual_calls_by if respond_to?(:ruby2_keywords, true) - - def has_been_invoked? - @actual_received_count > 0 - end - - def raise_already_invoked_error_if_necessary(calling_customization) - return unless has_been_invoked? - - error_generator.raise_already_invoked_error(message, calling_customization) - end - - def set_expected_received_count(relativity, n) - raise "`count` is not supported with negative message expectations" if negative? - @at_least = (relativity == :at_least) - @at_most = (relativity == :at_most) - @exactly = (relativity == :exactly) - @expected_received_count = case n - when Numeric then n - when :once then 1 - when :twice then 2 - when :thrice then 3 - end - end - - def initial_implementation_action=(action) - implementation.initial_action = action - end - - def inner_implementation_action=(action) - return unless action - warn_about_stub_override if implementation.inner_action - implementation.inner_action = action - end - - def terminal_implementation_action=(action) - implementation.terminal_action = action - end - - def warn_about_stub_override - RSpec.warning( - "You're overriding a previous stub implementation of `#{@message}`. " \ - "Called from #{CallerFilter.first_non_rspec_line}." - ) - end - - def wrap_original(method_name, &block) - if RSpec::Mocks::TestDouble === @method_double.object - @error_generator.raise_only_valid_on_a_partial_double(method_name) - else - warn_about_stub_override if implementation.inner_action - @implementation = AndWrapOriginalImplementation.new(@method_double.original_implementation_callable, block) - @yield_receiver_to_implementation_block = false - end - - nil - end - end - - include ImplementationDetails - end - # rubocop:enable Metrics/ModuleLength - - # Handles the implementation of an `and_yield` declaration. - # @private - class AndYieldImplementation - def initialize(args_to_yield, eval_context, error_generator) - @args_to_yield = args_to_yield - @eval_context = eval_context - @error_generator = error_generator - end - - def call(*_args_to_ignore, &block) - return if @args_to_yield.empty? && @eval_context.nil? - - @error_generator.raise_missing_block_error @args_to_yield unless block - value = nil - block_signature = Support::BlockSignature.new(block) - - @args_to_yield.each do |args| - unless Support::StrictSignatureVerifier.new(block_signature, args).valid? - @error_generator.raise_wrong_arity_error(args, block_signature) - end - - value = @eval_context ? @eval_context.instance_exec(*args, &block) : yield(*args) - end - value - end - end - - # Handles the implementation of an `and_return` implementation. - # @private - class AndReturnImplementation - def initialize(values_to_return) - @values_to_return = values_to_return - end - - def call(*_args_to_ignore, &_block) - if @values_to_return.size > 1 - @values_to_return.shift - else - @values_to_return.first - end - end - end - - # Handles the implementation of an `and_invoke` implementation. - # @private - class AndInvokeImplementation - def initialize(procs_to_invoke) - @procs_to_invoke = procs_to_invoke - end - - def call(*args, &block) - proc = if @procs_to_invoke.size > 1 - @procs_to_invoke.shift - else - @procs_to_invoke.first - end - - proc.call(*args, &block) - end - ruby2_keywords(:call) if respond_to?(:ruby2_keywords, true) - end - - # Represents a configured implementation. Takes into account - # any number of sub-implementations. - # @private - class Implementation - attr_accessor :initial_action, :inner_action, :terminal_action - - def call(*args, &block) - actions.map do |action| - action.call(*args, &block) - end.last - end - ruby2_keywords :call if respond_to?(:ruby2_keywords, true) - - def present? - actions.any? - end - - private - - def actions - [initial_action, inner_action, terminal_action].compact - end - end - - # Represents an `and_call_original` implementation. - # @private - class AndWrapOriginalImplementation - def initialize(method, block) - @method = method - @block = block - end - - CannotModifyFurtherError = Class.new(StandardError) - - def initial_action=(_value) - raise cannot_modify_further_error - end - - def inner_action=(_value) - raise cannot_modify_further_error - end - - def terminal_action=(_value) - raise cannot_modify_further_error - end - - def present? - true - end - - def inner_action - true - end - - def call(*args, &block) - @block.call(@method, *args, &block) - end - ruby2_keywords :call if respond_to?(:ruby2_keywords, true) - - private - - def cannot_modify_further_error - CannotModifyFurtherError.new "This method has already been configured " \ - "to call the original implementation, and cannot be modified further." - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb deleted file mode 100644 index 7417f65..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_double.rb +++ /dev/null @@ -1,316 +0,0 @@ -module RSpec - module Mocks - # @private - class MethodDouble - # @private TODO: drop in favor of FrozenError in ruby 2.5+ - FROZEN_ERROR_MSG = /can't modify frozen/ - - # @private - attr_reader :method_name, :object, :expectations, :stubs, :method_stasher - - # @private - def initialize(object, method_name, proxy) - @method_name = method_name - @object = object - @proxy = proxy - - @original_visibility = nil - @method_stasher = InstanceMethodStasher.new(object, method_name) - @method_is_proxied = false - @expectations = [] - @stubs = [] - end - - def original_implementation_callable - # If original method is not present, uses the `method_missing` - # handler of the object. This accounts for cases where the user has not - # correctly defined `respond_to?`, and also 1.8 which does not provide - # method handles for missing methods even if `respond_to?` is correct. - @original_implementation_callable ||= original_method || method_missing_block - end - - alias_method :save_original_implementation_callable!, :original_implementation_callable - - def original_method - @original_method ||= - @method_stasher.original_method || - @proxy.original_method_handle_for(method_name) - end - - # @private - def method_missing_block - block = Proc.new do |*args, &b| - @object.__send__(:method_missing, @method_name, *args, &b) - end - block.ruby2_keywords if block.respond_to?(:ruby2_keywords) - - block - end - - # @private - def visibility - @proxy.visibility_for(@method_name) - end - - # @private - def object_singleton_class - class << @object; self; end - end - - # @private - def configure_method - @original_visibility = visibility - @method_stasher.stash unless @method_is_proxied - define_proxy_method - end - - # @private - def define_proxy_method - return if @method_is_proxied - - save_original_implementation_callable! - definition_target.class_exec(self, method_name, @original_visibility || visibility) do |method_double, method_name, visibility| - define_method(method_name) do |*args, &block| - method_double.proxy_method_invoked(self, *args, &block) - end - # This can't be `if respond_to?(:ruby2_keywords, true)`, - # see https://github.com/rspec/rspec-mocks/pull/1385#issuecomment-755340298 - ruby2_keywords(method_name) if Module.private_method_defined?(:ruby2_keywords) - __send__(visibility, method_name) - end - - @method_is_proxied = true - rescue RuntimeError, TypeError => e - # TODO: drop in favor of FrozenError in ruby 2.5+ - # RuntimeError (and FrozenError) for ruby 2.x - # TypeError for ruby 1.x - if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message - raise ArgumentError, "Cannot proxy frozen objects, rspec-mocks relies on proxies for method stubbing and expectations." - end - raise - end - - # The implementation of the proxied method. Subclasses may override this - # method to perform additional operations. - # - # @private - def proxy_method_invoked(_obj, *args, &block) - @proxy.message_received method_name, *args, &block - end - ruby2_keywords :proxy_method_invoked if respond_to?(:ruby2_keywords, true) - - # @private - def restore_original_method - return unless @method_is_proxied - - remove_method_from_definition_target - @method_stasher.restore if @method_stasher.method_is_stashed? - restore_original_visibility - - @method_is_proxied = false - rescue RuntimeError, TypeError => e - # TODO: drop in favor of FrozenError in ruby 2.5+ - # RuntimeError (and FrozenError) for ruby 2.x - # TypeError for ruby 1.x - if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message - return show_frozen_warning - end - raise - end - - # @private - def show_frozen_warning - RSpec.warn_with( - "WARNING: rspec-mocks was unable to restore the original `#{@method_name}` " \ - "method on #{@object.inspect} because it has been frozen. If you reuse this " \ - "object, `#{@method_name}` will continue to respond with its stub implementation.", - :call_site => nil, - :use_spec_location_as_call_site => true - ) - end - - # @private - def restore_original_visibility - return unless @original_visibility && - MethodReference.method_defined_at_any_visibility?(object_singleton_class, @method_name) - - object_singleton_class.__send__(@original_visibility, method_name) - end - - # @private - def verify - expectations.each { |e| e.verify_messages_received } - end - - # @private - def reset - restore_original_method - clear - end - - # @private - def clear - expectations.clear - stubs.clear - end - - # The type of message expectation to create has been extracted to its own - # method so that subclasses can override it. - # - # @private - def message_expectation_class - MessageExpectation - end - - # @private - def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation) - configure_method - expectation = message_expectation_class.new(error_generator, expectation_ordering, - expected_from, self, :expectation, opts, &implementation) - expectations << expectation - expectation - end - - # @private - def build_expectation(error_generator, expectation_ordering) - expected_from = IGNORED_BACKTRACE_LINE - message_expectation_class.new(error_generator, expectation_ordering, expected_from, self) - end - - # @private - def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation) - configure_method - stub = message_expectation_class.new(error_generator, expectation_ordering, expected_from, - self, :stub, opts, &implementation) - stubs.unshift stub - stub - end - - # A simple stub can only return a concrete value for a message, and - # cannot match on arguments. It is used as an optimization over - # `add_stub` / `add_expectation` where it is known in advance that this - # is all that will be required of a stub, such as when passing attributes - # to the `double` example method. They do not stash or restore existing method - # definitions. - # - # @private - def add_simple_stub(method_name, response) - setup_simple_method_double method_name, response, stubs - end - - # @private - def add_simple_expectation(method_name, response, error_generator, backtrace_line) - setup_simple_method_double method_name, response, expectations, error_generator, backtrace_line - end - - # @private - def setup_simple_method_double(method_name, response, collection, error_generator=nil, backtrace_line=nil) - define_proxy_method - - me = SimpleMessageExpectation.new(method_name, response, error_generator, backtrace_line) - collection.unshift me - me - end - - # @private - def add_default_stub(*args, &implementation) - return if stubs.any? - add_stub(*args, &implementation) - end - - # @private - def remove_stub - raise_method_not_stubbed_error if stubs.empty? - remove_stub_if_present - end - - # @private - def remove_stub_if_present - expectations.empty? ? reset : stubs.clear - end - - # @private - def raise_method_not_stubbed_error - RSpec::Mocks.error_generator.raise_method_not_stubbed_error(method_name) - end - - # In Ruby 2.0.0 and above prepend will alter the method lookup chain. - # We use an object's singleton class to define method doubles upon, - # however if the object has had its singleton class (as opposed to - # its actual class) prepended too then the the method lookup chain - # will look in the prepended module first, **before** the singleton - # class. - # - # This code works around that by providing a mock definition target - # that is either the singleton class, or if necessary, a prepended module - # of our own. - # - if Support::RubyFeatures.module_prepends_supported? - - private - - # We subclass `Module` in order to be able to easily detect our prepended module. - RSpecPrependedModule = Class.new(Module) - - def definition_target - @definition_target ||= usable_rspec_prepended_module || object_singleton_class - end - - def usable_rspec_prepended_module - @proxy.prepended_modules_of_singleton_class.each do |mod| - # If we have one of our modules prepended before one of the user's - # modules that defines the method, use that, since our module's - # definition will take precedence. - return mod if RSpecPrependedModule === mod - - # If we hit a user module with the method defined first, - # we must create a new prepend module, even if one exists later, - # because ours will only take precedence if it comes first. - return new_rspec_prepended_module if mod.method_defined?(method_name) - end - - nil - end - - def new_rspec_prepended_module - RSpecPrependedModule.new.tap do |mod| - object_singleton_class.__send__ :prepend, mod - end - end - - else - - private - - def definition_target - object_singleton_class - end - - end - - private - - def remove_method_from_definition_target - definition_target.__send__(:remove_method, @method_name) - rescue NameError - # This can happen when the method has been monkeyed with by - # something outside RSpec. This happens, for example, when - # `file.write` has been stubbed, and then `file.reopen(other_io)` - # is later called, as `File#reopen` appears to redefine `write`. - # - # Note: we could avoid rescuing this by checking - # `definition_target.instance_method(@method_name).owner == definition_target`, - # saving us from the cost of the expensive exception, but this error is - # extremely rare (it was discovered on 2014-12-30, only happens on - # RUBY_VERSION < 2.0 and our spec suite only hits this condition once), - # so we'd rather avoid the cost of that check for every method double, - # and risk the rare situation where this exception will get raised. - RSpec.warn_with( - "WARNING: RSpec could not fully restore #{@object.inspect}." \ - "#{@method_name}, possibly because the method has been redefined " \ - "by something outside of RSpec." - ) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb deleted file mode 100644 index 50608b0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/method_reference.rb +++ /dev/null @@ -1,214 +0,0 @@ -RSpec::Support.require_rspec_support 'comparable_version' - -module RSpec - module Mocks - # Represents a method on an object that may or may not be defined. - # The method may be an instance method on a module or a method on - # any object. - # - # @private - class MethodReference - def self.for(object_reference, method_name) - new(object_reference, method_name) - end - - def initialize(object_reference, method_name) - @object_reference = object_reference - @method_name = method_name - end - - # A method is implemented if sending the message does not result in - # a `NoMethodError`. It might be dynamically implemented by - # `method_missing`. - def implemented? - @object_reference.when_loaded do |m| - method_implemented?(m) - end - end - - # Returns true if we definitively know that sending the method - # will result in a `NoMethodError`. - # - # This is not simply the inverse of `implemented?`: there are - # cases when we don't know if a method is implemented and - # both `implemented?` and `unimplemented?` will return false. - def unimplemented? - @object_reference.when_loaded do |_m| - return !implemented? - end - - # If it's not loaded, then it may be implemented but we can't check. - false - end - - # A method is defined if we are able to get a `Method` object for it. - # In that case, we can assert against metadata like the arity. - def defined? - @object_reference.when_loaded do |m| - method_defined?(m) - end - end - - def with_signature - return unless (original = original_method) - yield Support::MethodSignature.new(original) - end - - def visibility - @object_reference.when_loaded do |m| - return visibility_from(m) - end - - # When it's not loaded, assume it's public. We don't want to - # wrongly treat the method as private. - :public - end - - def self.instance_method_visibility_for(klass, method_name) - if klass.public_method_defined?(method_name) - :public - elsif klass.private_method_defined?(method_name) - :private - elsif klass.protected_method_defined?(method_name) - :protected - end - end - - class << self - alias method_defined_at_any_visibility? instance_method_visibility_for - end - - def self.method_visibility_for(object, method_name) - vis = instance_method_visibility_for(class << object; self; end, method_name) - - # If the method is not defined on the class, `instance_method_visibility_for` - # returns `nil`. However, it may be handled dynamically by `method_missing`, - # so here we check `respond_to` (passing false to not check private methods). - # - # This only considers the public case, but I don't think it's possible to - # write `method_missing` in such a way that it handles a dynamic message - # with private or protected visibility. Ruby doesn't provide you with - # the caller info. - return vis unless vis.nil? - - proxy = RSpec::Mocks.space.proxy_for(object) - respond_to = proxy.method_double_if_exists_for_message(:respond_to?) - - visible = respond_to && respond_to.original_method.call(method_name) || - object.respond_to?(method_name) - - return :public if visible - end - - private - - def original_method - @object_reference.when_loaded do |m| - self.defined? && find_method(m) - end - end - end - - # @private - class InstanceMethodReference < MethodReference - private - - def method_implemented?(mod) - MethodReference.method_defined_at_any_visibility?(mod, @method_name) - end - - # Ideally, we'd use `respond_to?` for `method_implemented?` but we need a - # reference to an instance to do that and we don't have one. Note that - # we may get false negatives: if the method is implemented via - # `method_missing`, we'll return `false` even though it meets our - # definition of "implemented". However, it's the best we can do. - alias method_defined? method_implemented? - - # works around the fact that repeated calls for method parameters will - # falsely return empty arrays on JRuby in certain circumstances, this - # is necessary here because we can't dup/clone UnboundMethods. - # - # This is necessary due to a bug in JRuby prior to 1.7.5 fixed in: - # https://github.com/jruby/jruby/commit/99a0613fe29935150d76a9a1ee4cf2b4f63f4a27 - if RUBY_PLATFORM == 'java' && RSpec::Support::ComparableVersion.new(JRUBY_VERSION) < '1.7.5' - def find_method(mod) - mod.dup.instance_method(@method_name) - end - else - def find_method(mod) - mod.instance_method(@method_name) - end - end - - def visibility_from(mod) - MethodReference.instance_method_visibility_for(mod, @method_name) - end - end - - # @private - class ObjectMethodReference < MethodReference - def self.for(object_reference, method_name) - if ClassNewMethodReference.applies_to?(method_name) { object_reference.when_loaded { |o| o } } - ClassNewMethodReference.new(object_reference, method_name) - else - super - end - end - - private - - def method_implemented?(object) - object.respond_to?(@method_name, true) - end - - def method_defined?(object) - (class << object; self; end).method_defined?(@method_name) - end - - def find_method(object) - object.method(@method_name) - end - - def visibility_from(object) - MethodReference.method_visibility_for(object, @method_name) - end - end - - # When a class's `.new` method is stubbed, we want to use the method - # signature from `#initialize` because `.new`'s signature is a generic - # `def new(*args)` and it simply delegates to `#initialize` and forwards - # all args...so the method with the actually used signature is `#initialize`. - # - # This method reference implementation handles that specific case. - # @private - class ClassNewMethodReference < ObjectMethodReference - def self.applies_to?(method_name) - return false unless method_name == :new - klass = yield - return false unless ::Class === klass && klass.respond_to?(:new, true) - - # We only want to apply our special logic to normal `new` methods. - # Methods that the user has monkeyed with should be left as-is. - uses_class_new?(klass) - end - - if RUBY_VERSION.to_i >= 3 - CLASS_NEW = ::Class.instance_method(:new) - - def self.uses_class_new?(klass) - ::RSpec::Support.method_handle_for(klass, :new) == CLASS_NEW.bind(klass) - end - else # Ruby 2's Method#== is too strict - def self.uses_class_new?(klass) - ::RSpec::Support.method_handle_for(klass, :new).owner == ::Class - end - end - - def with_signature - @object_reference.when_loaded do |klass| - yield Support::MethodSignature.new(klass.instance_method(:initialize)) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb deleted file mode 100644 index a129890..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/minitest_integration.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'rspec/mocks' - -module RSpec - module Mocks - # @private - module MinitestIntegration - include ::RSpec::Mocks::ExampleMethods - - def before_setup - ::RSpec::Mocks.setup - super - end - - def after_teardown - super - - # Only verify if there's not already an error. Otherwise - # we risk getting the same failure twice, since negative - # expectation violations raise both when the message is - # unexpectedly received, and also during `verify` (in case - # the first failure was caught by user code via a - # `rescue Exception`). - ::RSpec::Mocks.verify unless failures.any? - ensure - ::RSpec::Mocks.teardown - end - end - end -end - -Minitest::Test.send(:include, RSpec::Mocks::MinitestIntegration) - -if defined?(::Minitest::Expectation) - if defined?(::RSpec::Expectations) && ::Minitest::Expectation.method_defined?(:to) - # rspec/expectations/minitest_integration has already been loaded and - # has defined `to`/`not_to`/`to_not` on `Minitest::Expectation` so we do - # not want to here (or else we would interfere with rspec-expectations' definition). - else - # ...otherwise, define those methods now. If `rspec/expectations/minitest_integration` - # is loaded after this file, it'll override the definition here. - Minitest::Expectation.class_eval do - include RSpec::Mocks::ExpectationTargetMethods - - def to(*args) - ctx.assertions += 1 - super - end - - def not_to(*args) - ctx.assertions += 1 - super - end - - def to_not(*args) - ctx.assertions += 1 - super - end - end - end -end - -module RSpec - module Mocks - remove_const :MockExpectationError - # Raised when a message expectation is not satisfied. - MockExpectationError = ::Minitest::Assertion - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb deleted file mode 100644 index 071d7a2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/mutate_const.rb +++ /dev/null @@ -1,339 +0,0 @@ -RSpec::Support.require_rspec_support 'recursive_const_methods' - -module RSpec - module Mocks - # Provides information about constants that may (or may not) - # have been mutated by rspec-mocks. - class Constant - extend Support::RecursiveConstMethods - - # @api private - def initialize(name) - @name = name - @previously_defined = false - @stubbed = false - @hidden = false - @valid_name = true - yield self if block_given? - end - - # @return [String] The fully qualified name of the constant. - attr_reader :name - - # @return [Object, nil] The original value (e.g. before it - # was mutated by rspec-mocks) of the constant, or - # nil if the constant was not previously defined. - attr_accessor :original_value - - # @private - attr_writer :previously_defined, :stubbed, :hidden, :valid_name - - # @return [Boolean] Whether or not the constant was defined - # before the current example. - def previously_defined? - @previously_defined - end - - # @return [Boolean] Whether or not rspec-mocks has mutated - # (stubbed or hidden) this constant. - def mutated? - @stubbed || @hidden - end - - # @return [Boolean] Whether or not rspec-mocks has stubbed - # this constant. - def stubbed? - @stubbed - end - - # @return [Boolean] Whether or not rspec-mocks has hidden - # this constant. - def hidden? - @hidden - end - - # @return [Boolean] Whether or not the provided constant name - # is a valid Ruby constant name. - def valid_name? - @valid_name - end - - # The default `to_s` isn't very useful, so a custom version is provided. - def to_s - "#<#{self.class.name} #{name}>" - end - alias inspect to_s - - # @private - def self.unmutated(name) - previously_defined = !!recursive_const_defined?(name) - rescue NameError - new(name) do |c| - c.valid_name = false - end - else - new(name) do |const| - const.previously_defined = previously_defined - const.original_value = recursive_const_get(name) if previously_defined - end - end - - # Queries rspec-mocks to find out information about the named constant. - # - # @param [String] name the name of the constant - # @return [Constant] an object containing information about the named - # constant. - def self.original(name) - mutator = ::RSpec::Mocks.space.constant_mutator_for(name) - mutator ? mutator.to_constant : unmutated(name) - end - end - - # Provides a means to stub constants. - class ConstantMutator - extend Support::RecursiveConstMethods - - # Stubs a constant. - # - # @param (see ExampleMethods#stub_const) - # @option (see ExampleMethods#stub_const) - # @return (see ExampleMethods#stub_const) - # - # @see ExampleMethods#stub_const - # @note It's recommended that you use `stub_const` in your - # examples. This is an alternate public API that is provided - # so you can stub constants in other contexts (e.g. helper - # classes). - def self.stub(constant_name, value, options={}) - unless String === constant_name - raise ArgumentError, "`stub_const` requires a String, but you provided a #{constant_name.class.name}" - end - - mutator = if recursive_const_defined?(constant_name, &raise_on_invalid_const) - DefinedConstantReplacer - else - UndefinedConstantSetter - end - - mutate(mutator.new(constant_name, value, options[:transfer_nested_constants])) - value - end - - # Hides a constant. - # - # @param (see ExampleMethods#hide_const) - # - # @see ExampleMethods#hide_const - # @note It's recommended that you use `hide_const` in your - # examples. This is an alternate public API that is provided - # so you can hide constants in other contexts (e.g. helper - # classes). - def self.hide(constant_name) - mutate(ConstantHider.new(constant_name, nil, {})) - nil - end - - # Contains common functionality used by all of the constant mutators. - # - # @private - class BaseMutator - include Support::RecursiveConstMethods - - attr_reader :original_value, :full_constant_name - - def initialize(full_constant_name, mutated_value, transfer_nested_constants) - @full_constant_name = normalize_const_name(full_constant_name) - @mutated_value = mutated_value - @transfer_nested_constants = transfer_nested_constants - @context_parts = @full_constant_name.split('::') - @const_name = @context_parts.pop - @reset_performed = false - end - - def to_constant - const = Constant.new(full_constant_name) - const.original_value = original_value - - const - end - - def idempotently_reset - reset unless @reset_performed - @reset_performed = true - end - end - - # Hides a defined constant for the duration of an example. - # - # @private - class ConstantHider < BaseMutator - def mutate - return unless (@defined = recursive_const_defined?(full_constant_name)) - @context = recursive_const_get(@context_parts.join('::')) - @original_value = get_const_defined_on(@context, @const_name) - - @context.__send__(:remove_const, @const_name) - end - - def to_constant - return Constant.unmutated(full_constant_name) unless @defined - - const = super - const.hidden = true - const.previously_defined = true - - const - end - - def reset - return unless @defined - @context.const_set(@const_name, @original_value) - end - end - - # Replaces a defined constant for the duration of an example. - # - # @private - class DefinedConstantReplacer < BaseMutator - def initialize(*args) - super - @constants_to_transfer = [] - end - - def mutate - @context = recursive_const_get(@context_parts.join('::')) - @original_value = get_const_defined_on(@context, @const_name) - - @constants_to_transfer = verify_constants_to_transfer! - - @context.__send__(:remove_const, @const_name) - @context.const_set(@const_name, @mutated_value) - - transfer_nested_constants - end - - def to_constant - const = super - const.stubbed = true - const.previously_defined = true - - const - end - - def reset - @constants_to_transfer.each do |const| - @mutated_value.__send__(:remove_const, const) - end - - @context.__send__(:remove_const, @const_name) - @context.const_set(@const_name, @original_value) - end - - def transfer_nested_constants - @constants_to_transfer.each do |const| - @mutated_value.const_set(const, get_const_defined_on(original_value, const)) - end - end - - def verify_constants_to_transfer! - return [] unless should_transfer_nested_constants? - - { @original_value => "the original value", @mutated_value => "the stubbed value" }.each do |value, description| - next if value.respond_to?(:constants) - - raise ArgumentError, - "Cannot transfer nested constants for #{@full_constant_name} " \ - "since #{description} is not a class or module and only classes " \ - "and modules support nested constants." - end - - if Array === @transfer_nested_constants - @transfer_nested_constants = @transfer_nested_constants.map(&:to_s) if RUBY_VERSION == '1.8.7' - undefined_constants = @transfer_nested_constants - constants_defined_on(@original_value) - - if undefined_constants.any? - available_constants = constants_defined_on(@original_value) - @transfer_nested_constants - raise ArgumentError, - "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " \ - "for #{@full_constant_name} since they are not defined. Did you mean " \ - "#{available_constants.join(' or ')}?" - end - - @transfer_nested_constants - else - constants_defined_on(@original_value) - end - end - - def should_transfer_nested_constants? - return true if @transfer_nested_constants - return false unless RSpec::Mocks.configuration.transfer_nested_constants? - @original_value.respond_to?(:constants) && @mutated_value.respond_to?(:constants) - end - end - - # Sets an undefined constant for the duration of an example. - # - # @private - class UndefinedConstantSetter < BaseMutator - def mutate - @parent = @context_parts.inject(Object) do |klass, name| - if const_defined_on?(klass, name) - get_const_defined_on(klass, name) - else - ConstantMutator.stub(name_for(klass, name), Module.new) - end - end - - @parent.const_set(@const_name, @mutated_value) - end - - def to_constant - const = super - const.stubbed = true - const.previously_defined = false - - const - end - - def reset - @parent.__send__(:remove_const, @const_name) - end - - private - - def name_for(parent, name) - root = if parent == Object - '' - else - parent.name - end - root + '::' + name - end - end - - # Uses the mutator to mutate (stub or hide) a constant. Ensures that - # the mutator is correctly registered so it can be backed out at the end - # of the test. - # - # @private - def self.mutate(mutator) - ::RSpec::Mocks.space.register_constant_mutator(mutator) - mutator.mutate - end - - # Used internally by the constant stubbing to raise a helpful - # error when a constant like "A::B::C" is stubbed and A::B is - # not a module (and thus, it's impossible to define "A::B::C" - # since only modules can have nested constants). - # - # @api private - def self.raise_on_invalid_const - lambda do |const_name, failed_name| - raise "Cannot stub constant #{failed_name} on #{const_name} " \ - "since #{const_name} is not a module." - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb deleted file mode 100644 index cce2c33..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/object_reference.rb +++ /dev/null @@ -1,149 +0,0 @@ -module RSpec - module Mocks - # @private - class ObjectReference - # Returns an appropriate Object or Module reference based - # on the given argument. - def self.for(object_module_or_name, allow_direct_object_refs=false) - case object_module_or_name - when Module - if anonymous_module?(object_module_or_name) - DirectObjectReference.new(object_module_or_name) - else - # Use a `NamedObjectReference` if it has a name because this - # will use the original value of the constant in case it has - # been stubbed. - NamedObjectReference.new(name_of(object_module_or_name)) - end - when String - NamedObjectReference.new(object_module_or_name) - else - if allow_direct_object_refs - DirectObjectReference.new(object_module_or_name) - else - raise ArgumentError, - "Module or String expected, got #{object_module_or_name.inspect}" - end - end - end - - if Module.new.name.nil? - def self.anonymous_module?(mod) - !name_of(mod) - end - else # 1.8.7 - def self.anonymous_module?(mod) - name_of(mod) == "" - end - end - private_class_method :anonymous_module? - - def self.name_of(mod) - MODULE_NAME_METHOD.bind(mod).call - end - private_class_method :name_of - - # @private - MODULE_NAME_METHOD = Module.instance_method(:name) - end - - # An implementation of rspec-mocks' reference interface. - # Used when an object is passed to {ExampleMethods#object_double}, or - # an anonymous class or module is passed to {ExampleMethods#instance_double} - # or {ExampleMethods#class_double}. - # Represents a reference to that object. - # @see NamedObjectReference - class DirectObjectReference - # @param object [Object] the object to which this refers - def initialize(object) - @object = object - end - - # @return [String] the object's description (via `#inspect`). - def description - @object.inspect - end - - # Defined for interface parity with the other object reference - # implementations. Raises an `ArgumentError` to indicate that `as_stubbed_const` - # is invalid when passing an object argument to `object_double`. - def const_to_replace - raise ArgumentError, - "Can not perform constant replacement with an anonymous object." - end - - # The target of the verifying double (the object itself). - # - # @return [Object] - def target - @object - end - - # Always returns true for an object as the class is defined. - # - # @return [true] - def defined? - true - end - - # Yields if the reference target is loaded, providing a generic mechanism - # to optionally run a bit of code only when a reference's target is - # loaded. - # - # This specific implementation always yields because direct references - # are always loaded. - # - # @yield [Object] the target of this reference. - def when_loaded - yield @object - end - end - - # An implementation of rspec-mocks' reference interface. - # Used when a string is passed to {ExampleMethods#object_double}, - # and when a string, named class or named module is passed to - # {ExampleMethods#instance_double}, or {ExampleMethods#class_double}. - # Represents a reference to the object named (via a constant lookup) - # by the string. - # @see DirectObjectReference - class NamedObjectReference - # @param const_name [String] constant name - def initialize(const_name) - @const_name = const_name - end - - # @return [Boolean] true if the named constant is defined, false otherwise. - def defined? - !!object - end - - # @return [String] the constant name to replace with a double. - def const_to_replace - @const_name - end - alias description const_to_replace - - # @return [Object, nil] the target of the verifying double (the named object), or - # nil if it is not defined. - def target - object - end - - # Yields if the reference target is loaded, providing a generic mechanism - # to optionally run a bit of code only when a reference's target is - # loaded. - # - # @yield [Object] the target object - def when_loaded - yield object if object - end - - private - - def object - return @object if defined?(@object) - @object = Constant.original(@const_name).original_value - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb deleted file mode 100644 index a994799..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/order_group.rb +++ /dev/null @@ -1,81 +0,0 @@ -module RSpec - module Mocks - # @private - class OrderGroup - def initialize - @expectations = [] - @invocation_order = [] - @index = 0 - end - - # @private - def register(expectation) - @expectations << expectation - end - - def invoked(message) - @invocation_order << message - end - - # @private - def ready_for?(expectation) - remaining_expectations.find(&:ordered?) == expectation - end - - # @private - def consume - remaining_expectations.each_with_index do |expectation, index| - next unless expectation.ordered? - - @index += index + 1 - return expectation - end - nil - end - - # @private - def handle_order_constraint(expectation) - return unless expectation.ordered? && remaining_expectations.include?(expectation) - return consume if ready_for?(expectation) - expectation.raise_out_of_order_error - end - - def verify_invocation_order(expectation) - expectation.raise_out_of_order_error unless expectations_invoked_in_order? - true - end - - def clear - @index = 0 - @invocation_order.clear - @expectations.clear - end - - def empty? - @expectations.empty? - end - - private - - def remaining_expectations - @expectations[@index..-1] || [] - end - - def expectations_invoked_in_order? - invoked_expectations == expected_invocations - end - - def invoked_expectations - @expectations.select { |e| e.ordered? && @invocation_order.include?(e) } - end - - def expected_invocations - @invocation_order.map { |invocation| expectation_for(invocation) }.compact - end - - def expectation_for(message) - @expectations.find { |e| message == e } - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb deleted file mode 100644 index 6bd1393..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/proxy.rb +++ /dev/null @@ -1,517 +0,0 @@ -RSpec::Support.require_rspec_support 'mutex' - -module RSpec - module Mocks - # @private - class Proxy - # @private - SpecificMessage = Struct.new(:object, :message, :args) do - def ==(expectation) - expectation.orig_object == object && expectation.matches?(message, *args) - end - end - - # @private - def ensure_implemented(*_args) - # noop for basic proxies, see VerifyingProxy for behaviour. - end - - # @private - def initialize(object, order_group, options={}) - ensure_can_be_proxied!(object) - - @object = object - @order_group = order_group - @error_generator = ErrorGenerator.new(object) - @messages_received = [] - @messages_received_mutex = Support::Mutex.new - @options = options - @null_object = false - @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) } - end - - # @private - def ensure_can_be_proxied!(object) - return unless Symbol === object - - msg = "Cannot proxy frozen objects. Symbols such as #{object} cannot be mocked or stubbed." - raise ArgumentError, msg - end - - # @private - attr_reader :object - - # @private - def null_object? - @null_object - end - - # @private - # Tells the object to ignore any messages that aren't explicitly set as - # stubs or message expectations. - def as_null_object - @null_object = true - @object - end - - # @private - def original_method_handle_for(_message) - nil - end - - DEFAULT_MESSAGE_EXPECTATION_OPTS = {}.freeze - - # @private - def add_message_expectation(method_name, opts=DEFAULT_MESSAGE_EXPECTATION_OPTS, &block) - location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line } - meth_double = method_double_for(method_name) - - if null_object? && !block - meth_double.add_default_stub(@error_generator, @order_group, location, opts) do - @object - end - end - - meth_double.add_expectation @error_generator, @order_group, location, opts, &block - end - - # @private - def add_simple_expectation(method_name, response, location) - method_double_for(method_name).add_simple_expectation method_name, response, @error_generator, location - end - - # @private - def build_expectation(method_name) - meth_double = method_double_for(method_name) - - meth_double.build_expectation( - @error_generator, - @order_group - ) - end - - # @private - def replay_received_message_on(expectation, &block) - expected_method_name = expectation.message - meth_double = method_double_for(expected_method_name) - - if meth_double.expectations.any? - @error_generator.raise_expectation_on_mocked_method(expected_method_name) - end - - unless null_object? || meth_double.stubs.any? - @error_generator.raise_expectation_on_unstubbed_method(expected_method_name) - end - - @messages_received_mutex.synchronize do - @messages_received.each do |(actual_method_name, args, received_block)| - next unless expectation.matches?(actual_method_name, *args) - - expectation.safe_invoke(nil) - block.call(*args, &received_block) if block - end - end - end - - # @private - def check_for_unexpected_arguments(expectation) - @messages_received_mutex.synchronize do - return if @messages_received.empty? - - return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) } - - name_but_not_args, others = @messages_received.partition do |(method_name, args, _)| - expectation.matches_name_but_not_args(method_name, *args) - end - - return if name_but_not_args.empty? && !others.empty? - - expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] }) - end - end - - # @private - def add_stub(method_name, opts={}, &implementation) - location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line } - method_double_for(method_name).add_stub @error_generator, @order_group, location, opts, &implementation - end - - # @private - def add_simple_stub(method_name, response) - method_double_for(method_name).add_simple_stub method_name, response - end - - # @private - def remove_stub(method_name) - method_double_for(method_name).remove_stub - end - - # @private - def remove_stub_if_present(method_name) - method_double_for(method_name).remove_stub_if_present - end - - # @private - def verify - @method_doubles.each_value { |d| d.verify } - end - - # @private - def reset - @messages_received_mutex.synchronize do - @messages_received.clear - end - end - - # @private - def received_message?(method_name, *args, &block) - @messages_received_mutex.synchronize do - @messages_received.any? { |array| array == [method_name, args, block] } - end - end - - # @private - def messages_arg_list - @messages_received_mutex.synchronize do - @messages_received.map { |_, args, _| args } - end - end - - # @private - def has_negative_expectation?(message) - method_double_for(message).expectations.find { |expectation| expectation.negative_expectation_for?(message) } - end - - # @private - def record_message_received(message, *args, &block) - @order_group.invoked SpecificMessage.new(object, message, args) - @messages_received_mutex.synchronize do - @messages_received << [message, args, block] - end - end - ruby2_keywords :record_message_received if respond_to?(:ruby2_keywords, true) - - # @private - def message_received(message, *args, &block) - record_message_received message, *args, &block - - expectation = find_matching_expectation(message, *args) - stub = find_matching_method_stub(message, *args) - - if (stub && expectation && expectation.called_max_times?) || (stub && !expectation) - expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters? - if (expectation = find_almost_matching_expectation(message, *args)) - expectation.advise(*args) unless expectation.expected_messages_received? - end - stub.invoke(nil, *args, &block) - elsif expectation - expectation.unadvise(messages_arg_list) - expectation.invoke(stub, *args, &block) - elsif (expectation = find_almost_matching_expectation(message, *args)) - expectation.advise(*args) if null_object? unless expectation.expected_messages_received? - - if null_object? || !has_negative_expectation?(message) - expectation.raise_unexpected_message_args_error([args]) - end - elsif (stub = find_almost_matching_stub(message, *args)) - stub.advise(*args) - raise_missing_default_stub_error(stub, [args]) - elsif Class === @object - @object.superclass.__send__(message, *args, &block) - else - @object.__send__(:method_missing, message, *args, &block) - end - end - ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true) - - # @private - def raise_unexpected_message_error(method_name, args) - @error_generator.raise_unexpected_message_error method_name, args - end - - # @private - def raise_missing_default_stub_error(expectation, args_for_multiple_calls) - @error_generator.raise_missing_default_stub_error(expectation, args_for_multiple_calls) - end - - # @private - def visibility_for(_method_name) - # This is the default (for test doubles). Subclasses override this. - :public - end - - if Support::RubyFeatures.module_prepends_supported? - def self.prepended_modules_of(klass) - ancestors = klass.ancestors - - # `|| 0` is necessary for Ruby 2.0, where the singleton class - # is only in the ancestor list when there are prepended modules. - singleton_index = ancestors.index(klass) || 0 - - ancestors[0, singleton_index] - end - - def prepended_modules_of_singleton_class - @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class) - end - end - - # @private - def method_double_if_exists_for_message(message) - method_double_for(message) if @method_doubles.key?(message.to_sym) - end - - private - - def method_double_for(message) - @method_doubles[message.to_sym] - end - - def find_matching_expectation(method_name, *args) - find_best_matching_expectation_for(method_name) do |expectation| - expectation.matches?(method_name, *args) - end - end - ruby2_keywords :find_matching_expectation if respond_to?(:ruby2_keywords, true) - - def find_almost_matching_expectation(method_name, *args) - find_best_matching_expectation_for(method_name) do |expectation| - expectation.matches_name_but_not_args(method_name, *args) - end - end - ruby2_keywords :find_almost_matching_expectation if respond_to?(:ruby2_keywords, true) - - def find_best_matching_expectation_for(method_name) - first_match = nil - - method_double_for(method_name).expectations.each do |expectation| - next unless yield expectation - return expectation unless expectation.called_max_times? - first_match ||= expectation - end - - first_match - end - - def find_matching_method_stub(method_name, *args) - method_double_for(method_name).stubs.find { |stub| stub.matches?(method_name, *args) } - end - ruby2_keywords :find_matching_method_stub if respond_to?(:ruby2_keywords, true) - - def find_almost_matching_stub(method_name, *args) - method_double_for(method_name).stubs.find { |stub| stub.matches_name_but_not_args(method_name, *args) } - end - ruby2_keywords :find_almost_matching_stub if respond_to?(:ruby2_keywords, true) - end - - # @private - class TestDoubleProxy < Proxy - def reset - @method_doubles.clear - object.__disallow_further_usage! - super - end - end - - # @private - class PartialDoubleProxy < Proxy - def original_method_handle_for(message) - if any_instance_class_recorder_observing_method?(@object.class, message) - message = ::RSpec::Mocks.space. - any_instance_recorder_for(@object.class). - build_alias_method_name(message) - end - - ::RSpec::Support.method_handle_for(@object, message) - rescue NameError - nil - end - - # @private - def add_simple_expectation(method_name, response, location) - method_double_for(method_name).configure_method - super - end - - # @private - def add_simple_stub(method_name, response) - method_double_for(method_name).configure_method - super - end - - # @private - def visibility_for(method_name) - # We fall back to :public because by default we allow undefined methods - # to be stubbed, and when we do so, we make them public. - MethodReference.method_visibility_for(@object, method_name) || :public - end - - def reset - @method_doubles.each_value { |d| d.reset } - super - end - - def message_received(message, *args, &block) - RSpec::Mocks.space.any_instance_recorders_from_ancestry_of(object).each do |subscriber| - subscriber.notify_received_message(object, message, args, block) - end - super - end - ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true) - - private - - def any_instance_class_recorder_observing_method?(klass, method_name) - only_return_existing = true - recorder = ::RSpec::Mocks.space.any_instance_recorder_for(klass, only_return_existing) - return true if recorder && recorder.already_observing?(method_name) - - superklass = klass.superclass - return false if superklass.nil? - any_instance_class_recorder_observing_method?(superklass, method_name) - end - end - - # @private - # When we mock or stub a method on a class, we have to treat it a bit different, - # because normally singleton method definitions only affect the object on which - # they are defined, but on classes they affect subclasses, too. As a result, - # we need some special handling to get the original method. - module PartialClassDoubleProxyMethods - def initialize(source_space, *args) - @source_space = source_space - super(*args) - end - - # Consider this situation: - # - # class A; end - # class B < A; end - # - # allow(A).to receive(:new) - # expect(B).to receive(:new).and_call_original - # - # When getting the original definition for `B.new`, we cannot rely purely on - # using `B.method(:new)` before our redefinition is defined on `B`, because - # `B.method(:new)` will return a method that will execute the stubbed version - # of the method on `A` since singleton methods on classes are in the lookup - # hierarchy. - # - # To do it properly, we need to find the original definition of `new` from `A` - # from _before_ `A` was stubbed, and we need to rebind it to `B` so that it will - # run with the proper `self`. - # - # That's what this method (together with `original_unbound_method_handle_from_ancestor_for`) - # does. - def original_method_handle_for(message) - unbound_method = superclass_proxy && - superclass_proxy.original_unbound_method_handle_from_ancestor_for(message.to_sym) - - return super unless unbound_method - unbound_method.bind(object) - # :nocov: - rescue TypeError - if RUBY_VERSION == '1.8.7' - # In MRI 1.8.7, a singleton method on a class cannot be rebound to its subclass - if unbound_method && unbound_method.owner.ancestors.first != unbound_method.owner - # This is a singleton method; we can't do anything with it - # But we can work around this using a different implementation - double = method_double_from_ancestor_for(message) - return object.method(double.method_stasher.stashed_method_name) - end - end - raise - # :nocov: - end - - protected - - def original_unbound_method_handle_from_ancestor_for(message) - double = method_double_from_ancestor_for(message) - double && double.original_method.unbind - end - - def method_double_from_ancestor_for(message) - @method_doubles.fetch(message) do - # The fact that there is no method double for this message indicates - # that it has not been redefined by rspec-mocks. We need to continue - # looking up the ancestor chain. - return superclass_proxy && - superclass_proxy.method_double_from_ancestor_for(message) - end - end - - def superclass_proxy - return @superclass_proxy if defined?(@superclass_proxy) - - if (superclass = object.superclass) - @superclass_proxy = @source_space.superclass_proxy_for(superclass) - else - @superclass_proxy = nil - end - end - end - - # @private - class PartialClassDoubleProxy < PartialDoubleProxy - include PartialClassDoubleProxyMethods - end - - # @private - class ProxyForNil < PartialDoubleProxy - def initialize(order_group) - set_expectation_behavior - super(nil, order_group) - end - - attr_accessor :disallow_expectations - attr_accessor :warn_about_expectations - - def add_message_expectation(method_name, opts={}, &block) - warn_or_raise!(method_name) - super - end - - def add_stub(method_name, opts={}, &implementation) - warn_or_raise!(method_name) - super - end - - private - - def set_expectation_behavior - case RSpec::Mocks.configuration.allow_message_expectations_on_nil - when false - @warn_about_expectations = false - @disallow_expectations = true - when true - @warn_about_expectations = false - @disallow_expectations = false - else - @warn_about_expectations = true - @disallow_expectations = false - end - end - - def warn_or_raise!(method_name) - # This method intentionally swallows the message when - # neither disallow_expectations nor warn_about_expectations - # are set to true. - if disallow_expectations - raise_error(method_name) - elsif warn_about_expectations - warn(method_name) - end - end - - def warn(method_name) - warning_msg = @error_generator.expectation_on_nil_message(method_name) - RSpec.warning(warning_msg) - end - - def raise_error(method_name) - @error_generator.raise_expectation_on_nil_error(method_name) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb deleted file mode 100644 index f933caa..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/space.rb +++ /dev/null @@ -1,238 +0,0 @@ -RSpec::Support.require_rspec_support 'reentrant_mutex' - -module RSpec - module Mocks - # @private - # Provides a default space implementation for outside - # the scope of an example. Called "root" because it serves - # as the root of the space stack. - class RootSpace - def proxy_for(*_args) - raise_lifecycle_message - end - - def any_instance_recorder_for(*_args) - raise_lifecycle_message - end - - def any_instance_proxy_for(*_args) - raise_lifecycle_message - end - - def register_constant_mutator(_mutator) - raise_lifecycle_message - end - - def any_instance_recorders_from_ancestry_of(_object) - raise_lifecycle_message - end - - def reset_all - end - - def verify_all - end - - def registered?(_object) - false - end - - def superclass_proxy_for(*_args) - raise_lifecycle_message - end - - def new_scope - Space.new - end - - private - - def raise_lifecycle_message - raise OutsideOfExampleError, - "The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported." - end - end - - # @private - class Space - attr_reader :proxies, :any_instance_recorders, :proxy_mutex, :any_instance_mutex - - def initialize - @proxies = {} - @any_instance_recorders = {} - @constant_mutators = [] - @expectation_ordering = OrderGroup.new - @proxy_mutex = new_mutex - @any_instance_mutex = new_mutex - end - - def new_scope - NestedSpace.new(self) - end - - def verify_all - proxies.values.each { |proxy| proxy.verify } - any_instance_recorders.each_value { |recorder| recorder.verify } - end - - def reset_all - proxies.each_value { |proxy| proxy.reset } - any_instance_recorders.each_value { |recorder| recorder.stop_all_observation! } - any_instance_recorders.clear - @constant_mutators.reverse.each { |mut| mut.idempotently_reset } - end - - def register_constant_mutator(mutator) - @constant_mutators << mutator - end - - def constant_mutator_for(name) - @constant_mutators.find { |m| m.full_constant_name == name } - end - - def any_instance_recorder_for(klass, only_return_existing=false) - any_instance_mutex.synchronize do - id = klass.__id__ - any_instance_recorders.fetch(id) do - return nil if only_return_existing - any_instance_recorder_not_found_for(id, klass) - end - end - end - - def any_instance_proxy_for(klass) - AnyInstance::Proxy.new(any_instance_recorder_for(klass), proxies_of(klass)) - end - - def proxies_of(klass) - proxies.values.select { |proxy| klass === proxy.object } - end - - def proxy_for(object) - proxy_mutex.synchronize do - id = id_for(object) - proxies.fetch(id) { proxy_not_found_for(id, object) } - end - end - - def superclass_proxy_for(klass) - proxy_mutex.synchronize do - id = id_for(klass) - proxies.fetch(id) { superclass_proxy_not_found_for(id, klass) } - end - end - - alias ensure_registered proxy_for - - def registered?(object) - proxies.key?(id_for object) - end - - def any_instance_recorders_from_ancestry_of(object) - # Optimization: `any_instance` is a feature we generally - # recommend not using, so we can often early exit here - # without doing an O(N) linear search over the number of - # ancestors in the object's class hierarchy. - return [] if any_instance_recorders.empty? - - # We access the ancestors through the singleton class, to avoid calling - # `class` in case `class` has been stubbed. - (class << object; ancestors; end).map do |klass| - any_instance_recorders[klass.__id__] - end.compact - end - - private - - def new_mutex - Support::ReentrantMutex.new - end - - def proxy_not_found_for(id, object) - proxies[id] = case object - when NilClass then ProxyForNil.new(@expectation_ordering) - when TestDouble then object.__build_mock_proxy_unless_expired(@expectation_ordering) - when Class - class_proxy_with_callback_verification_strategy(object, CallbackInvocationStrategy.new) - else - if RSpec::Mocks.configuration.verify_partial_doubles? - VerifyingPartialDoubleProxy.new(object, @expectation_ordering) - else - PartialDoubleProxy.new(object, @expectation_ordering) - end - end - end - - def superclass_proxy_not_found_for(id, object) - raise "superclass_proxy_not_found_for called with something that is not a class" unless Class === object - proxies[id] = class_proxy_with_callback_verification_strategy(object, NoCallbackInvocationStrategy.new) - end - - def class_proxy_with_callback_verification_strategy(object, strategy) - if RSpec::Mocks.configuration.verify_partial_doubles? - VerifyingPartialClassDoubleProxy.new( - self, - object, - @expectation_ordering, - strategy - ) - else - PartialClassDoubleProxy.new(self, object, @expectation_ordering) - end - end - - def any_instance_recorder_not_found_for(id, klass) - any_instance_recorders[id] = AnyInstance::Recorder.new(klass) - end - - if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2 - require 'securerandom' - - def id_for(object) - id = object.__id__ - - return id if object.equal?(::ObjectSpace._id2ref(id)) - # this suggests that object.__id__ is proxying through to some wrapped object - - object.instance_exec do - @__id_for_rspec_mocks_space ||= ::SecureRandom.uuid - end - end - else - def id_for(object) - object.__id__ - end - end - end - - # @private - class NestedSpace < Space - def initialize(parent) - @parent = parent - super() - end - - def proxies_of(klass) - super + @parent.proxies_of(klass) - end - - def constant_mutator_for(name) - super || @parent.constant_mutator_for(name) - end - - def registered?(object) - super || @parent.registered?(object) - end - - private - - def proxy_not_found_for(id, object) - @parent.proxies[id] || super - end - - def any_instance_recorder_not_found_for(id, klass) - @parent.any_instance_recorders[id] || super - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb deleted file mode 100644 index 74317b0..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/standalone.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'rspec/mocks' -extend RSpec::Mocks::ExampleMethods -RSpec::Mocks.setup diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb deleted file mode 100644 index 2caabd1..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/syntax.rb +++ /dev/null @@ -1,325 +0,0 @@ -module RSpec - module Mocks - # @api private - # Provides methods for enabling and disabling the available syntaxes - # provided by rspec-mocks. - module Syntax - # @private - def self.warn_about_should! - @warn_about_should = true - end - - # @private - def self.warn_unless_should_configured(method_name , replacement="the new `:expect` syntax or explicitly enable `:should`") - if @warn_about_should - RSpec.deprecate( - "Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", - :replacement => replacement - ) - - @warn_about_should = false - end - end - - # @api private - # Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). - def self.enable_should(syntax_host=default_should_syntax_host) - @warn_about_should = false if syntax_host == default_should_syntax_host - return if should_enabled?(syntax_host) - - syntax_host.class_exec do - def should_receive(message, opts={}, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.expect_message(self, message, opts, &block) - end - - def should_not_receive(message, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.expect_message(self, message, {}, &block).never - end - - def stub(message_or_hash, opts={}, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - if ::Hash === message_or_hash - message_or_hash.each { |message, value| stub(message).and_return value } - else - ::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block) - end - end - - def unstub(message) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to receive(...).and_call_original` or explicitly enable `:should`") - ::RSpec::Mocks.space.proxy_for(self).remove_stub(message) - end - - def stub_chain(*chain, &blk) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk) - end - - def as_null_object - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - @_null_object = true - ::RSpec::Mocks.space.proxy_for(self).as_null_object - end - - def null_object? - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - defined?(@_null_object) - end - - def received_message?(message, *args, &block) - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.space.proxy_for(self).received_message?(message, *args, &block) - end - - unless Class.respond_to? :any_instance - Class.class_exec do - def any_instance - ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) - ::RSpec::Mocks.space.any_instance_proxy_for(self) - end - end - end - end - end - - # @api private - # Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). - def self.disable_should(syntax_host=default_should_syntax_host) - return unless should_enabled?(syntax_host) - - syntax_host.class_exec do - undef should_receive - undef should_not_receive - undef stub - undef unstub - undef stub_chain - undef as_null_object - undef null_object? - undef received_message? - end - - Class.class_exec do - undef any_instance - end - end - - # @api private - # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). - def self.enable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) - return if expect_enabled?(syntax_host) - - syntax_host.class_exec do - def receive(method_name, &block) - Matchers::Receive.new(method_name, block) - end - - def receive_messages(message_return_value_hash, &_block) - matcher = Matchers::ReceiveMessages.new(message_return_value_hash) - matcher.warn_about_block if block_given? - matcher - end - - def receive_message_chain(*messages, &block) - Matchers::ReceiveMessageChain.new(messages, &block) - end - - def allow(target) - AllowanceTarget.new(target) - end - - def expect_any_instance_of(klass) - AnyInstanceExpectationTarget.new(klass) - end - - def allow_any_instance_of(klass) - AnyInstanceAllowanceTarget.new(klass) - end - end - - RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do - def expect(target) - ExpectationTarget.new(target) - end - end - end - - # @api private - # Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). - def self.disable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) - return unless expect_enabled?(syntax_host) - - syntax_host.class_exec do - undef receive - undef receive_messages - undef receive_message_chain - undef allow - undef expect_any_instance_of - undef allow_any_instance_of - end - - RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do - undef expect - end - end - - # @api private - # Indicates whether or not the should syntax is enabled. - def self.should_enabled?(syntax_host=default_should_syntax_host) - syntax_host.method_defined?(:should_receive) - end - - # @api private - # Indicates whether or not the expect syntax is enabled. - def self.expect_enabled?(syntax_host=::RSpec::Mocks::ExampleMethods) - syntax_host.method_defined?(:allow) - end - - # @api private - # Determines where the methods like `should_receive`, and `stub` are added. - def self.default_should_syntax_host - # JRuby 1.7.4 introduces a regression whereby `defined?(::BasicObject) => nil` - # yet `BasicObject` still exists and patching onto ::Object breaks things - # e.g. SimpleDelegator expectations won't work - # - # See: https://github.com/jruby/jruby/issues/814 - if defined?(JRUBY_VERSION) && JRUBY_VERSION == '1.7.4' && RUBY_VERSION.to_f > 1.8 - return ::BasicObject - end - - # On 1.8.7, Object.ancestors.last == Kernel but - # things blow up if we include `RSpec::Mocks::Methods` - # into Kernel...not sure why. - return Object unless defined?(::BasicObject) - - # MacRuby has BasicObject but it's not the root class. - return Object unless Object.ancestors.last == ::BasicObject - - ::BasicObject - end - end - end -end - -if defined?(BasicObject) - # The legacy `:should` syntax adds the following methods directly to - # `BasicObject` so that they are available off of any object. Note, however, - # that this syntax does not always play nice with delegate/proxy objects. - # We recommend you use the non-monkeypatching `:expect` syntax instead. - # @see Class - class BasicObject - # @method should_receive - # Sets an expectation that this object should receive a message before - # the end of the example. - # - # @example - # logger = double('logger') - # thing_that_logs = ThingThatLogs.new(logger) - # logger.should_receive(:log) - # thing_that_logs.do_something_that_logs_a_message - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#expect - - # @method should_not_receive - # Sets and expectation that this object should _not_ receive a message - # during this example. - # @see RSpec::Mocks::ExampleMethods#expect - - # @method stub - # Tells the object to respond to the message with the specified value. - # - # @example - # counter.stub(:count).and_return(37) - # counter.stub(:count => 37) - # counter.stub(:count) { 37 } - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#allow - - # @method unstub - # Removes a stub. On a double, the object will no longer respond to - # `message`. On a real object, the original method (if it exists) is - # restored. - # - # This is rarely used, but can be useful when a stub is set up during a - # shared `before` hook for the common case, but you want to replace it - # for a special case. - # - # @note This is only available when you have enabled the `should` syntax. - - # @method stub_chain - # @overload stub_chain(method1, method2) - # @overload stub_chain("method1.method2") - # @overload stub_chain(method1, method_to_value_hash) - # - # Stubs a chain of methods. - # - # ## Warning: - # - # Chains can be arbitrarily long, which makes it quite painless to - # violate the Law of Demeter in violent ways, so you should consider any - # use of `stub_chain` a code smell. Even though not all code smells - # indicate real problems (think fluent interfaces), `stub_chain` still - # results in brittle examples. For example, if you write - # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the - # implementation calls `foo.baz.bar`, the stub will not work. - # - # @example - # double.stub_chain("foo.bar") { :baz } - # double.stub_chain(:foo, :bar => :baz) - # double.stub_chain(:foo, :bar) { :baz } - # - # # Given any of ^^ these three forms ^^: - # double.foo.bar # => :baz - # - # # Common use in Rails/ActiveRecord: - # Article.stub_chain("recent.published") { [Article.new] } - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#receive_message_chain - - # @method as_null_object - # Tells the object to respond to all messages. If specific stub values - # are declared, they'll work as expected. If not, the receiver is - # returned. - # - # @note This is only available when you have enabled the `should` syntax. - - # @method null_object? - # Returns true if this object has received `as_null_object` - # - # @note This is only available when you have enabled the `should` syntax. - end -end - -# The legacy `:should` syntax adds the `any_instance` to `Class`. -# We generally recommend you use the newer `:expect` syntax instead, -# which allows you to stub any instance of a class using -# `allow_any_instance_of(klass)` or mock any instance using -# `expect_any_instance_of(klass)`. -# @see BasicObject -class Class - # @method any_instance - # Used to set stubs and message expectations on any instance of a given - # class. Returns a [Recorder](Recorder), which records messages like - # `stub` and `should_receive` for later playback on instances of the - # class. - # - # @example - # Car.any_instance.should_receive(:go) - # race = Race.new - # race.cars << Car.new - # race.go # assuming this delegates to all of its cars - # # this example would pass - # - # Account.any_instance.stub(:balance) { Money.new(:USD, 25) } - # Account.new.balance # => Money.new(:USD, 25)) - # - # @return [Recorder] - # - # @note This is only available when you have enabled the `should` syntax. - # @see RSpec::Mocks::ExampleMethods#expect_any_instance_of - # @see RSpec::Mocks::ExampleMethods#allow_any_instance_of -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb deleted file mode 100644 index 26f7287..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/targets.rb +++ /dev/null @@ -1,124 +0,0 @@ -module RSpec - module Mocks - # @private - module TargetDelegationClassMethods - def delegate_to(matcher_method) - define_method(:to) do |matcher, &block| - unless matcher_allowed?(matcher) - raise_unsupported_matcher(:to, matcher) - end - define_matcher(matcher, matcher_method, &block) - end - end - - def delegate_not_to(matcher_method, options={}) - method_name = options.fetch(:from) - define_method(method_name) do |matcher, &block| - case matcher - when Matchers::Receive, Matchers::HaveReceived - define_matcher(matcher, matcher_method, &block) - when Matchers::ReceiveMessages, Matchers::ReceiveMessageChain - raise_negation_unsupported(method_name, matcher) - else - raise_unsupported_matcher(method_name, matcher) - end - end - end - - def disallow_negation(method_name) - define_method(method_name) do |matcher, *_args| - raise_negation_unsupported(method_name, matcher) - end - end - end - - # @private - module TargetDelegationInstanceMethods - attr_reader :target - - private - - def matcher_allowed?(matcher) - Matchers::Matcher === matcher - end - - def define_matcher(matcher, name, &block) - matcher.__send__(name, target, &block) - end - - def raise_unsupported_matcher(method_name, matcher) - raise UnsupportedMatcherError, - "only the `receive`, `have_received` and `receive_messages` matchers are supported " \ - "with `#{expression}(...).#{method_name}`, but you have provided: #{matcher}" - end - - def raise_negation_unsupported(method_name, matcher) - raise NegationUnsupportedError, - "`#{expression}(...).#{method_name} #{matcher.matcher_name}` is not supported since it " \ - "doesn't really make sense. What would it even mean?" - end - end - - # @private - class TargetBase - def initialize(target) - @target = target - end - - extend TargetDelegationClassMethods - include TargetDelegationInstanceMethods - end - - # @private - module ExpectationTargetMethods - extend TargetDelegationClassMethods - include TargetDelegationInstanceMethods - - delegate_to :setup_expectation - delegate_not_to :setup_negative_expectation, :from => :not_to - delegate_not_to :setup_negative_expectation, :from => :to_not - - def expression - :expect - end - end - - # @private - class ExpectationTarget < TargetBase - include ExpectationTargetMethods - end - - # @private - class AllowanceTarget < TargetBase - def expression - :allow - end - - delegate_to :setup_allowance - disallow_negation :not_to - disallow_negation :to_not - end - - # @private - class AnyInstanceAllowanceTarget < TargetBase - def expression - :allow_any_instance_of - end - - delegate_to :setup_any_instance_allowance - disallow_negation :not_to - disallow_negation :to_not - end - - # @private - class AnyInstanceExpectationTarget < TargetBase - def expression - :expect_any_instance_of - end - - delegate_to :setup_any_instance_expectation - delegate_not_to :setup_any_instance_negative_expectation, :from => :not_to - delegate_not_to :setup_any_instance_negative_expectation, :from => :to_not - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb deleted file mode 100644 index c208311..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/test_double.rb +++ /dev/null @@ -1,174 +0,0 @@ -module RSpec - module Mocks - # Implements the methods needed for a pure test double. RSpec::Mocks::Double - # includes this module, and it is provided for cases where you want a - # pure test double without subclassing RSpec::Mocks::Double. - module TestDouble - # Creates a new test double with a `name` (that will be used in error - # messages only) - def initialize(name=nil, stubs={}) - @__expired = false - if Hash === name && stubs.empty? - stubs = name - @name = nil - else - @name = name - end - assign_stubs(stubs) - end - - # Tells the object to respond to all messages. If specific stub values - # are declared, they'll work as expected. If not, the receiver is - # returned. - def as_null_object - __mock_proxy.as_null_object - end - - # Returns true if this object has received `as_null_object` - def null_object? - __mock_proxy.null_object? - end - - # This allows for comparing the mock to other objects that proxy such as - # ActiveRecords belongs_to proxy objects. By making the other object run - # the comparison, we're sure the call gets delegated to the proxy - # target. - def ==(other) - other == __mock_proxy - end - - # @private - def inspect - TestDoubleFormatter.format(self) - end - - # @private - def to_s - inspect.tr('<', '[').tr('>', ']') - end - - # @private - def respond_to?(message, incl_private=false) - return true if __mock_proxy.null_object? - - super - end - - # @private - def __build_mock_proxy_unless_expired(order_group) - __raise_expired_error || __build_mock_proxy(order_group) - end - - # @private - def __disallow_further_usage! - @__expired = true - end - - # Override for default freeze implementation to prevent freezing of test - # doubles. - def freeze - RSpec.warn_with("WARNING: you attempted to freeze a test double. This is explicitly a no-op as freezing doubles can lead to undesired behaviour when resetting tests.") - self - end - - private - - def method_missing(message, *args, &block) - proxy = __mock_proxy - proxy.record_message_received(message, *args, &block) - - if proxy.null_object? - case message - when :to_int then return 0 - when :to_a, :to_ary then return nil - when :to_h, :to_hash then return {} - when :to_str then return to_s - else return self - end - end - - # Defined private and protected methods will still trigger `method_missing` - # when called publicly. We want ruby's method visibility error to get raised, - # so we simply delegate to `super` in that case. - # ...well, we would delegate to `super`, but there's a JRuby - # bug, so we raise our own visibility error instead: - # https://github.com/jruby/jruby/issues/1398 - visibility = proxy.visibility_for(message) - if visibility == :private || visibility == :protected - ErrorGenerator.new(self).raise_non_public_error( - message, visibility - ) - end - - # Required wrapping doubles in an Array on Ruby 1.9.2 - raise NoMethodError if [:to_a, :to_ary].include? message - proxy.raise_unexpected_message_error(message, args) - end - - def assign_stubs(stubs) - stubs.each_pair do |message, response| - __mock_proxy.add_simple_stub(message, response) - end - end - - def __mock_proxy - ::RSpec::Mocks.space.proxy_for(self) - end - - def __build_mock_proxy(order_group) - TestDoubleProxy.new(self, order_group) - end - - def __raise_expired_error - return false unless @__expired - ErrorGenerator.new(self).raise_expired_test_double_error - end - - def initialize_copy(other) - as_null_object if other.null_object? - super - end - end - - # A generic test double object. `double`, `instance_double` and friends - # return an instance of this. - class Double - include TestDouble - end - - # @private - module TestDoubleFormatter - def self.format(dbl, unwrap=false) - format = "#{type_desc(dbl)}#{verified_module_desc(dbl)} #{name_desc(dbl)}" - return format if unwrap - "#<#{format}>" - end - - class << self - private - - def type_desc(dbl) - case dbl - when InstanceVerifyingDouble then "InstanceDouble" - when ClassVerifyingDouble then "ClassDouble" - when ObjectVerifyingDouble then "ObjectDouble" - else "Double" - end - end - - # @private - IVAR_GET = Object.instance_method(:instance_variable_get) - - def verified_module_desc(dbl) - return nil unless VerifyingDouble === dbl - "(#{IVAR_GET.bind(dbl).call(:@doubled_module).description})" - end - - def name_desc(dbl) - return "(anonymous)" unless (name = IVAR_GET.bind(dbl).call(:@name)) - name.inspect - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb deleted file mode 100644 index 3402967..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_double.rb +++ /dev/null @@ -1,125 +0,0 @@ -RSpec::Support.require_rspec_mocks 'verifying_proxy' - -module RSpec - module Mocks - # @private - module VerifyingDouble - def respond_to?(message, include_private=false) - return super unless null_object? - - method_ref = __mock_proxy.method_reference[message] - - case method_ref.visibility - when :public then true - when :private then include_private - when :protected then include_private || RUBY_VERSION.to_f < 2.0 - else !method_ref.unimplemented? - end - end - - def method_missing(message, *args, &block) - # Null object conditional is an optimization. If not a null object, - # validity of method expectations will have been checked at definition - # time. - if null_object? - if @__sending_message == message - __mock_proxy.ensure_implemented(message) - else - __mock_proxy.ensure_publicly_implemented(message, self) - end - - __mock_proxy.validate_arguments!(message, args) - end - - super - end - - # Redefining `__send__` causes ruby to issue a warning. - old, $VERBOSE = $VERBOSE, nil - # rubocop:disable Naming/MethodName - def __send__(name, *args, &block) - @__sending_message = name - super - ensure - @__sending_message = nil - end - # rubocop:enable Naming/MethodName - ruby2_keywords :__send__ if respond_to?(:ruby2_keywords, true) - $VERBOSE = old - - def send(name, *args, &block) - __send__(name, *args, &block) - end - ruby2_keywords :send if respond_to?(:ruby2_keywords, true) - - def initialize(doubled_module, *args) - @doubled_module = doubled_module - - possible_name = args.first - name = if String === possible_name || Symbol === possible_name - args.shift - end - - super(name, *args) - @__sending_message = nil - end - end - - # A mock providing a custom proxy that can verify the validity of any - # method stubs or expectations against the public instance methods of the - # given class. - # - # @private - class InstanceVerifyingDouble - include TestDouble - include VerifyingDouble - - def __build_mock_proxy(order_group) - VerifyingProxy.new(self, order_group, - @doubled_module, - InstanceMethodReference - ) - end - end - - # An awkward module necessary because we cannot otherwise have - # ClassVerifyingDouble inherit from Module and still share these methods. - # - # @private - module ObjectVerifyingDoubleMethods - include TestDouble - include VerifyingDouble - - def as_stubbed_const(options={}) - ConstantMutator.stub(@doubled_module.const_to_replace, self, options) - self - end - - private - - def __build_mock_proxy(order_group) - VerifyingProxy.new(self, order_group, - @doubled_module, - ObjectMethodReference - ) - end - end - - # Similar to an InstanceVerifyingDouble, except that it verifies against - # public methods of the given object. - # - # @private - class ObjectVerifyingDouble - include ObjectVerifyingDoubleMethods - end - - # Effectively the same as an ObjectVerifyingDouble (since a class is a type - # of object), except with Module in the inheritance chain so that - # transferring nested constants to work. - # - # @private - class ClassVerifyingDouble < Module - include ObjectVerifyingDoubleMethods - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb deleted file mode 100644 index d6dcb57..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_message_expectation.rb +++ /dev/null @@ -1,55 +0,0 @@ -RSpec::Support.require_rspec_support 'method_signature_verifier' - -module RSpec - module Mocks - # A message expectation that knows about the real implementation of the - # message being expected, so that it can verify that any expectations - # have the valid arguments. - # @api private - class VerifyingMessageExpectation < MessageExpectation - # A level of indirection is used here rather than just passing in the - # method itself, since method look up is expensive and we only want to - # do it if actually needed. - # - # Conceptually the method reference makes more sense as a constructor - # argument since it should be immutable, but it is significantly more - # straight forward to build the object in pieces so for now it stays as - # an accessor. - attr_accessor :method_reference - - def initialize(*args) - super - end - - # @private - def with(*args, &block) - super(*args, &block).tap do - validate_expected_arguments! do |signature| - example_call_site_args = [:an_arg] * signature.min_non_kw_args - example_call_site_args << :kw_args_hash if signature.required_kw_args.any? - @argument_list_matcher.resolve_expected_args_based_on(example_call_site_args) - end - end - end - ruby2_keywords(:with) if respond_to?(:ruby2_keywords, true) - - private - - def validate_expected_arguments! - return if method_reference.nil? - - method_reference.with_signature do |signature| - args = yield signature - verifier = Support::LooseSignatureVerifier.new(signature, args) - - unless verifier.valid? - # Fail fast is required, otherwise the message expectation will fail - # as well ("expected method not called") and clobber this one. - @failed_fast = true - @error_generator.raise_invalid_arguments_error(verifier) - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb deleted file mode 100644 index 6147b81..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/verifying_proxy.rb +++ /dev/null @@ -1,221 +0,0 @@ -RSpec::Support.require_rspec_mocks 'verifying_message_expectation' -RSpec::Support.require_rspec_mocks 'method_reference' - -module RSpec - module Mocks - # @private - class CallbackInvocationStrategy - def call(doubled_module) - RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| - block.call doubled_module - end - end - end - - # @private - class NoCallbackInvocationStrategy - def call(_doubled_module) - end - end - - # @private - module VerifyingProxyMethods - def add_stub(method_name, opts={}, &implementation) - ensure_implemented(method_name) - super - end - - def add_simple_stub(method_name, *args) - ensure_implemented(method_name) - super - end - - def add_message_expectation(method_name, opts={}, &block) - ensure_implemented(method_name) - super - end - - def ensure_implemented(method_name) - return unless method_reference[method_name].unimplemented? - - @error_generator.raise_unimplemented_error( - @doubled_module, - method_name, - @object - ) - end - - def ensure_publicly_implemented(method_name, _object) - ensure_implemented(method_name) - visibility = method_reference[method_name].visibility - - return if visibility == :public - @error_generator.raise_non_public_error(method_name, visibility) - end - end - - # A verifying proxy mostly acts like a normal proxy, except that it - # contains extra logic to try and determine the validity of any expectation - # set on it. This includes whether or not methods have been defined and the - # validity of arguments on method calls. - # - # In all other ways this behaves like a normal proxy. It only adds the - # verification behaviour to specific methods then delegates to the parent - # implementation. - # - # These checks are only activated if the doubled class has already been - # loaded, otherwise they are disabled. This allows for testing in - # isolation. - # - # @private - class VerifyingProxy < TestDoubleProxy - include VerifyingProxyMethods - - def initialize(object, order_group, doubled_module, method_reference_class) - super(object, order_group) - @object = object - @doubled_module = doubled_module - @method_reference_class = method_reference_class - - # A custom method double is required to pass through a way to lookup - # methods to determine their parameters. This is only relevant if the doubled - # class is loaded. - @method_doubles = Hash.new do |h, k| - h[k] = VerifyingMethodDouble.new(@object, k, self, method_reference[k]) - end - end - - def method_reference - @method_reference ||= Hash.new do |h, k| - h[k] = @method_reference_class.for(@doubled_module, k) - end - end - - def visibility_for(method_name) - method_reference[method_name].visibility - end - - def validate_arguments!(method_name, args) - @method_doubles[method_name].validate_arguments!(args) - end - end - - # @private - DEFAULT_CALLBACK_INVOCATION_STRATEGY = CallbackInvocationStrategy.new - - # @private - class VerifyingPartialDoubleProxy < PartialDoubleProxy - include VerifyingProxyMethods - - def initialize(object, expectation_ordering, optional_callback_invocation_strategy=DEFAULT_CALLBACK_INVOCATION_STRATEGY) - super(object, expectation_ordering) - @doubled_module = DirectObjectReference.new(object) - - # A custom method double is required to pass through a way to lookup - # methods to determine their parameters. - @method_doubles = Hash.new do |h, k| - h[k] = VerifyingExistingMethodDouble.for(object, k, self) - end - - optional_callback_invocation_strategy.call(@doubled_module) - end - - def ensure_implemented(_method_name) - return if Mocks.configuration.temporarily_suppress_partial_double_verification - super - end - - def method_reference - @method_doubles - end - end - - # @private - class VerifyingPartialClassDoubleProxy < VerifyingPartialDoubleProxy - include PartialClassDoubleProxyMethods - end - - # @private - class VerifyingMethodDouble < MethodDouble - def initialize(object, method_name, proxy, method_reference) - super(object, method_name, proxy) - @method_reference = method_reference - end - - def message_expectation_class - VerifyingMessageExpectation - end - - def add_expectation(*args, &block) - # explicit params necessary for 1.8.7 see #626 - super(*args, &block).tap { |x| x.method_reference = @method_reference } - end - - def add_stub(*args, &block) - # explicit params necessary for 1.8.7 see #626 - super(*args, &block).tap { |x| x.method_reference = @method_reference } - end - - def proxy_method_invoked(obj, *args, &block) - validate_arguments!(args) - super - end - ruby2_keywords :proxy_method_invoked if respond_to?(:ruby2_keywords, true) - - def validate_arguments!(actual_args) - @method_reference.with_signature do |signature| - verifier = Support::StrictSignatureVerifier.new(signature, actual_args) - raise ArgumentError, verifier.error_message unless verifier.valid? - end - end - end - - # A VerifyingMethodDouble fetches the method to verify against from the - # original object, using a MethodReference. This works for pure doubles, - # but when the original object is itself the one being modified we need to - # collapse the reference and the method double into a single object so that - # we can access the original pristine method definition. - # - # @private - class VerifyingExistingMethodDouble < VerifyingMethodDouble - def initialize(object, method_name, proxy) - super(object, method_name, proxy, self) - - @valid_method = object.respond_to?(method_name, true) - - # Trigger an eager find of the original method since if we find it any - # later we end up getting a stubbed method with incorrect arity. - save_original_implementation_callable! - end - - def with_signature - yield Support::MethodSignature.new(original_implementation_callable) - end - - def unimplemented? - !@valid_method - end - - def self.for(object, method_name, proxy) - if ClassNewMethodReference.applies_to?(method_name) { object } - VerifyingExistingClassNewMethodDouble - elsif Mocks.configuration.temporarily_suppress_partial_double_verification - MethodDouble - else - self - end.new(object, method_name, proxy) - end - end - - # Used in place of a `VerifyingExistingMethodDouble` for the specific case - # of mocking or stubbing a `new` method on a class. In this case, we substitute - # the method signature from `#initialize` since new's signature is just `*args`. - # - # @private - class VerifyingExistingClassNewMethodDouble < VerifyingExistingMethodDouble - def with_signature - yield Support::MethodSignature.new(object.instance_method(:initialize)) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb deleted file mode 100644 index d8bc5a9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-mocks-3.13.7/lib/rspec/mocks/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module RSpec - module Mocks - # Version information for RSpec mocks. - module Version - # Version of RSpec mocks currently in use in SemVer format. - STRING = '3.13.7' - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md deleted file mode 100644 index 80cc104..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/Changelog.md +++ /dev/null @@ -1,437 +0,0 @@ -### Development -[Full Changelog](https://github.com/rspec/rspec/compare/rspec-support-v3.13.6...3-13-maintenance) - -### 3.13.6 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.5...rspec-support-v3.13.6) - -Bug Fixes: - -* Change `RSpec::Support::HunkGenerator` to autoload rather than manual require, avoids - a load order issue. (Jon Rowe, rspec/rspec#249) - -### 3.13.5 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.4...rspec-support-v3.13.5) - -Bug Fixes: - -* Fix regression in `RSpec::Support::MethodSignature` where positional argument arity confused - a check for keyword arguments, meaning a hash would be wrongly detected as keyword arguments - when it should have been a positional argument. (Malcolm O'Hare, rspec/rspec#121) - -### 3.13.4 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.3...rspec-support-v3.13.4) - -Bug Fixes: - -* Fix homepage link in gemspec. (Jon Rowe) - -### 3.13.3 / 2025-04-30 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.2...rspec-support-v3.13.3) - -Bug Fixes: - -* Support for changes in diff-lcs and Ruby 3.4 in spec helpers. (Jon Rowe, #164 etc) - -### 3.13.2 / 2024-12-02 -[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.1...rspec-support-v3.13.2) - -No changes. Released during the monorepo migration to test release processes, but accidentally -contained no changes. - -### 3.13.1 / 2024-02-23 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.13.0...v3.13.1) - -Bug Fixes: - -* Exclude ruby internal require warnings from `RSpec::Support::CallerFilter#first_non_rspec_line`. - (Jon Rowe, rspec/rspec-support#593) - -### 3.13.0 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.2...v3.13.0) - -Enchancements - -* Add `RubyFeatures#supports_syntax_suggest?`. (Jon Rowe, rspec/rspec-support#571) - -Bug Fixes: - -* Allow string keys for keyword arguments during verification of method - signatures, (but only on Ruby 3+). (@malcolmohare, rspec/rspec-support#591) - -### 3.12.2 / 2024-02-04 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.1...v3.12.2) - -Bug Fixes: - -* Properly surface errors from `in_sub_process`. (Jon Rowe, rspec/rspec-support#575) -* Add magic comment for freezing string literals. (Josh Nichols, rspec/rspec-support#586) - -### 3.12.1 / 2023-06-26 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.0...v3.12.1) - -Bug Fixes: - -* Fix `RSpec::Support.thread_local_data` to be Thread local but not Fiber local. - (Jon Rowe, rspec/rspec-support#581) - -### 3.12.0 / 2022-10-26 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.11.1...v3.12.0) -Enhancements: - -* Add `RSpec::Support::RubyFeatures.distincts_kw_args_from_positional_hash?` - (Jean byroot Boussier, rspec/rspec-support#535) - -### 3.11.1 / 2022-09-12 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.11.0...v3.11.1) - -Bug Fixes: - -* Fix ripper detection on TruffleRuby. (Brandon Fish, rspec/rspec-support#541) - -### 3.11.0 / 2022-02-09 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.3...v3.11.0) - -No changes. Released to support other RSpec releases. - -### 3.10.3 / 2021-11-03 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.2...v3.10.3) - -Bug Fixes: - -* Use `Mutex#owned?` to allow `RSpec::Support::ReentrantMutex` to work in - nested Fibers on Ruby 3.0 and later. (Benoit Daloze, rspec/rspec-support#503, rspec/rspec-support#504) -* Support `end`-less methods in `RSpec::Support::Source::Token` - so that RSpec won't hang when an `end`-less method raises an error. (Yuji Nakayama, rspec/rspec-support#505) - -### 3.10.2 / 2021-01-28 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.1...v3.10.2) - -Bug Fixes: - -* Fix issue with `RSpec::Support.define_optimized_require_for_rspec` on JRuby - 9.1.17.0 (Jon Rowe, rspec/rspec-support#492) - -### 3.10.1 / 2020-12-27 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.0...v3.10.1) - -Bug Fixes: - -* Fix deprecation expectations to fail correctly when - asserting on messages. (Phil Pirozhkov, rspec/rspec-support#453) - -### 3.10.0 / 2020-10-30 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.4...v3.10.0) - -No changes. Released to support other RSpec releases. - -### 3.9.4 / 2020-10-23 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.3...v3.9.4) - -Bug Fixes: - -* Flag ripper as supported on Truffle Ruby. (Brandon Fish, rspec/rspec-support#427) -* Prevent stubbing `File.read` from breaking source extraction. - (Jon Rowe, rspec/rspec-support#431) - -### 3.9.3 / 2020-05-02 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.2...v3.9.3) - -Bug Fixes: - -* Mark ripper as unsupported on Truffle Ruby. (Brandon Fish, rspec/rspec-support#395) -* Mark ripper as unsupported on JRuby 9.2.0.0. (Brian Hawley, rspec/rspec-support#400) -* Capture `Mutex.new` for our `RSpec::Support:Mutex` in order to - allow stubbing `Mutex.new`. (Jon Rowe, rspec/rspec-support#411) - -### 3.9.2 / 2019-12-30 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.1...v3.9.2) - -Bug Fixes: - -* Remove unneeded eval. (Matijs van Zuijlen, rspec/rspec-support#394) - -### 3.9.1 / 2019-12-28 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.0...v3.9.1) - -Bug Fixes: - -* Remove warning caused by keyword arguments on Ruby 2.7.0. - (Jon Rowe, rspec/rspec-support#392) - -### 3.9.0 / 2019-10-07 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.3...v3.9.0) - -*NO CHANGES* - -Version 3.9.0 was released to allow other RSpec gems to release 3.9.0. - -### 3.8.3 / 2019-10-02 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.2...v3.8.3) - -Bug Fixes: - -* Escape \r when outputting strings inside arrays. - (Tomita Masahiro, Jon Rowe, rspec/rspec-support#378) -* Ensure that optional hash arguments are recognised correctly vs keyword - arguments. (Evgeni Dzhelyov, rspec/rspec-support#366) - -### 3.8.2 / 2019-06-10 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.1...v3.8.2) - -Bug Fixes: - -* Ensure that an empty hash is recognised as empty keyword arguments when - applicable. (Thomas Walpole, rspec/rspec-support#375) -* Ensure that diffing truthy values produce diffs consistently. - (Lucas Nestor, rspec/rspec-support#377) - -### 3.8.1 / 2019-03-03 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.0...v3.8.1) - -Bug Fixes: - -* Ensure that inspecting a `SimpleDelegator` based object works regardless of - visibility of the `__getobj__` method. (Jon Rowe, rspec/rspec-support#369) - -### 3.8.0 / 2018-08-04 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.7.1...v3.8.0) - -Bug Fixes: - -* Order hash keys before diffing to improve diff accuracy when using mocked calls. - (James Crisp, rspec/rspec-support#334) - -### 3.7.1 / 2018-01-29 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.7.0...v3.7.1) - -Bug Fixes: - -* Fix source extraction logic so that it does not trigger a `SystemStackError` - when processing deeply nested example groups. (Craig Bass, rspec/rspec-support#343) - -### 3.7.0 / 2017-10-17 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0...v3.7.0) - -Enhancements: - -* Improve compatibility with `--enable-frozen-string-literal` option - on Ruby 2.3+. (Pat Allan, rspec/rspec-support#320) -* Add `Support.class_of` for extracting class of any object. - (Yuji Nakayama, rspec/rspec-support#325) - -Bug Fixes: - -* Fix recursive const support to not blow up when given buggy classes - that raise odd errors from `#to_str`. (Myron Marston, rspec/rspec-support#317) - -### 3.6.0 / 2017-05-04 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta2...3.6.0) - -Enhancements: - -* Import `Source` classes from rspec-core. (Yuji Nakayama, rspec/rspec-support#315) - -### 3.6.0.beta2 / 2016-12-12 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta1...v3.6.0.beta2) - -No user-facing changes. - -### 3.6.0.beta1 / 2016-10-09 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0...v3.6.0.beta1) - -Bug Fixes: - -* Prevent truncated formatted object output from mangling console codes. (rspec/rspec-support#294, Anson Kelly) - -### 3.5.0 / 2016-07-01 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta4...v3.5.0) - -**No user facing changes since beta4** - -### 3.5.0.beta4 / 2016-06-05 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta3...v3.5.0.beta4) - -Enhancements: -* Improve `MethodSignature` to better support keyword arguments. (rspec/rspec-support#250, Rob Smith). - -### 3.5.0.beta3 / 2016-04-02 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta2...v3.5.0.beta3) - -Bug Fixes: - -* Fix `EncodedString` to properly handle the behavior of `String#split` - on JRuby when the string contains invalid bytes. (Jon Rowe, rspec/rspec-support#268) -* Fix `ObjectFormatter` so that formatting objects that don't respond to - `#inspect` (such as `BasicObject`) does not cause `NoMethodError`. - (Yuji Nakayama, rspec/rspec-support#269) -* Fix `ObjectFormatter` so that formatting recursive array or hash does not - cause `SystemStackError`. (Yuji Nakayama, rspec/rspec-support#270, rspec/rspec-support#272) - -### 3.5.0.beta2 / 2016-03-10 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta1...v3.5.0.beta2) - -No user-facing changes. - -### 3.5.0.beta1 / 2016-02-06 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.4.1...v3.5.0.beta1) - -Enhancements: - -* Improve formatting of objects by allowing truncation to a pre-configured length. - (Liam M, rspec/rspec-support#256) - -### 3.4.1 / 2015-11-20 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.4.0...v3.4.1) - -Bug Fixes: - -* Fix `RSpec::Support::RubyFeature.ripper_supported?` so it returns - `false` on Rubinius since the Rubinius team has no plans to support - it. This prevents rspec-core from trying to load and use ripper to - extract failure snippets. (Aaron Stone, rspec/rspec-support#251) - -Changes: - -* Remove `VersionChecker` in favor of `ComparableVersion`. (Yuji Nakayama, rspec/rspec-support#266) - -### 3.4.0 / 2015-11-11 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.3.0...v3.4.0) - -Enhancements: - -* Improve formatting of `Delegator` based objects (e.g. `SimpleDelegator`) in - failure messages and diffs. (Andrew Horner, rspec/rspec-support#215) -* Add `ComparableVersion`. (Yuji Nakayama, rspec/rspec-support#245) -* Add `Ripper` support detection. (Yuji Nakayama, rspec/rspec-support#245) - -Bug Fixes: - -* Work around bug in JRuby that reports that `attr_writer` methods - have no parameters, causing RSpec's verifying doubles to wrongly - fail when mocking or stubbing a writer method on JRuby. (Myron Marston, rspec/rspec-support#225) - -### 3.3.0 / 2015-06-12 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.2...v3.3.0) - -Enhancements: - -* Improve formatting of arrays and hashes in failure messages so they - use our custom formatting of matchers, time objects, etc. - (Myron Marston, Nicholas Chmielewski, rspec/rspec-support#205) -* Use improved formatting for diffs as well. (Nicholas Chmielewski, rspec/rspec-support#205) - -Bug Fixes: - -* Fix `FuzzyMatcher` so that it checks `expected == actual` rather than - `actual == expected`, which avoids errors in situations where the - `actual` object's `==` is improperly implemented to assume that only - objects of the same type will be given. This allows rspec-mocks' - `anything` to match against objects with buggy `==` definitions. - (Myron Marston, rspec/rspec-support#193) - -### 3.2.2 / 2015-02-23 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.1...v3.2.2) - -Bug Fixes: - -* Fix an encoding issue with `EncodedString#split` when encountering an - invalid byte string. (Benjamin Fleischer, rspec/rspec-support#1760) - -### 3.2.1 / 2015-02-04 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.0...v3.2.1) - -Bug Fixes: - -* Fix `RSpec::CallerFilter` to work on Rubinius 2.2. - (Myron Marston, rspec/rspec-support#169) - -### 3.2.0 / 2015-02-03 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.2...v3.2.0) - -Enhancements: - -* Add extra Ruby type detection. (Jon Rowe, rspec/rspec-support#133) -* Make differ instance re-usable. (Alexey Fedorov, rspec/rspec-support#160) - -Bug Fixes: - -* Do not consider `[]` and `{}` to match when performing fuzzy matching. - (Myron Marston, rspec/rspec-support#157) - -### 3.1.2 / 2014-10-08 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.1...v3.1.2) - -Bug Fixes: - -* Fix method signature to not blow up with a `NoMethodError` on 1.8.7 when - verifying against an RSpec matcher. (Myron Marston, rspec/rspec-support#116) - -### 3.1.1 / 2014-09-26 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.0...v3.1.1) - -Bug Fixes: - -* Fix `RSpec::Support::DirectoryMaker` (used by `rspec --init` and - `rails generate rspec:install`) so that it detects absolute paths - on Windows properly. (Scott Archer, rspec/rspec-support#107, rspec/rspec-support#108, rspec/rspec-support#109) (Jon Rowe, rspec/rspec-support#110) - -### 3.1.0 / 2014-09-04 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.4...v3.1.0) - -Bug Fixes: - -* Fix `FuzzyMatcher` so that it does not wrongly match a struct against - an array. (Myron Marston, rspec/rspec-support#97) -* Prevent infinitely recursing `#flatten` methods from causing the differ - to hang. (Jon Rowe, rspec/rspec-support#101) - -### 3.0.4 / 2014-08-14 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.3...v3.0.4) - -Bug Fixes: - -* Fix `FuzzyMatcher` so that it does not silence `ArgumentError` raised - from broken implementations of `==`. (Myron Marston, rspec/rspec-support#94) - -### 3.0.3 / 2014-07-21 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.2...v3.0.3) - -Bug Fixes: - -* Fix regression in `Support#method_handle_for` where proxy objects - with method delegated would wrongly not return a method handle. - (Jon Rowe, rspec/rspec-support#90) -* Properly detect Module#prepend support in Ruby 2.1+ (Ben Langfeld, rspec/rspec-support#91) -* Fix `rspec/support/warnings.rb` so it can be loaded and used in - isolation. (Myron Marston, rspec/rspec-support#93) - -### 3.0.2 / 2014-06-20 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.1...v3.0.2) - -* Revert `BlockSignature` change from 3.0.1 because of a ruby bug that - caused it to change the block's behavior (https://bugs.ruby-lang.org/issues/9967). - (Myron Marston, rspec-mocksrspec/rspec-support#721) - -### 3.0.1 / 2014-06-19 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0...v3.0.1) - -* Fix `BlockSignature` so that it correctly differentiates between - required and optional block args. (Myron Marston, rspec-mocksrspec/rspec-support#714) - -### 3.0.0 / 2014-06-01 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.rc1...v3.0.0) - -### 3.0.0.rc1 / 2014-05-18 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta2...v3.0.0.rc1) - -### 3.0.0.beta2 / 2014-02-17 -[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta1...v3.0.0.beta2) - -Bug Fixes: - -* Issue message when :replacement is passed to `RSpec.warn_with`. (Jon Rowe) - -### 3.0.0.beta1 / 2013-11-07 -[Full Changelog](https://github.com/rspec/rspec-support/compare/0dc12d1bdbbacc757a9989f8c09cd08ef3a4837e...v3.0.0.beta1) - -Initial release. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md deleted file mode 100644 index 08aa3ab..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/LICENSE.md +++ /dev/null @@ -1,23 +0,0 @@ -The MIT License (MIT) -==================== - -* Copyright © 2013 David Chelimsky, Myron Marston, Jon Rowe, Sam Phippen, Xavier Shay, Bradley Schaefer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md deleted file mode 100644 index bb88209..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# RSpec::Support [![Build Status](https://github.com/rspec/rspec-support/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-support/actions) - -`RSpec::Support` provides common functionality to `RSpec::Core`, -`RSpec::Expectations` and `RSpec::Mocks`. It is considered -suitable for internal use only at this time. - -## Installation / Usage - -Install one or more of the `RSpec` gems. - -Want to run against the `main` branch? You'll need to include the dependent -RSpec repos as well. Add the following to your `Gemfile`: - -```ruby -%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| - gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' -end -``` - -## Contributing - -Once you've set up the environment, you'll need to cd into the working -directory of whichever repo you want to work in. From there you can run the -specs and cucumber features, and make patches. - -NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You -can treat each RSpec repo as an independent project. - -- [Build details](BUILD_DETAIL.md) -- [Code of Conduct](CODE_OF_CONDUCT.md) -- [Detailed contributing guide](CONTRIBUTING.md) -- [Development setup guide](DEVELOPMENT.md) - -## Patches - -Please submit a pull request or a github issue. If you submit an issue, please -include a link to either of: - -* a gist (or equivalent) of the patch -* a branch or commit in your github fork of the repo diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb deleted file mode 100644 index 4d36414..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support.rb +++ /dev/null @@ -1,163 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - # @api private - # - # Defines a helper method that is optimized to require files from the - # named lib. The passed block MUST be `{ |f| require_relative f }` - # because for `require_relative` to work properly from within the named - # lib the line of code must be IN that lib. - # - # `require_relative` is preferred when available because it is always O(1), - # regardless of the number of dirs in $LOAD_PATH. `require`, on the other - # hand, does a linear O(N) search over the dirs in the $LOAD_PATH until - # it can resolve the file relative to one of the dirs. - def self.define_optimized_require_for_rspec(lib, &require_relative) - name = "require_rspec_#{lib}" - - if RUBY_PLATFORM == 'java' && !Kernel.respond_to?(:require) - # JRuby 9.1.17.0 has developed a regression for require - (class << self; self; end).__send__(:define_method, name) do |f| - Kernel.send(:require, "rspec/#{lib}/#{f}") - end - elsif Kernel.respond_to?(:require_relative) - (class << self; self; end).__send__(:define_method, name) do |f| - require_relative.call("#{lib}/#{f}") - end - else - (class << self; self; end).__send__(:define_method, name) do |f| - require "rspec/#{lib}/#{f}" - end - end - end - - define_optimized_require_for_rspec(:support) { |f| require_relative(f) } - require_rspec_support "version" - require_rspec_support "ruby_features" - - # @api private - KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method) - - # @api private - # - # Used internally to get a method handle for a particular object - # and method name. - # - # Includes handling for a few special cases: - # - # - Objects that redefine #method (e.g. an HTTPRequest struct) - # - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator) - # - Objects that undefine method and delegate everything to another - # object (e.g. Mongoid association objects) - if RubyFeatures.supports_rebinding_module_methods? - def self.method_handle_for(object, method_name) - KERNEL_METHOD_METHOD.bind(object).call(method_name) - rescue NameError => original - begin - handle = object.method(method_name) - raise original unless handle.is_a? Method - handle - rescue Support::AllExceptionsExceptOnesWeMustNotRescue - raise original - end - end - else - def self.method_handle_for(object, method_name) - if ::Kernel === object - KERNEL_METHOD_METHOD.bind(object).call(method_name) - else - object.method(method_name) - end - rescue NameError => original - begin - handle = object.method(method_name) - raise original unless handle.is_a? Method - handle - rescue Support::AllExceptionsExceptOnesWeMustNotRescue - raise original - end - end - end - - # @api private - # - # Used internally to get a class of a given object, even if it does not respond to #class. - def self.class_of(object) - object.class - rescue NoMethodError - singleton_class = class << object; self; end - singleton_class.ancestors.find { |ancestor| !ancestor.equal?(singleton_class) } - end - - # A single thread local variable so we don't excessively pollute that namespace. - if RUBY_VERSION.to_f >= 2 - def self.thread_local_data - Thread.current.thread_variable_get(:__rspec) || Thread.current.thread_variable_set(:__rspec, {}) - end - else - def self.thread_local_data - Thread.current[:__rspec] ||= {} - end - end - - # @api private - def self.failure_notifier=(callable) - thread_local_data[:failure_notifier] = callable - end - - # @private - DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure } - - # @api private - def self.failure_notifier - thread_local_data[:failure_notifier] || DEFAULT_FAILURE_NOTIFIER - end - - # @api private - def self.notify_failure(failure, options={}) - failure_notifier.call(failure, options) - end - - # @api private - def self.with_failure_notifier(callable) - orig_notifier = failure_notifier - self.failure_notifier = callable - yield - ensure - self.failure_notifier = orig_notifier - end - - class << self - # @api private - attr_writer :warning_notifier - end - - # @private - DEFAULT_WARNING_NOTIFIER = lambda { |warning| ::Kernel.warn warning } - - # @api private - def self.warning_notifier - @warning_notifier ||= DEFAULT_WARNING_NOTIFIER - end - - # @private - module AllExceptionsExceptOnesWeMustNotRescue - # These exceptions are dangerous to rescue as rescuing them - # would interfere with things we should not interfere with. - AVOID_RESCUING = [NoMemoryError, SignalException, Interrupt, SystemExit] - - def self.===(exception) - AVOID_RESCUING.none? { |ar| ar === exception } - end - end - - # The Differ is only needed when a spec fails with a diffable failure. - # In the more common case of all specs passing or the only failures being - # non-diffable, we can avoid the extra cost of loading the differ, diff-lcs, - # pp, etc by avoiding an unnecessary require. Instead, autoload will take - # care of loading the differ on first use. - autoload :Differ, "rspec/support/differ" - autoload :HunkGenerator, "rspec/support/hunk_generator" - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb deleted file mode 100644 index e54b23a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/caller_filter.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support "ruby_features" - -module RSpec - # Consistent implementation for "cleaning" the caller method to strip out - # non-rspec lines. This enables errors to be reported at the call site in - # the code using the library, which is far more useful than the particular - # internal method that raised an error. - class CallerFilter - RSPEC_LIBS = %w[ - core - mocks - expectations - support - matchers - rails - ] - - ADDITIONAL_TOP_LEVEL_FILES = %w[ autorun ] - - LIB_REGEX = %r{/lib/rspec/(#{(RSPEC_LIBS + ADDITIONAL_TOP_LEVEL_FILES).join('|')})(\.rb|/)} - - # rubygems/core_ext/kernel_require.rb isn't actually part of rspec (obviously) but we want - # it ignored when we are looking for the first meaningful line of the backtrace outside - # of RSpec. It can show up in the backtrace as the immediate first caller - # when `CallerFilter.first_non_rspec_line` is called from the top level of a required - # file, but it depends on if rubygems is loaded or not. We don't want to have to deal - # with this complexity in our `RSpec.deprecate` calls, so we ignore it here. - IGNORE_REGEX = Regexp.union(LIB_REGEX, "rubygems/core_ext/kernel_require.rb", "(other) - other = self.class.new(other) unless other.is_a?(self.class) - - return 0 if string == other.string - - longer_segment_count = [self, other].map { |version| version.segments.count }.max - - longer_segment_count.times do |index| - self_segment = segments[index] || 0 - other_segment = other.segments[index] || 0 - - if self_segment.class == other_segment.class - result = self_segment <=> other_segment - return result unless result == 0 - else - return self_segment.is_a?(String) ? -1 : 1 - end - end - - 0 - end - - def segments - @segments ||= string.scan(/[a-z]+|\d+/i).map do |segment| - if segment =~ /\A\d+\z/ - segment.to_i - else - segment - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb deleted file mode 100644 index 9344fb3..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/differ.rb +++ /dev/null @@ -1,216 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support 'encoded_string' -RSpec::Support.require_rspec_support "object_formatter" - -require 'pp' - -module RSpec - module Support - # rubocop:disable Metrics/ClassLength - class Differ - def diff(actual, expected) - diff = "" - - unless actual.nil? || expected.nil? - if all_strings?(actual, expected) - if any_multiline_strings?(actual, expected) - diff = diff_as_string(coerce_to_string(actual), coerce_to_string(expected)) - end - elsif no_procs?(actual, expected) && no_numbers?(actual, expected) - diff = diff_as_object(actual, expected) - end - end - - diff.to_s - end - - # rubocop:disable Metrics/MethodLength - def diff_as_string(actual, expected) - encoding = EncodedString.pick_encoding(actual, expected) - - actual = EncodedString.new(actual, encoding) - expected = EncodedString.new(expected, encoding) - - output = EncodedString.new("\n", encoding) - hunks = build_hunks(actual, expected) - - hunks.each_cons(2) do |prev_hunk, current_hunk| - begin - if current_hunk.overlaps?(prev_hunk) - add_old_hunk_to_hunk(current_hunk, prev_hunk) - else - add_to_output(output, prev_hunk.diff(format_type).to_s) - end - ensure - add_to_output(output, "\n") - end - end - - finalize_output(output, hunks.last.diff(format_type).to_s) if hunks.last - - color_diff output - rescue Encoding::CompatibilityError - handle_encoding_errors(actual, expected) - end - # rubocop:enable Metrics/MethodLength - - def diff_as_object(actual, expected) - actual_as_string = object_to_string(actual) - expected_as_string = object_to_string(expected) - diff_as_string(actual_as_string, expected_as_string) - end - - def color? - @color - end - - def initialize(opts={}) - @color = opts.fetch(:color, false) - @object_preparer = opts.fetch(:object_preparer, lambda { |string| string }) - end - - private - - def no_procs?(*args) - safely_flatten(args).none? { |a| Proc === a } - end - - def all_strings?(*args) - safely_flatten(args).all? { |a| String === a } - end - - def any_multiline_strings?(*args) - all_strings?(*args) && safely_flatten(args).any? { |a| multiline?(a) } - end - - def no_numbers?(*args) - safely_flatten(args).none? { |a| Numeric === a } - end - - def coerce_to_string(string_or_array) - return string_or_array unless Array === string_or_array - diffably_stringify(string_or_array).join("\n") - end - - def diffably_stringify(array) - array.map do |entry| - if Array === entry - entry.inspect - else - entry.to_s.gsub("\n", "\\n").gsub("\r", "\\r") - end - end - end - - if String.method_defined?(:encoding) - def multiline?(string) - string.include?("\n".encode(string.encoding)) - end - else - def multiline?(string) - string.include?("\n") - end - end - - def build_hunks(actual, expected) - HunkGenerator.new(actual, expected).hunks - end - - def finalize_output(output, final_line) - add_to_output(output, final_line) - add_to_output(output, "\n") - end - - def add_to_output(output, string) - output << string - end - - def add_old_hunk_to_hunk(hunk, oldhunk) - hunk.merge(oldhunk) - end - - def safely_flatten(array) - array = array.flatten(1) until (array == array.flatten(1)) - array - end - - def format_type - :unified - end - - def color(text, color_code) - "\e[#{color_code}m#{text}\e[0m" - end - - def red(text) - color(text, 31) - end - - def green(text) - color(text, 32) - end - - def blue(text) - color(text, 34) - end - - def normal(text) - color(text, 0) - end - - def color_diff(diff) - return diff unless color? - - diff.lines.map do |line| - case line[0].chr - when "+" - green line - when "-" - red line - when "@" - line[1].chr == "@" ? blue(line) : normal(line) - else - normal(line) - end - end.join - end - - def object_to_string(object) - object = @object_preparer.call(object) - case object - when Hash - hash_to_string(object) - when Array - PP.pp(ObjectFormatter.prepare_for_inspection(object), "".dup) - when String - object =~ /\n/ ? object : object.inspect - else - PP.pp(object, "".dup) - end - end - - def hash_to_string(hash) - formatted_hash = ObjectFormatter.prepare_for_inspection(hash) - formatted_hash.keys.sort_by { |k| k.to_s }.map do |key| - pp_key = PP.singleline_pp(key, "".dup) - pp_value = PP.singleline_pp(formatted_hash[key], "".dup) - - "#{pp_key} => #{pp_value}," - end.join("\n") - end - - def handle_encoding_errors(actual, expected) - if actual.source_encoding != expected.source_encoding - "Could not produce a diff because the encoding of the actual string " \ - "(#{actual.source_encoding}) differs from the encoding of the expected " \ - "string (#{expected.source_encoding})" - else - "Could not produce a diff because of the encoding of the string " \ - "(#{expected.source_encoding})" - end - end - end - # rubocop:enable Metrics/ClassLength - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb deleted file mode 100644 index c59d751..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/directory_maker.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support 'ruby_features' - -module RSpec - module Support - # @api private - # - # Replacement for fileutils#mkdir_p because we don't want to require parts - # of stdlib in RSpec. - class DirectoryMaker - # @api private - # - # Implements nested directory construction - def self.mkdir_p(path) - stack = generate_stack(path) - path.split(File::SEPARATOR).each do |part| - stack = generate_path(stack, part) - begin - Dir.mkdir(stack) unless directory_exists?(stack) - rescue Errno::EEXIST => e - raise e unless directory_exists?(stack) - rescue Errno::ENOTDIR => e - raise Errno::EEXIST, e.message - end - end - end - - if OS.windows_file_path? - def self.generate_stack(path) - if path.start_with?(File::SEPARATOR) - File::SEPARATOR - elsif path[1] == ':' - '' - else - '.' - end - end - def self.generate_path(stack, part) - if stack == '' - part - elsif stack == File::SEPARATOR - File.join('', part) - else - File.join(stack, part) - end - end - else - def self.generate_stack(path) - path.start_with?(File::SEPARATOR) ? File::SEPARATOR : "." - end - def self.generate_path(stack, part) - File.join(stack, part) - end - end - - def self.directory_exists?(dirname) - File.exist?(dirname) && File.directory?(dirname) - end - private_class_method :directory_exists? - private_class_method :generate_stack - private_class_method :generate_path - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb deleted file mode 100644 index 044c151..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/encoded_string.rb +++ /dev/null @@ -1,163 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - # @private - class EncodedString - # Reduce allocations by storing constants. - UTF_8 = "UTF-8" - US_ASCII = "US-ASCII" - - # Ruby's default replacement string is: - # U+FFFD ("\xEF\xBF\xBD"), for Unicode encoding forms, else - # ? ("\x3F") - REPLACE = "?" - - def initialize(string, encoding=nil) - @encoding = encoding - @source_encoding = detect_source_encoding(string) - @string = matching_encoding(string) - end - attr_reader :source_encoding - - delegated_methods = String.instance_methods.map(&:to_s) & %w[eql? lines == encoding empty?] - delegated_methods.each do |name| - define_method(name) { |*args, &block| @string.__send__(name, *args, &block) } - end - - def <<(string) - @string << matching_encoding(string) - end - - if Ruby.jruby? - def split(regex_or_string) - @string.split(matching_encoding(regex_or_string)) - rescue ArgumentError - # JRuby raises an ArgumentError when splitting a source string that - # contains invalid bytes. - remove_invalid_bytes(@string).split regex_or_string - end - else - def split(regex_or_string) - @string.split(matching_encoding(regex_or_string)) - end - end - - def to_s - @string - end - alias :to_str :to_s - - if String.method_defined?(:encoding) - - private - - # Encoding Exceptions: - # - # Raised by Encoding and String methods: - # Encoding::UndefinedConversionError: - # when a transcoding operation fails - # if the String contains characters invalid for the target encoding - # e.g. "\x80".encode('UTF-8','ASCII-8BIT') - # vs "\x80".encode('UTF-8','ASCII-8BIT', undef: :replace, replace: '') - # # => '' - # Encoding::CompatibilityError - # when Encoding.compatible?(str1, str2) is nil - # e.g. utf_16le_emoji_string.split("\n") - # e.g. valid_unicode_string.encode(utf8_encoding) << ascii_string - # Encoding::InvalidByteSequenceError: - # when the string being transcoded contains a byte invalid for - # either the source or target encoding - # e.g. "\x80".encode('UTF-8','US-ASCII') - # vs "\x80".encode('UTF-8','US-ASCII', invalid: :replace, replace: '') - # # => '' - # ArgumentError - # when operating on a string with invalid bytes - # e.g."\x80".split("\n") - # TypeError - # when a symbol is passed as an encoding - # Encoding.find(:"UTF-8") - # when calling force_encoding on an object - # that doesn't respond to #to_str - # - # Raised by transcoding methods: - # Encoding::ConverterNotFoundError: - # when a named encoding does not correspond with a known converter - # e.g. 'abc'.force_encoding('UTF-8').encode('foo') - # or a converter path cannot be found - # e.g. "\x80".force_encoding('ASCII-8BIT').encode('Emacs-Mule') - # - # Raised by byte <-> char conversions - # RangeError: out of char range - # e.g. the UTF-16LE emoji: 128169.chr - def matching_encoding(string) - string = remove_invalid_bytes(string) - string.encode(@encoding) - rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError - # Originally defined as a constant to avoid unneeded allocations, this hash must - # be defined inline (without {}) to avoid warnings on Ruby 2.7 - # - # In MRI 2.1 'invalid: :replace' changed to also replace an invalid byte sequence - # see https://github.com/ruby/ruby/blob/v2_1_0/NEWS#L176 - # https://www.ruby-forum.com/topic/6861247 - # https://twitter.com/nalsh/status/553413844685438976 - # - # For example, given: - # "\x80".force_encoding("Emacs-Mule").encode(:invalid => :replace).bytes.to_a - # - # On MRI 2.1 or above: 63 # '?' - # else : 128 # "\x80" - # - string.encode(@encoding, :invalid => :replace, :undef => :replace, :replace => REPLACE) - rescue Encoding::ConverterNotFoundError - # Originally defined as a constant to avoid unneeded allocations, this hash must - # be defined inline (without {}) to avoid warnings on Ruby 2.7 - string.dup.force_encoding(@encoding).encode(:invalid => :replace, :replace => REPLACE) - end - - # Prevents raising ArgumentError - if String.method_defined?(:scrub) - # https://github.com/ruby/ruby/blob/eeb05e8c11/doc/NEWS-2.1.0#L120-L123 - # https://github.com/ruby/ruby/blob/v2_1_0/string.c#L8242 - # https://github.com/hsbt/string-scrub - # https://github.com/rubinius/rubinius/blob/v2.5.2/kernel/common/string.rb#L1913-L1972 - def remove_invalid_bytes(string) - string.scrub(REPLACE) - end - else - # http://stackoverflow.com/a/8711118/879854 - # Loop over chars in a string replacing chars - # with invalid encoding, which is a pretty good proxy - # for the invalid byte sequence that causes an ArgumentError - def remove_invalid_bytes(string) - string.chars.map do |char| - char.valid_encoding? ? char : REPLACE - end.join - end - end - - def detect_source_encoding(string) - string.encoding - end - - def self.pick_encoding(source_a, source_b) - Encoding.compatible?(source_a, source_b) || Encoding.default_external - end - else - - def self.pick_encoding(_source_a, _source_b) - end - - private - - def matching_encoding(string) - string - end - - def detect_source_encoding(_string) - US_ASCII - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb deleted file mode 100644 index 46c0cab..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/fuzzy_matcher.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - # Provides a means to fuzzy-match between two arbitrary objects. - # Understands array/hash nesting. Uses `===` or `==` to - # perform the matching. - module FuzzyMatcher - # @api private - def self.values_match?(expected, actual) - if Hash === actual - return hashes_match?(expected, actual) if Hash === expected - elsif Array === expected && Enumerable === actual && !(Struct === actual) - return arrays_match?(expected, actual.to_a) - end - - return true if expected == actual - - begin - expected === actual - rescue ArgumentError - # Some objects, like 0-arg lambdas on 1.9+, raise - # ArgumentError for `expected === actual`. - false - end - end - - # @private - def self.arrays_match?(expected_list, actual_list) - return false if expected_list.size != actual_list.size - - expected_list.zip(actual_list).all? do |expected, actual| - values_match?(expected, actual) - end - end - - # @private - def self.hashes_match?(expected_hash, actual_hash) - return false if expected_hash.size != actual_hash.size - - expected_hash.all? do |expected_key, expected_value| - actual_value = actual_hash.fetch(expected_key) { return false } - values_match?(expected_value, actual_value) - end - end - - private_class_method :arrays_match?, :hashes_match? - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb deleted file mode 100644 index 086a88e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/hunk_generator.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -require 'diff/lcs' -require 'diff/lcs/hunk' - -module RSpec - module Support - # @private - class HunkGenerator - def initialize(actual, expected) - @actual = actual - @expected = expected - end - - def hunks - @file_length_difference = 0 - @hunks ||= diffs.map do |piece| - build_hunk(piece) - end - end - - private - - def diffs - Diff::LCS.diff(expected_lines, actual_lines) - end - - def expected_lines - @expected.split("\n").map! { |e| e.chomp } - end - - def actual_lines - @actual.split("\n").map! { |e| e.chomp } - end - - def build_hunk(piece) - Diff::LCS::Hunk.new( - expected_lines, actual_lines, piece, context_lines, @file_length_difference - ).tap do |h| - @file_length_difference = h.file_length_difference - end - end - - def context_lines - 3 - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb deleted file mode 100644 index 6b7819c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/matcher_definition.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - # @private - def self.matcher_definitions - @matcher_definitions ||= [] - end - - # Used internally to break cyclic dependency between mocks, expectations, - # and support. We don't currently have a consistent implementation of our - # matchers, though we are considering changing that: - # https://github.com/rspec/rspec-mocks/issues/513 - # - # @private - def self.register_matcher_definition(&block) - matcher_definitions << block - end - - # Remove a previously registered matcher. Useful for cleaning up after - # yourself in specs. - # - # @private - def self.deregister_matcher_definition(&block) - matcher_definitions.delete(block) - end - - # @private - def self.is_a_matcher?(object) - matcher_definitions.any? { |md| md.call(object) } - end - - # @api private - # - # gives a string representation of an object for use in RSpec descriptions - def self.rspec_description_for_object(object) - if RSpec::Support.is_a_matcher?(object) && object.respond_to?(:description) - object.description - else - object - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb deleted file mode 100644 index a462772..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/method_signature_verifier.rb +++ /dev/null @@ -1,467 +0,0 @@ -# frozen_string_literal: true - -require 'rspec/support' -RSpec::Support.require_rspec_support "ruby_features" -RSpec::Support.require_rspec_support "matcher_definition" - -module RSpec - module Support - # Extracts info about the number of arguments and allowed/required - # keyword args of a given method. - # - # @private - class MethodSignature # rubocop:disable Metrics/ClassLength - attr_reader :min_non_kw_args, :max_non_kw_args, :optional_kw_args, :required_kw_args - - def initialize(method) - @method = method - @optional_kw_args = [] - @required_kw_args = [] - classify_parameters - end - - def non_kw_args_arity_description - case max_non_kw_args - when min_non_kw_args then min_non_kw_args.to_s - when INFINITY then "#{min_non_kw_args} or more" - else "#{min_non_kw_args} to #{max_non_kw_args}" - end - end - - def valid_non_kw_args?(positional_arg_count, optional_max_arg_count=positional_arg_count) - return true if positional_arg_count.nil? - - min_non_kw_args <= positional_arg_count && - optional_max_arg_count <= max_non_kw_args - end - - def classify_arity(arity=@method.arity) - if arity < 0 - # `~` inverts the one's complement and gives us the - # number of required args - @min_non_kw_args = ~arity - @max_non_kw_args = INFINITY - else - @min_non_kw_args = arity - @max_non_kw_args = arity - end - end - - if RubyFeatures.optional_and_splat_args_supported? - def description - @description ||= begin - parts = [] - - unless non_kw_args_arity_description == "0" - parts << "arity of #{non_kw_args_arity_description}" - end - - if @optional_kw_args.any? - parts << "optional keyword args (#{@optional_kw_args.map(&:inspect).join(", ")})" - end - - if @required_kw_args.any? - parts << "required keyword args (#{@required_kw_args.map(&:inspect).join(", ")})" - end - - parts << "any additional keyword args" if @allows_any_kw_args - - parts.join(" and ") - end - end - - def missing_kw_args_from(given_kw_args) - @required_kw_args - given_kw_args - end - - def invalid_kw_args_from(given_kw_args) - return [] if @allows_any_kw_args - given_kw_args - @allowed_kw_args - end - - # Considering the arg types, are there kw_args? - if RubyFeatures.kw_arg_separation? - def has_kw_args_in?(args) - # If the last arg is a hash, depending on the signature it could be kw_args or a positional parameter. - return false unless Hash === args.last && could_contain_kw_args?(args) - - # If the position of the hash is beyond the count of required and optional positional - # args then it is the kwargs hash - return true if args.count > @max_non_kw_args - - # This is the proper way to disambiguate between positional args and keywords hash - # but relies on beginning of the call chain annotating the method with - # ruby2_keywords, so only use it for positive feedback as without the annotation - # this is always false - return true if Hash.ruby2_keywords_hash?(args[-1]) - - # Otherwise, the hash could be defined kw_args or an optional positional parameter - # inspect the keys against known kwargs to determine what it is - # Note: the problem with this is that if a user passes only invalid keyword args, - # rspec no longer detects is and will assign this to a positional argument - return arbitrary_kw_args? || args.last.keys.all? { |x| @allowed_kw_args.include?(x) } - end - else - def has_kw_args_in?(args) - # Version <= Ruby 2.7 - # If the last argument is Hash, Ruby will treat only symbol keys as keyword arguments - # the rest will be grouped in another Hash and passed as positional argument. - Hash === args.last && - could_contain_kw_args?(args) && - (args.last.empty? || args.last.keys.any? { |x| x.is_a?(Symbol) }) - end - end - - # Without considering what the last arg is, could it - # contain keyword arguments? - def could_contain_kw_args?(args) - return false if args.count <= min_non_kw_args - - @allows_any_kw_args || @allowed_kw_args.any? - end - - def arbitrary_kw_args? - @allows_any_kw_args - end - - def unlimited_args? - @max_non_kw_args == INFINITY - end - - def classify_parameters - optional_non_kw_args = @min_non_kw_args = 0 - @allows_any_kw_args = false - - @method.parameters.each do |(type, name)| - case type - # def foo(a:) - when :keyreq then @required_kw_args << name - # def foo(a: 1) - when :key then @optional_kw_args << name - # def foo(**kw_args) - when :keyrest then @allows_any_kw_args = true - # def foo(a) - when :req then @min_non_kw_args += 1 - # def foo(a = 1) - when :opt then optional_non_kw_args += 1 - # def foo(*a) - when :rest then optional_non_kw_args = INFINITY - end - end - - @max_non_kw_args = @min_non_kw_args + optional_non_kw_args - @allowed_kw_args = @required_kw_args + @optional_kw_args - end - else - def description - "arity of #{non_kw_args_arity_description}" - end - - def missing_kw_args_from(_given_kw_args) - [] - end - - def invalid_kw_args_from(_given_kw_args) - [] - end - - def has_kw_args_in?(_args) - false - end - - def could_contain_kw_args?(*) - false - end - - def arbitrary_kw_args? - false - end - - def unlimited_args? - false - end - - alias_method :classify_parameters, :classify_arity - end - - INFINITY = 1 / 0.0 - end - - if RSpec::Support::Ruby.jruby? - # JRuby has only partial support for UnboundMethod#parameters, so we fall back on using #arity - # https://github.com/jruby/jruby/issues/2816 and https://github.com/jruby/jruby/issues/2817 - if RubyFeatures.optional_and_splat_args_supported? && - Java::JavaLang::String.instance_method(:char_at).parameters == [] - - class MethodSignature < remove_const(:MethodSignature) - private - - def classify_parameters - super - if (arity = @method.arity) != 0 && @method.parameters.empty? - classify_arity(arity) - end - end - end - end - - # JRuby used to always report -1 arity for Java proxy methods. - # The workaround essentially makes use of Java's introspection to figure - # out matching methods (which could be more than one partly because Java - # supports multiple overloads, and partly because JRuby introduces - # aliases to make method names look more Rubyesque). If there is only a - # single match, we can use that methods arity directly instead of the - # default -1 arity. - # - # This workaround only works for Java proxy methods, and in order to - # support regular methods and blocks, we need to be careful about calling - # owner and java_class as they might not be available - if Java::JavaLang::String.instance_method(:char_at).arity == -1 - class MethodSignature < remove_const(:MethodSignature) - private - - def classify_parameters - super - return unless @method.arity == -1 - return unless @method.respond_to?(:owner) - return unless @method.owner.respond_to?(:java_class) - java_instance_methods = @method.owner.java_class.java_instance_methods - compatible_overloads = java_instance_methods.select do |java_method| - @method == @method.owner.instance_method(java_method.name) - end - if compatible_overloads.size == 1 - classify_arity(compatible_overloads.first.arity) - end - end - end - end - end - - # Encapsulates expectations about the number of arguments and - # allowed/required keyword args of a given method. - # - # @api private - class MethodSignatureExpectation - def initialize - @min_count = nil - @max_count = nil - @keywords = [] - - @expect_unlimited_arguments = false - @expect_arbitrary_keywords = false - end - - attr_reader :min_count, :max_count, :keywords - - attr_accessor :expect_unlimited_arguments, :expect_arbitrary_keywords - - def max_count=(number) - raise ArgumentError, 'must be a non-negative integer or nil' \ - unless number.nil? || (number.is_a?(Integer) && number >= 0) - - @max_count = number - end - - def min_count=(number) - raise ArgumentError, 'must be a non-negative integer or nil' \ - unless number.nil? || (number.is_a?(Integer) && number >= 0) - - @min_count = number - end - - def empty? - @min_count.nil? && - @keywords.to_a.empty? && - !@expect_arbitrary_keywords && - !@expect_unlimited_arguments - end - - def keywords=(values) - @keywords = values.to_a || [] - end - end - - # Deals with the slightly different semantics of block arguments. - # For methods, arguments are required unless a default value is provided. - # For blocks, arguments are optional, even if no default value is provided. - # - # However, we want to treat block args as required since you virtually - # always want to pass a value for each received argument and our - # `and_yield` has treated block args as required for many years. - # - # @api private - class BlockSignature < MethodSignature - if RubyFeatures.optional_and_splat_args_supported? - def classify_parameters - super - @min_non_kw_args = @max_non_kw_args unless @max_non_kw_args == INFINITY - end - end - end - - # Abstract base class for signature verifiers. - # - # @api private - class MethodSignatureVerifier - attr_reader :non_kw_args, :kw_args, :min_non_kw_args, :max_non_kw_args - - def initialize(signature, args=[]) - @signature = signature - @non_kw_args, @kw_args = split_args(args.clone) - @min_non_kw_args = @max_non_kw_args = @non_kw_args - @arbitrary_kw_args = @unlimited_args = false - end - - def with_expectation(expectation) # rubocop:disable Metrics/MethodLength - return self unless MethodSignatureExpectation === expectation - - if expectation.empty? - @min_non_kw_args = @max_non_kw_args = @non_kw_args = nil - @kw_args = [] - else - @min_non_kw_args = @non_kw_args = expectation.min_count || 0 - @max_non_kw_args = expectation.max_count || @min_non_kw_args - - if RubyFeatures.optional_and_splat_args_supported? - @unlimited_args = expectation.expect_unlimited_arguments - else - @unlimited_args = false - end - - if RubyFeatures.kw_args_supported? - @kw_args = expectation.keywords - @arbitrary_kw_args = expectation.expect_arbitrary_keywords - else - @kw_args = [] - @arbitrary_kw_args = false - end - end - - self - end - - def valid? - missing_kw_args.empty? && - invalid_kw_args.empty? && - valid_non_kw_args? && - arbitrary_kw_args? && - unlimited_args? - end - - def error_message - if missing_kw_args.any? - "Missing required keyword arguments: %s" % [ - missing_kw_args.join(", ") - ] - elsif invalid_kw_args.any? - "Invalid keyword arguments provided: %s" % [ - invalid_kw_args.join(", ") - ] - elsif !valid_non_kw_args? - "Wrong number of arguments. Expected %s, got %s." % [ - @signature.non_kw_args_arity_description, - non_kw_args - ] - end - end - - private - - def valid_non_kw_args? - @signature.valid_non_kw_args?(min_non_kw_args, max_non_kw_args) - end - - def missing_kw_args - @signature.missing_kw_args_from(kw_args) - end - - def invalid_kw_args - @signature.invalid_kw_args_from(kw_args) - end - - def arbitrary_kw_args? - !@arbitrary_kw_args || @signature.arbitrary_kw_args? - end - - def unlimited_args? - !@unlimited_args || @signature.unlimited_args? - end - - def split_args(args) - kw_args = if @signature.has_kw_args_in?(args) && !RubyFeatures.kw_arg_separation? - last = args.pop - non_kw_args = last.reject { |k, _| k.is_a?(Symbol) } - if non_kw_args.empty? - last.keys - else - args << non_kw_args - last.select { |k, _| k.is_a?(Symbol) }.keys - end - elsif @signature.has_kw_args_in?(args) && RubyFeatures.kw_arg_separation? - args.pop.keys - else - [] - end - - [args.length, kw_args] - end - end - - # Figures out whether a given method can accept various arguments. - # Surprisingly non-trivial. - # - # @private - StrictSignatureVerifier = MethodSignatureVerifier - - # Allows matchers to be used instead of providing keyword arguments. In - # practice, when this happens only the arity of the method is verified. - # - # @private - class LooseSignatureVerifier < MethodSignatureVerifier - private - - def split_args(args) - if RSpec::Support.is_a_matcher?(args.last) && @signature.could_contain_kw_args?(args) - args.pop - @signature = SignatureWithKeywordArgumentsMatcher.new(@signature) - end - - super(args) - end - - # If a matcher is used in a signature in place of keyword arguments, all - # keyword argument validation needs to be skipped since the matcher is - # opaque. - # - # Instead, keyword arguments will be validated when the method is called - # and they are actually known. - # - # @private - class SignatureWithKeywordArgumentsMatcher - def initialize(signature) - @signature = signature - end - - def missing_kw_args_from(_kw_args) - [] - end - - def invalid_kw_args_from(_kw_args) - [] - end - - def non_kw_args_arity_description - @signature.non_kw_args_arity_description - end - - def valid_non_kw_args?(*args) - @signature.valid_non_kw_args?(*args) - end - - def has_kw_args_in?(args) - @signature.has_kw_args_in?(args) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb deleted file mode 100644 index 63eeca4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/mutex.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - # On 1.8.7, it's in the stdlib. - # We don't want to load the stdlib, b/c this is a test tool, and can affect - # the test environment, causing tests to pass where they should fail. - # - # So we're transcribing/modifying it from - # https://github.com/ruby/ruby/blob/v1_8_7_374/lib/thread.rb#L56 - # Some methods we don't need are deleted. Anything I don't - # understand (there's quite a bit, actually) is left in. - # - # Some formatting changes are made to appease the robot overlord: - # https://travis-ci.org/rspec/rspec-core/jobs/54410874 - # @private - class Mutex - def initialize - @waiting = [] - @locked = false - @waiting.taint - taint - end - - # @private - def lock - while Thread.critical = true && @locked - @waiting.push Thread.current - Thread.stop - end - @locked = true - Thread.critical = false - self - end - - # @private - def unlock - return unless @locked - Thread.critical = true - @locked = false - wakeup_and_run_waiting_thread - self - end - - # @private - def synchronize - lock - begin - yield - ensure - unlock - end - end - - private - - def wakeup_and_run_waiting_thread - begin - t = @waiting.shift - t.wakeup if t - rescue ThreadError - retry - end - Thread.critical = false - begin - t.run if t - rescue ThreadError - :noop - end - end - - # Avoid warnings for library wide checks spec - end unless defined?(::RSpec::Support::Mutex) || defined?(::Mutex) - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb deleted file mode 100644 index d464f1b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/object_formatter.rb +++ /dev/null @@ -1,279 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support 'matcher_definition' - -module RSpec - module Support - # Provide additional output details beyond what `inspect` provides when - # printing Time, DateTime, or BigDecimal - # @api private - class ObjectFormatter # rubocop:disable Metrics/ClassLength - ELLIPSIS = "..." - - attr_accessor :max_formatted_output_length - - # Methods are deferred to a default instance of the class to maintain the interface - # For example, calling ObjectFormatter.format is still possible - def self.default_instance - @default_instance ||= new - end - - def self.format(object) - default_instance.format(object) - end - - def self.prepare_for_inspection(object) - default_instance.prepare_for_inspection(object) - end - - def initialize(max_formatted_output_length=200) - @max_formatted_output_length = max_formatted_output_length - @current_structure_stack = [] - end - - def format(object) - if max_formatted_output_length.nil? - prepare_for_inspection(object).inspect - else - formatted_object = prepare_for_inspection(object).inspect - if formatted_object.length < max_formatted_output_length - formatted_object - else - beginning = truncate_string formatted_object, 0, max_formatted_output_length / 2 - ending = truncate_string formatted_object, -max_formatted_output_length / 2, -1 - beginning + ELLIPSIS + ending - end - end - end - - # Prepares the provided object to be formatted by wrapping it as needed - # in something that, when `inspect` is called on it, will produce the - # desired output. - # - # This allows us to apply the desired formatting to hash/array data structures - # at any level of nesting, simply by walking that structure and replacing items - # with custom items that have `inspect` defined to return the desired output - # for that item. Then we can just use `Array#inspect` or `Hash#inspect` to - # format the entire thing. - def prepare_for_inspection(object) - case object - when Array - prepare_array(object) - when Hash - prepare_hash(object) - when Symbol - object - else - inspector_class = INSPECTOR_CLASSES.find { |inspector| inspector.can_inspect?(object) } - inspector_class.new(object, self) - end - end - - def prepare_array(array) - with_entering_structure(array) do - array.map { |element| prepare_element(element) } - end - end - - def prepare_hash(input_hash) - with_entering_structure(input_hash) do - sort_hash_keys(input_hash).inject({}) do |output_hash, key_and_value| - key, value = key_and_value.map { |element| prepare_element(element) } - output_hash[key] = value - output_hash - end - end - end - - def sort_hash_keys(input_hash) - if input_hash.keys.all? { |k| k.is_a?(String) || k.is_a?(Symbol) } - Hash[input_hash.sort_by { |k, _v| k.to_s }] - else - input_hash - end - end - - def prepare_element(element) - if recursive_structure?(element) - case element - when Array then InspectableItem.new('[...]') - when Hash then InspectableItem.new('{...}') - else raise # This won't happen - end - else - prepare_for_inspection(element) - end - end - - def with_entering_structure(structure) - @current_structure_stack.push(structure) - return_value = yield - @current_structure_stack.pop - return_value - end - - def recursive_structure?(object) - @current_structure_stack.any? { |seen_structure| seen_structure.equal?(object) } - end - - InspectableItem = Struct.new(:text) do - def inspect - text - end - - def pretty_print(pp) - pp.text(text) - end - end - - BaseInspector = Struct.new(:object, :formatter) do - def self.can_inspect?(_object) - raise NotImplementedError - end - - def inspect - raise NotImplementedError - end - - def pretty_print(pp) - pp.text(inspect) - end - end - - class TimeInspector < BaseInspector - FORMAT = "%Y-%m-%d %H:%M:%S" - - def self.can_inspect?(object) - Time === object - end - - if Time.method_defined?(:nsec) - def inspect - object.strftime("#{FORMAT}.#{"%09d" % object.nsec} %z") - end - else # for 1.8.7 - def inspect - object.strftime("#{FORMAT}.#{"%06d" % object.usec} %z") - end - end - end - - class DateTimeInspector < BaseInspector - FORMAT = "%a, %d %b %Y %H:%M:%S.%N %z" - - def self.can_inspect?(object) - defined?(DateTime) && DateTime === object - end - - # ActiveSupport sometimes overrides inspect. If `ActiveSupport` is - # defined use a custom format string that includes more time precision. - def inspect - if defined?(ActiveSupport) - object.strftime(FORMAT) - else - object.inspect - end - end - end - - class BigDecimalInspector < BaseInspector - def self.can_inspect?(object) - defined?(BigDecimal) && BigDecimal === object - end - - def inspect - "#{object.to_s('F')} (#{object.inspect})" - end - end - - class DescribableMatcherInspector < BaseInspector - def self.can_inspect?(object) - Support.is_a_matcher?(object) && object.respond_to?(:description) - end - - def inspect - object.description - end - end - - class UninspectableObjectInspector < BaseInspector - OBJECT_ID_FORMAT = '%#016x' - - def self.can_inspect?(object) - object.inspect - false - rescue NoMethodError - true - end - - def inspect - "#<#{klass}:#{native_object_id}>" - end - - def klass - Support.class_of(object) - end - - # http://stackoverflow.com/a/2818916 - def native_object_id - OBJECT_ID_FORMAT % (object.__id__ << 1) - rescue NoMethodError - # In Ruby 1.9.2, BasicObject responds to none of #__id__, #object_id, #id... - '-' - end - end - - class DelegatorInspector < BaseInspector - def self.can_inspect?(object) - defined?(Delegator) && Delegator === object - end - - def inspect - "#<#{object.class}(#{formatter.format(object.send(:__getobj__))})>" - end - end - - class InspectableObjectInspector < BaseInspector - def self.can_inspect?(object) - object.inspect - true - rescue NoMethodError - false - end - - def inspect - object.inspect - end - end - - INSPECTOR_CLASSES = [ - TimeInspector, - DateTimeInspector, - BigDecimalInspector, - UninspectableObjectInspector, - DescribableMatcherInspector, - DelegatorInspector, - InspectableObjectInspector - ].tap do |classes| - # 2.4 has improved BigDecimal formatting so we do not need - # to provide our own. - # https://github.com/ruby/bigdecimal/pull/42 - classes.delete(BigDecimalInspector) if RUBY_VERSION >= '2.4' - end - - private - - # Returns the substring defined by the start_index and end_index - # If the string ends with a partial ANSI code code then that - # will be removed as printing partial ANSI - # codes to the terminal can lead to corruption - def truncate_string(str, start_index, end_index) - cut_str = str[start_index..end_index] - - # ANSI color codes are like: \e[33m so anything with \e[ and a - # number without a 'm' is an incomplete color code - cut_str.sub(/\e\[\d+$/, '') - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb deleted file mode 100644 index ac2910d..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/recursive_const_methods.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - # Provides recursive constant lookup methods useful for - # constant stubbing. - module RecursiveConstMethods - # We only want to consider constants that are defined directly on a - # particular module, and not include top-level/inherited constants. - # Unfortunately, the constant API changed between 1.8 and 1.9, so - # we need to conditionally define methods to ignore the top-level/inherited - # constants. - # - # Given: - # class A; B = 1; end - # class C < A; end - # - # On 1.8: - # - C.const_get("Hash") # => ::Hash - # - C.const_defined?("Hash") # => false - # - C.constants # => ["B"] - # - None of these methods accept the extra `inherit` argument - # On 1.9: - # - C.const_get("Hash") # => ::Hash - # - C.const_defined?("Hash") # => true - # - C.const_get("Hash", false) # => raises NameError - # - C.const_defined?("Hash", false) # => false - # - C.constants # => [:B] - # - C.constants(false) #=> [] - if Module.method(:const_defined?).arity == 1 - def const_defined_on?(mod, const_name) - mod.const_defined?(const_name) - end - - def get_const_defined_on(mod, const_name) - return mod.const_get(const_name) if const_defined_on?(mod, const_name) - - raise NameError, "uninitialized constant #{mod.name}::#{const_name}" - end - - def constants_defined_on(mod) - mod.constants.select { |c| const_defined_on?(mod, c) } - end - else - def const_defined_on?(mod, const_name) - mod.const_defined?(const_name, false) - end - - def get_const_defined_on(mod, const_name) - mod.const_get(const_name, false) - end - - def constants_defined_on(mod) - mod.constants(false) - end - end - - def recursive_const_get(const_name) - normalize_const_name(const_name).split('::').inject(Object) do |mod, name| - get_const_defined_on(mod, name) - end - end - - def recursive_const_defined?(const_name) - parts = normalize_const_name(const_name).split('::') - parts.inject([Object, '']) do |(mod, full_name), name| - yield(full_name, name) if block_given? && !(Module === mod) - return false unless const_defined_on?(mod, name) - [get_const_defined_on(mod, name), [mod.name, name].join('::')] - end - end - - def normalize_const_name(const_name) - const_name.sub(/\A::/, '') - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb deleted file mode 100644 index 28957a2..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/reentrant_mutex.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - # Allows a thread to lock out other threads from a critical section of code, - # while allowing the thread with the lock to reenter that section. - # - # Based on Monitor as of 2.2 - - # https://github.com/ruby/ruby/blob/eb7ddaa3a47bf48045d26c72eb0f263a53524ebc/lib/monitor.rb#L9 - # - # Depends on Mutex, but Mutex is only available as part of core since 1.9.1: - # exists - http://ruby-doc.org/core-1.9.1/Mutex.html - # dne - http://ruby-doc.org/core-1.9.0/Mutex.html - # - # @private - class ReentrantMutex - def initialize - @owner = nil - @count = 0 - @mutex = Mutex.new - end - - def synchronize - enter - yield - ensure - exit - end - - private - - # This is fixing a bug #501 that is specific to Ruby 3.0. The new implementation - # depends on `owned?` that was introduced in Ruby 2.0, so both should work for Ruby 2.x. - if RUBY_VERSION.to_f >= 3.0 - def enter - @mutex.lock unless @mutex.owned? - @count += 1 - end - - def exit - unless @mutex.owned? - raise ThreadError, "Attempt to unlock a mutex which is locked by another thread/fiber" - end - @count -= 1 - @mutex.unlock if @count == 0 - end - else - def enter - @mutex.lock if @owner != Thread.current - @owner = Thread.current - @count += 1 - end - - def exit - @count -= 1 - return unless @count == 0 - @owner = nil - @mutex.unlock - end - end - end - - if defined? ::Mutex - # On 1.9 and up, this is in core, so we just use the real one - class Mutex < ::Mutex - # If you mock Mutex.new you break our usage of Mutex, so - # instead we capture the original method to return Mutexes. - NEW_MUTEX_METHOD = Mutex.method(:new) - - def self.new - NEW_MUTEX_METHOD.call - end - end - else # For 1.8.7 - # :nocov: - RSpec::Support.require_rspec_support "mutex" - # :nocov: - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb deleted file mode 100644 index 7ccdb7e..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/ruby_features.rb +++ /dev/null @@ -1,221 +0,0 @@ -# frozen_string_literal: true - -require 'rbconfig' -RSpec::Support.require_rspec_support "comparable_version" - -module RSpec - module Support - # @api private - # - # Provides query methods for different OS or OS features. - module OS - module_function - - def windows? - !!(RbConfig::CONFIG['host_os'] =~ /cygwin|mswin|mingw|bccwin|wince|emx/) - end - - def windows_file_path? - ::File::ALT_SEPARATOR == '\\' - end - end - - # @api private - # - # Provides query methods for different rubies - module Ruby - module_function - - def jruby? - RUBY_PLATFORM == 'java' - end - - def jruby_version - @jruby_version ||= ComparableVersion.new(JRUBY_VERSION) - end - - def jruby_9000? - jruby? && JRUBY_VERSION >= '9.0.0.0' - end - - def rbx? - defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' - end - - def non_mri? - !mri? - end - - def mri? - !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' - end - - def truffleruby? - defined?(RUBY_ENGINE) && RUBY_ENGINE == 'truffleruby' - end - end - - # @api private - # - # Provides query methods for ruby features that differ among - # implementations. - module RubyFeatures - module_function - - if Ruby.jruby? && RUBY_VERSION.to_f < 1.9 - # On JRuby 1.7 `--1.8` mode, `Process.respond_to?(:fork)` returns true, - # but when you try to fork, it raises an error: - # NotImplementedError: fork is not available on this platform - # - # When we drop support for JRuby 1.7 and/or Ruby 1.8, we can drop - # this special case. - def fork_supported? - false - end - else - def fork_supported? - Process.respond_to?(:fork) - end - end - - def optional_and_splat_args_supported? - Method.method_defined?(:parameters) - end - - def caller_locations_supported? - respond_to?(:caller_locations, true) - end - - if Exception.method_defined?(:cause) - def supports_exception_cause? - true - end - else - def supports_exception_cause? - false - end - end - - if RUBY_VERSION.to_f >= 3.2 - def supports_syntax_suggest? - true - end - else - def supports_syntax_suggest? - false - end - end - - if RUBY_VERSION.to_f >= 3.0 - # https://rubyreferences.github.io/rubychanges/3.0.html#keyword-arguments-are-now-fully-separated-from-positional-arguments - def kw_arg_separation? - true - end - else - def kw_arg_separation? - false - end - end - - if RUBY_VERSION.to_f >= 2.7 - def supports_taint? - false - end - else - def supports_taint? - true - end - end - ripper_requirements = [ComparableVersion.new(RUBY_VERSION) >= '1.9.2'] - - ripper_requirements.push(false) if Ruby.rbx? - - if Ruby.jruby? - ripper_requirements.push(Ruby.jruby_version >= '1.7.5') - # Ripper on JRuby 9.0.0.0.rc1 - 9.1.8.0 reports wrong line number - # or cannot parse source including `:if`. - # Ripper on JRuby 9.x.x.x < 9.1.17.0 can't handle keyword arguments - # Neither can JRuby 9.2, e.g. < 9.2.1.0 - ripper_requirements.push(!Ruby.jruby_version.between?('9.0.0.0.rc1', '9.2.0.0')) - end - - # TruffleRuby disables ripper due to low performance - ripper_requirements.push(false) if Ruby.truffleruby? - - if ripper_requirements.all? - def ripper_supported? - true - end - else - def ripper_supported? - false - end - end - - def distincts_kw_args_from_positional_hash? - RUBY_VERSION >= '3.0.0' - end - - if Ruby.mri? - def kw_args_supported? - RUBY_VERSION >= '2.0.0' - end - - def required_kw_args_supported? - RUBY_VERSION >= '2.1.0' - end - - def supports_rebinding_module_methods? - RUBY_VERSION.to_i >= 2 - end - else - # RBX / JRuby et al support is unknown for keyword arguments - begin - eval("o = Object.new; def o.m(a: 1); end;"\ - " raise SyntaxError unless o.method(:m).parameters.include?([:key, :a])") - - def kw_args_supported? - true - end - rescue SyntaxError - def kw_args_supported? - false - end - end - - begin - eval("o = Object.new; def o.m(a: ); end;"\ - "raise SyntaxError unless o.method(:m).parameters.include?([:keyreq, :a])") - - def required_kw_args_supported? - true - end - rescue SyntaxError - def required_kw_args_supported? - false - end - end - - begin - Module.new { def foo; end }.instance_method(:foo).bind(Object.new) - - def supports_rebinding_module_methods? - true - end - rescue TypeError - def supports_rebinding_module_methods? - false - end - end - end - - def module_refinement_supported? - Module.method_defined?(:refine) || Module.private_method_defined?(:refine) - end - - def module_prepends_supported? - Module.method_defined?(:prepend) || Module.private_method_defined?(:prepend) - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb deleted file mode 100644 index 8aad27b..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source.rb +++ /dev/null @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support 'encoded_string' -RSpec::Support.require_rspec_support 'ruby_features' - -module RSpec - module Support - # @private - # Represents a Ruby source file and provides access to AST and tokens. - class Source - attr_reader :source, :path - - # This class protects us against having File read and expand_path - # stubbed out within tests. - class File - class << self - [:read, :expand_path].each do |method_name| - define_method(method_name, &::File.method(method_name)) - end - end - end - - def self.from_file(path) - source = File.read(path) - new(source, path) - end - - if String.method_defined?(:encoding) - def initialize(source_string, path=nil) - @source = RSpec::Support::EncodedString.new(source_string, Encoding.default_external) - @path = path ? File.expand_path(path) : '(string)' - end - else # for 1.8.7 - # :nocov: - def initialize(source_string, path=nil) - @source = RSpec::Support::EncodedString.new(source_string) - @path = path ? File.expand_path(path) : '(string)' - end - # :nocov: - end - - def lines - @lines ||= source.split("\n") - end - - def inspect - "#<#{self.class} #{path}>" - end - - if RSpec::Support::RubyFeatures.ripper_supported? - RSpec::Support.require_rspec_support 'source/node' - RSpec::Support.require_rspec_support 'source/token' - - def ast - @ast ||= begin - require 'ripper' - sexp = Ripper.sexp(source) - raise SyntaxError unless sexp - Node.new(sexp) - end - end - - def tokens - @tokens ||= begin - require 'ripper' - tokens = Ripper.lex(source) - Token.tokens_from_ripper_tokens(tokens) - end - end - - def nodes_by_line_number - @nodes_by_line_number ||= begin - nodes_by_line_number = ast.select(&:location).group_by { |node| node.location.line } - Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number) - end - end - - def tokens_by_line_number - @tokens_by_line_number ||= begin - nodes_by_line_number = tokens.group_by { |token| token.location.line } - Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number) - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb deleted file mode 100644 index fb5a377..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/location.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - class Source - # @private - # Represents a source location of node or token. - Location = Struct.new(:line, :column) do - include Comparable - - def self.location?(array) - array.is_a?(Array) && array.size == 2 && array.all? { |e| e.is_a?(Integer) } - end - - def <=>(other) - line_comparison = (line <=> other.line) - return line_comparison unless line_comparison == 0 - column <=> other.column - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb deleted file mode 100644 index 359bf9f..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/node.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support 'source/location' - -module RSpec - module Support - class Source - # @private - # A wrapper for Ripper AST node which is generated with `Ripper.sexp`. - class Node - include Enumerable - - attr_reader :sexp, :parent - - def self.sexp?(array) - array.is_a?(Array) && array.first.is_a?(Symbol) - end - - def initialize(ripper_sexp, parent=nil) - @sexp = ripper_sexp.freeze - @parent = parent - end - - def type - sexp[0] - end - - def args - @args ||= raw_args.map do |raw_arg| - if Node.sexp?(raw_arg) - Node.new(raw_arg, self) - elsif Location.location?(raw_arg) - Location.new(*raw_arg) - elsif raw_arg.is_a?(Array) - ExpressionSequenceNode.new(raw_arg, self) - else - raw_arg - end - end.freeze - end - - def children - @children ||= args.select { |arg| arg.is_a?(Node) }.freeze - end - - def location - @location ||= args.find { |arg| arg.is_a?(Location) } - end - - # We use a loop here (instead of recursion) to prevent SystemStackError - def each - return to_enum(__method__) unless block_given? - - node_queue = [] - node_queue << self - - while (current_node = node_queue.shift) - yield current_node - node_queue.concat(current_node.children) - end - end - - def each_ancestor - return to_enum(__method__) unless block_given? - - current_node = self - - while (current_node = current_node.parent) - yield current_node - end - end - - def inspect - "#<#{self.class} #{type}>" - end - - private - - def raw_args - sexp[1..-1] || [] - end - end - - # @private - # Basically `Ripper.sexp` generates arrays whose first element is a symbol (type of sexp), - # but it exceptionally generates typeless arrays for expression sequence: - # - # Ripper.sexp('foo; bar') - # => [ - # :program, - # [ # Typeless array - # [:vcall, [:@ident, "foo", [1, 0]]], - # [:vcall, [:@ident, "bar", [1, 5]]] - # ] - # ] - # - # We wrap typeless arrays in this pseudo type node - # so that it can be handled in the same way as other type node. - class ExpressionSequenceNode < Node - def type - :_expression_sequence - end - - private - - def raw_args - sexp - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb deleted file mode 100644 index ca887a7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/source/token.rb +++ /dev/null @@ -1,96 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support 'source/location' - -module RSpec - module Support - class Source - # @private - # A wrapper for Ripper token which is generated with `Ripper.lex`. - class Token - CLOSING_TYPES_BY_OPENING_TYPE = { - :on_lbracket => :on_rbracket, - :on_lparen => :on_rparen, - :on_lbrace => :on_rbrace, - :on_heredoc_beg => :on_heredoc_end - }.freeze - - CLOSING_KEYWORDS_BY_OPENING_KEYWORD = { - 'def' => 'end', - 'do' => 'end', - }.freeze - - attr_reader :token - - def self.tokens_from_ripper_tokens(ripper_tokens) - ripper_tokens.map { |ripper_token| new(ripper_token) }.freeze - end - - def initialize(ripper_token) - @token = ripper_token.freeze - end - - def location - @location ||= Location.new(*token[0]) - end - - def type - token[1] - end - - def string - token[2] - end - - def ==(other) - token == other.token - end - - alias_method :eql?, :== - - def inspect - "#<#{self.class} #{type} #{string.inspect}>" - end - - def keyword? - type == :on_kw - end - - def equals_operator? - type == :on_op && string == '=' - end - - def opening? - opening_delimiter? || opening_keyword? - end - - def closed_by?(other) - delimiter_closed_by?(other) || keyword_closed_by?(other) - end - - private - - def opening_delimiter? - CLOSING_TYPES_BY_OPENING_TYPE.key?(type) - end - - def opening_keyword? - return false unless keyword? - CLOSING_KEYWORDS_BY_OPENING_KEYWORD.key?(string) - end - - def delimiter_closed_by?(other) - other.type == CLOSING_TYPES_BY_OPENING_TYPE[type] - end - - def keyword_closed_by?(other) - return false unless keyword? - return true if other.string == CLOSING_KEYWORDS_BY_OPENING_KEYWORD[string] - - # Ruby 3's `end`-less method definition: `def method_name = body` - string == 'def' && other.equals_operator? && location.line == other.location.line - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb deleted file mode 100644 index 5468cf9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -require 'rspec/support' -require 'rspec/support/spec/in_sub_process' - -RSpec::Support.require_rspec_support "spec/deprecation_helpers" -RSpec::Support.require_rspec_support "spec/diff_helpers" -RSpec::Support.require_rspec_support "spec/with_isolated_stderr" -RSpec::Support.require_rspec_support "spec/stderr_splitter" -RSpec::Support.require_rspec_support "spec/formatting_support" -RSpec::Support.require_rspec_support "spec/with_isolated_directory" -RSpec::Support.require_rspec_support "ruby_features" - -warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr) - -RSpec.configure do |c| - c.include RSpecHelpers - c.include RSpec::Support::WithIsolatedStdErr - c.include RSpec::Support::FormattingSupport - c.include RSpec::Support::InSubProcess - - unless defined?(Debugger) # debugger causes warnings when used - c.before do - warning_preventer.reset! - end - - c.after do - warning_preventer.verify_no_warnings! - end - end - - if c.files_to_run.one? - c.full_backtrace = true - c.default_formatter = 'doc' - end - - c.filter_run_when_matching :focus - - c.example_status_persistence_file_path = "./spec/examples.txt" - - c.define_derived_metadata :failing_on_windows_ci do |meta| - meta[:pending] ||= "This spec fails on Windows CI and needs someone to fix it." - end if RSpec::Support::OS.windows? && ENV['CI'] -end - -module RSpec - module Support - module Spec - def self.setup_simplecov(&block) - # Simplecov emits some ruby warnings when loaded, so silence them. - old_verbose, $VERBOSE = $VERBOSE, false - - return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3' - return if RUBY_ENGINE != 'ruby' || RSpec::Support::OS.windows? - - # Don't load it when we're running a single isolated - # test file rather than the whole suite. - return if RSpec.configuration.files_to_run.one? - - require 'simplecov' - start_simplecov(&block) - rescue LoadError - warn "Simplecov could not be loaded" - ensure - $VERBOSE = old_verbose - end - - def self.start_simplecov(&block) - SimpleCov.start do - add_filter "bundle/" - add_filter "tmp/" - add_filter do |source_file| - # Filter out `spec` directory except when it is under `lib` - # (as is the case in rspec-support) - source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/') - end - - instance_eval(&block) if block - end - end - private_class_method :start_simplecov - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb deleted file mode 100644 index f7458c3..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/deprecation_helpers.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -module RSpecHelpers - def expect_deprecation_with_call_site(file, line, snippet=//) - expect(RSpec.configuration.reporter).to receive(:deprecation). - with(include(:deprecated => match(snippet), :call_site => include([file, line].join(':')))) - end - - def expect_deprecation_without_call_site(snippet=//) - expect(RSpec.configuration.reporter).to receive(:deprecation). - with(include(:deprecated => match(snippet), :call_site => eq(nil))) - end - - def expect_warn_deprecation_with_call_site(file, line, snippet=//) - expect(RSpec.configuration.reporter).to receive(:deprecation). - with(include(:message => match(snippet), :call_site => include([file, line].join(':')))) - end - - def expect_warn_deprecation(snippet=//) - expect(RSpec.configuration.reporter).to receive(:deprecation). - with(include(:message => match(snippet))) - end - - def allow_deprecation - allow(RSpec.configuration.reporter).to receive(:deprecation) - end - - def expect_no_deprecations - expect(RSpec.configuration.reporter).not_to receive(:deprecation) - end - alias expect_no_deprecation expect_no_deprecations - - def expect_warning_without_call_site(expected=//) - expect(::Kernel).to receive(:warn). - with(match(expected).and(satisfy { |message| !(/Called from/ =~ message) })) - end - - def expect_warning_with_call_site(file, line, expected=//) - expect(::Kernel).to receive(:warn). - with(match(expected).and(match(/Called from #{file}:#{line}/))) - end - - def expect_no_warnings - expect(::Kernel).not_to receive(:warn) - end - - def allow_warning - allow(::Kernel).to receive(:warn) - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb deleted file mode 100644 index 58e0712..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/diff_helpers.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -require 'diff/lcs' - -module RSpec - module Support - module Spec - module DiffHelpers - # In the updated version of diff-lcs several diff headers change format slightly - # compensate for this and change minimum version in RSpec 4 - if ::Diff::LCS::VERSION.to_f < 1.4 - def one_line_header(line_number=2) - "-1,#{line_number} +1,#{line_number}" - end - elsif ::Diff::LCS::VERSION.to_f < 1.6 - def one_line_header(_=2) - "-1 +1" - end - else - def one_line_header(line_number=2) - if line_number - 1 == 1 - "-1 +1" - else - "-1,#{line_number - 1} +1,#{line_number - 1}" - end - end - end - - if ::Diff::LCS::VERSION.to_f > 1.5 - def removing_two_line_header - "-1,2 +0,0" - end - elsif Diff::LCS::VERSION.to_f < 1.4 || Diff::LCS::VERSION >= "1.4.4" - def removing_two_line_header - "-1,3 +1" - end - else - def removing_two_line_header - "-1,3 +1,5" - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb deleted file mode 100644 index a773a20..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/formatting_support.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - module FormattingSupport - def dedent(string) - string.gsub(/^\s+\|/, '').chomp - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb deleted file mode 100644 index 4130225..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/in_sub_process.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - module InSubProcess - if Process.respond_to?(:fork) && !(Ruby.jruby? && RUBY_VERSION == '1.8.7') - - UnmarshableObject = Struct.new(:error) - - # Useful as a way to isolate a global change to a subprocess. - - def in_sub_process(prevent_warnings=true) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize - exception_reader, exception_writer = IO.pipe - result_reader, result_writer = IO.pipe - - # Set binary mode to avoid errors surrounding ascii-8bit to utf-8 conversion - # this happens with warnings on rspec-rails for example - [exception_reader, exception_writer, result_reader, result_writer].each { |io| io.binmode } - - pid = Process.fork do - warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr) - - begin - result = yield - warning_preventer.verify_no_warnings! if prevent_warnings - # rubocop:disable Lint/HandleExceptions - rescue Support::AllExceptionsExceptOnesWeMustNotRescue => exception - # rubocop:enable Lint/HandleExceptions - end - - exception_writer.write marshal_dump_with_unmarshable_object_handling(exception) - exception_reader.close - exception_writer.close - - result_writer.write marshal_dump_with_unmarshable_object_handling(result) - result_reader.close - result_writer.close - - exit! # prevent at_exit hooks from running (e.g. minitest) - end - - exception_writer.close - result_writer.close - Process.waitpid(pid) - - exception = Marshal.load(exception_reader.read) - exception_reader.close - raise exception if exception - - result = Marshal.load(result_reader.read) - result_reader.close - result - end - alias :in_sub_process_if_possible :in_sub_process - - def marshal_dump_with_unmarshable_object_handling(object) - Marshal.dump(object) - rescue TypeError => error - Marshal.dump(UnmarshableObject.new(error)) - end - else - def in_sub_process(*) - skip "This spec requires forking to work properly, " \ - "and your platform does not support forking" - end - - def in_sub_process_if_possible(*) - yield - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb deleted file mode 100644 index d424525..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/library_wide_checks.rb +++ /dev/null @@ -1,152 +0,0 @@ -# frozen_string_literal: true - -require 'rspec/support/spec/shell_out' - -module RSpec - module Support - module WhitespaceChecks - # This malformed whitespace detection logic has been borrowed from bundler: - # https://github.com/bundler/bundler/blob/v1.8.0/spec/quality_spec.rb - def check_for_tab_characters(filename) - failing_lines = [] - File.readlines(filename).each_with_index do |line, number| - failing_lines << number + 1 if line =~ /\t/ - end - - return if failing_lines.empty? - "#{filename} has tab characters on lines #{failing_lines.join(', ')}" - end - - def check_for_extra_spaces(filename) - failing_lines = [] - File.readlines(filename).each_with_index do |line, number| - next if line =~ /^\s+#.*\s+\n$/ - failing_lines << number + 1 if line =~ /\s+\n$/ - end - - return if failing_lines.empty? - "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}" - end - end - end -end - -RSpec.shared_examples_for "library wide checks" do |lib, options| - consider_a_test_env_file = options.fetch(:consider_a_test_env_file, /MATCHES NOTHING/) - allowed_loaded_feature_regexps = options.fetch(:allowed_loaded_feature_regexps, []) - preamble_for_lib = options[:preamble_for_lib] - preamble_for_spec = "require 'rspec/core'; require 'spec_helper'" - skip_spec_files = options.fetch(:skip_spec_files, /MATCHES NOTHING/) - - include RSpec::Support::ShellOut - include RSpec::Support::WhitespaceChecks - - define_method :files_to_require_for do |sub_dir| - slash = File::SEPARATOR - lib_path_re = /#{slash + lib}[^#{slash}]*#{slash}lib/ - load_path = $LOAD_PATH.grep(lib_path_re).first - directory = load_path.sub(/lib$/, sub_dir) - files = Dir["#{directory}/**/*.rb"] - extract_regex = /#{Regexp.escape(directory) + File::SEPARATOR}(.+)\.rb$/ - - # We sort to ensure the files are loaded in a consistent order, regardless - # of OS. Otherwise, it could load in a different order on Travis than - # locally, and potentially trigger a "circular require considered harmful" - # warning or similar. - files.sort.map { |file| file[extract_regex, 1] } - end - - def command_from(code_lines) - code_lines.join("\n") - end - - def load_all_files(files, preamble, postamble=nil) - requires = files.map { |f| "require '#{f}'" } - command = command_from(Array(preamble) + requires + Array(postamble)) - - stdout, stderr, status = with_env 'NO_COVERAGE' => '1' do - options = %w[ -w ] - options << "--disable=gem" if RUBY_VERSION.to_f >= 1.9 && RSpec::Support::Ruby.mri? - run_ruby_with_current_load_path(command, *options) - end - - [stdout, strip_known_warnings(stderr), status.exitstatus] - end - - define_method :load_all_lib_files do - files = all_lib_files - lib_test_env_files - preamble = ['orig_loaded_features = $".dup', preamble_for_lib] - postamble = ['puts(($" - orig_loaded_features).join("\n"))'] - - @loaded_feature_lines, stderr, exitstatus = load_all_files(files, preamble, postamble) - ["", stderr, exitstatus] - end - - define_method :load_all_spec_files do - files = files_to_require_for("spec") + lib_test_env_files - files = files.reject { |f| f =~ skip_spec_files } - load_all_files(files, preamble_for_spec) - end - - attr_reader :all_lib_files, :lib_test_env_files, - :lib_file_results, :spec_file_results - - before(:context) do - @all_lib_files = files_to_require_for("lib") - @lib_test_env_files = all_lib_files.grep(consider_a_test_env_file) - - @lib_file_results, @spec_file_results = [ - # Load them in parallel so it's faster... - Thread.new { load_all_lib_files }, - Thread.new { load_all_spec_files } - ].map(&:join).map(&:value) - end - - def have_successful_no_warnings_output - eq ["", "", 0] - end - - it "issues no warnings when loaded", :slow do - expect(lib_file_results).to have_successful_no_warnings_output - end - - it "issues no warnings when the spec files are loaded", :slow do - expect(spec_file_results).to have_successful_no_warnings_output - end - - it 'only loads a known set of stdlibs so gem authors are forced ' \ - 'to load libs they use to have passing specs', :slow do - loaded_features = @loaded_feature_lines.split("\n") - if RUBY_VERSION == '1.8.7' - # On 1.8.7, $" returns the relative require path if that was used - # to require the file. LIB_REGEX will not match the relative version - # since it has a `/lib` prefix. Here we deal with this by expanding - # relative files relative to the $LOAD_PATH dir (lib). - Dir.chdir("lib") { loaded_features.map! { |f| File.expand_path(f) } } - end - - loaded_features.reject! { |feature| RSpec::CallerFilter::LIB_REGEX =~ feature } - loaded_features.reject! { |feature| allowed_loaded_feature_regexps.any? { |r| r =~ feature } } - - expect(loaded_features).to eq([]) - end - - RSpec::Matchers.define :be_well_formed do - match do |actual| - actual.empty? - end - - failure_message do |actual| - actual.join("\n") - end - end - - it "has no malformed whitespace", :slow do - error_messages = [] - `git ls-files -z`.split("\x0").each do |filename| - error_messages << check_for_tab_characters(filename) - error_messages << check_for_extra_spaces(filename) - end - expect(error_messages.compact).to be_well_formed - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb deleted file mode 100644 index 3727c8a..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/shell_out.rb +++ /dev/null @@ -1,115 +0,0 @@ -# frozen_string_literal: true - -require 'open3' -require 'rake/file_utils' -require 'shellwords' - -module RSpec - module Support - module ShellOut - def with_env(vars) - original = ENV.to_hash - vars.each { |k, v| ENV[k] = v } - - begin - yield - ensure - ENV.replace(original) - end - end - - if Open3.respond_to?(:capture3) # 1.9+ - def shell_out(*command) - stdout, stderr, status = Open3.capture3(*command) - return stdout, filter(stderr), status - end - else # 1.8.7 - # popen3 doesn't provide the exit status so we fake it out. - FakeProcessStatus = Struct.new(:exitstatus) - - def shell_out(*command) - stdout = stderr = nil - - Open3.popen3(*command) do |_in, out, err| - stdout = out.read - stderr = err.read - end - - status = FakeProcessStatus.new(0) - return stdout, filter(stderr), status - end - end - - def run_ruby_with_current_load_path(ruby_command, *flags) - command = [ - FileUtils::RUBY, - "-I#{$LOAD_PATH.map(&:shellescape).join(File::PATH_SEPARATOR)}", - "-e", ruby_command, *flags - ] - - # Unset these env vars because `ruby -w` will issue warnings whenever - # they are set to non-default values. - with_env 'RUBY_GC_HEAP_FREE_SLOTS' => nil, 'RUBY_GC_MALLOC_LIMIT' => nil, - 'RUBY_FREE_MIN' => nil do - shell_out(*command) - end - end - - LINES_TO_IGNORE = - [ - # Ignore bundler warning. - %r{bundler/source/rubygems}, - # Ignore bundler + rubygems warning. - %r{site_ruby/\d\.\d\.\d/rubygems}, - %r{site_ruby/\d\.\d\.\d/bundler}, - %r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/rubygems}, - %r{lib/rubygems/custom_require}, - # This is required for windows for some reason - %r{lib/bundler/rubygems}, - # This is a JRuby file that generates warnings on 9.0.3.0 - %r{lib/ruby/stdlib/jar}, - # This is a JRuby file that generates warnings on 9.1.7.0 - %r{org/jruby/RubyKernel\.java}, - # This is a JRuby gem that generates warnings on 9.1.7.0 - %r{ffi-1\.13\.\d+-java}, - %r{uninitialized constant FFI}, - # These are related to the above, there is a warning about io from FFI - %r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/io}, - %r{io/console on JRuby shells out to stty for most operations}, - # This is a JRuby 9.1.17.0 error on Github Actions - %r{io/console not supported; tty will not be manipulated}, - # This is a JRuby 9.2.1.x error - %r{jruby/kernel/gem_prelude}, - %r{lib/jruby\.jar!/jruby/preludes}, - # Ignore some JRuby errors for gems - %r{jruby/\d\.\d(\.\d)?/gems/aruba}, - %r{jruby/\d\.\d(\.\d)?/gems/ffi}, - %r{warning: encoding options not supported in 1\.8}, - # Ignore errors from asdf - %r{\.asdf/installs}, - ] - - def strip_known_warnings(input) - input.split("\n").reject do |l| - LINES_TO_IGNORE.any? { |to_ignore| l =~ to_ignore } || - # Remove blank lines - l == "" || l.nil? - end.join("\n") - end - - private - - if Ruby.jruby? - def filter(output) - output.each_line.reject do |line| - line.include?("lib/ruby/shared/rubygems") - end.join($/) - end - else - def filter(output) - output - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb deleted file mode 100644 index 9caa34c..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/stderr_splitter.rb +++ /dev/null @@ -1,77 +0,0 @@ -# frozen_string_literal: true - -require 'stringio' - -module RSpec - module Support - class StdErrSplitter - def initialize(original) - @orig_stderr = original - @output_tracker = ::StringIO.new - @last_line = nil - end - - respond_to_name = (::RUBY_VERSION.to_f < 1.9) ? :respond_to? : :respond_to_missing? - define_method respond_to_name do |*args| - @orig_stderr.respond_to?(*args) || super(*args) - end - - def method_missing(name, *args, &block) - @output_tracker.__send__(name, *args, &block) if @output_tracker.respond_to?(name) - @orig_stderr.__send__(name, *args, &block) - end - - def ==(other) - @orig_stderr == other - end - - def reopen(*args) - reset! - @orig_stderr.reopen(*args) - end - - # To work around JRuby error: - # can't convert RSpec::Support::StdErrSplitter into String - def to_io - @orig_stderr.to_io - end - - # To work around JRuby error: - # TypeError: $stderr must have write method, RSpec::StdErrSplitter given - def write(line) - return if line =~ %r{^\S+/gems/\S+:\d+: warning:} # http://rubular.com/r/kqeUIZOfPG - - # Ruby 2.7.0 warnings from keyword arguments span multiple lines, extend check above - # to look for the next line. - return if @last_line =~ %r{^\S+/gems/\S+:\d+: warning:} && - line =~ %r{warning: The called method .* is defined here} - - # Ruby 2.7.0 complains about hashes used in place of keyword arguments - # Aruba 0.14.2 uses this internally triggering that here - return if line =~ %r{lib/ruby/2\.7\.0/fileutils\.rb:622: warning:} - - @orig_stderr.write(line) - @output_tracker.write(line) - ensure - @last_line = line - end - - def has_output? - !output.empty? - end - - def reset! - @output_tracker = ::StringIO.new - end - - def verify_no_warnings! - raise "Warnings were generated: #{output}" if has_output? - reset! - end - - def output - @output_tracker.string - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb deleted file mode 100644 index b8c0c71..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/string_matcher.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require 'rspec/matchers' -# Special matcher for comparing encoded strings so that -# we don't run any expectation failures through the Differ, -# which also relies on EncodedString. Instead, confirm the -# strings have the same bytes. -RSpec::Matchers.define :be_identical_string do |expected| - if String.method_defined?(:encoding) - match do - expected_encoding? && - actual.bytes.to_a == expected.bytes.to_a - end - - failure_message do - "expected\n#{actual.inspect} (#{actual.encoding.name}) to be identical to\n"\ - "#{expected.inspect} (#{expected.encoding.name})\n"\ - "The exact bytes are printed below for more detail:\n"\ - "#{actual.bytes.to_a}\n"\ - "#{expected.bytes.to_a}\n"\ - end - - # Depends on chaining :with_same_encoding for it to - # check for string encoding. - def expected_encoding? - if defined?(@expect_same_encoding) && @expect_same_encoding - actual.encoding == expected.encoding - else - true - end - end - else - match do - actual.split(//) == expected.split(//) - end - - failure_message do - "expected\n#{actual.inspect} to be identical to\n#{expected.inspect}\n" - end - end - - chain :with_same_encoding do - @expect_same_encoding ||= true - end -end -RSpec::Matchers.alias_matcher :a_string_identical_to, :be_identical_string -RSpec::Matchers.alias_matcher :be_diffed_as, :be_identical_string diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb deleted file mode 100644 index f81a7df..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_directory.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require 'tmpdir' - -RSpec.shared_context "isolated directory" do - around do |ex| - Dir.mktmpdir do |tmp_dir| - Dir.chdir(tmp_dir, &ex) - end - end -end - -RSpec.configure do |c| - c.include_context "isolated directory", :isolated_directory => true -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb deleted file mode 100644 index ef62be4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/spec/with_isolated_stderr.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - module WithIsolatedStdErr - def with_isolated_stderr - original = $stderr - $stderr = StringIO.new - yield - ensure - $stderr = original - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb deleted file mode 100644 index 20db6c7..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module RSpec - module Support - module Version - STRING = '3.13.6' - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb deleted file mode 100644 index 31783d9..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/warnings.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -require 'rspec/support' -RSpec::Support.require_rspec_support "caller_filter" - -module RSpec - module Support - module Warnings - def deprecate(deprecated, options={}) - warn_with "DEPRECATION: #{deprecated} is deprecated.", options - end - - # @private - # - # Used internally to print deprecation warnings - # when rspec-core isn't loaded - def warn_deprecation(message, options={}) - warn_with "DEPRECATION: \n #{message}", options - end - - # @private - # - # Used internally to print warnings - def warning(text, options={}) - warn_with "WARNING: #{text}.", options - end - - # @private - # - # Used internally to print longer warnings - def warn_with(message, options={}) - call_site = options.fetch(:call_site) { CallerFilter.first_non_rspec_line } - message += " Use #{options[:replacement]} instead." if options[:replacement] - message += " Called from #{call_site}." if call_site - Support.warning_notifier.call message - end - end - end - - extend RSpec::Support::Warnings -end diff --git a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb b/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb deleted file mode 100644 index bec99f4..0000000 --- a/vendor/bundle/ruby/3.2.0/gems/rspec-support-3.13.6/lib/rspec/support/with_keywords_when_needed.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -RSpec::Support.require_rspec_support("method_signature_verifier") - -module RSpec - module Support - module WithKeywordsWhenNeeded - # This module adds keyword sensitive support for core ruby methods - # where we cannot use `ruby2_keywords` directly. - - module_function - - if RSpec::Support::RubyFeatures.kw_args_supported? - # Remove this in RSpec 4 in favour of explicitly passed in kwargs where - # this is used. Works around a warning in Ruby 2.7 - - def class_exec(klass, *args, &block) - if MethodSignature.new(block).has_kw_args_in?(args) - binding.eval(<<-CODE, __FILE__, __LINE__) - kwargs = args.pop - klass.class_exec(*args, **kwargs, &block) - CODE - else - klass.class_exec(*args, &block) - end - end - ruby2_keywords :class_exec if respond_to?(:ruby2_keywords, true) - else - def class_exec(klass, *args, &block) - klass.class_exec(*args, &block) - end - end - end - end -end diff --git a/vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec b/vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec deleted file mode 100644 index 7574737..0000000 --- a/vendor/bundle/ruby/3.2.0/specifications/diff-lcs-1.6.2.gemspec +++ /dev/null @@ -1,35 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: diff-lcs 1.6.2 ruby lib - -Gem::Specification.new do |s| - s.name = "diff-lcs".freeze - s.version = "1.6.2" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/halostatue/diff-lcs/issues", "changelog_uri" => "https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md", "homepage_uri" => "https://github.com/halostatue/diff-lcs", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/halostatue/diff-lcs" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Austin Ziegler".freeze] - s.date = "2025-05-12" - s.description = "Diff::LCS computes the difference between two Enumerable sequences using the\nMcIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities\nto create a simple HTML diff output format and a standard diff-like tool.\n\nThis is release 1.6.1, providing a simple extension that allows for\nDiff::LCS::Change objects to be treated implicitly as arrays and fixes a number\nof formatting issues.\n\nRuby versions below 2.5 are soft-deprecated, which means that older versions are\nno longer part of the CI test suite. If any changes have been introduced that\nbreak those versions, bug reports and patches will be accepted, but it will be\nup to the reporter to verify any fixes prior to release. The next major release\nwill completely break compatibility.".freeze - s.email = ["halostatue@gmail.com".freeze] - s.executables = ["htmldiff".freeze, "ldiff".freeze] - s.extra_rdoc_files = ["CHANGELOG.md".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "CONTRIBUTORS.md".freeze, "LICENCE.md".freeze, "Manifest.txt".freeze, "README.md".freeze, "SECURITY.md".freeze, "docs/COPYING.txt".freeze, "docs/artistic.txt".freeze] - s.files = ["CHANGELOG.md".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "CONTRIBUTORS.md".freeze, "LICENCE.md".freeze, "Manifest.txt".freeze, "README.md".freeze, "SECURITY.md".freeze, "bin/htmldiff".freeze, "bin/ldiff".freeze, "docs/COPYING.txt".freeze, "docs/artistic.txt".freeze] - s.homepage = "https://github.com/halostatue/diff-lcs".freeze - s.licenses = ["MIT".freeze, "Artistic-1.0-Perl".freeze, "GPL-2.0-or-later".freeze] - s.rdoc_options = ["--main".freeze, "README.md".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 1.8".freeze) - s.rubygems_version = "3.4.20".freeze - s.summary = "Diff::LCS computes the difference between two Enumerable sequences using the McIlroy-Hunt longest common subsequence (LCS) algorithm".freeze - - s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version - - s.specification_version = 4 - - s.add_development_dependency(%q.freeze, ["~> 4.0"]) - s.add_development_dependency(%q.freeze, ["~> 2.0"]) - s.add_development_dependency(%q.freeze, ["~> 1.0"]) - s.add_development_dependency(%q.freeze, [">= 2.0", "< 4"]) - s.add_development_dependency(%q.freeze, [">= 10.0", "< 14"]) - s.add_development_dependency(%q.freeze, [">= 6.3.1", "< 7"]) -end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec deleted file mode 100644 index 2c8c519..0000000 --- a/vendor/bundle/ruby/3.2.0/specifications/rake-13.3.1.gemspec +++ /dev/null @@ -1,26 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: rake 13.3.1 ruby lib - -Gem::Specification.new do |s| - s.name = "rake".freeze - s.version = "13.3.1" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/ruby/rake/issues", "changelog_uri" => "https://github.com/ruby/rake/releases", "documentation_uri" => "https://ruby.github.io/rake", "source_code_uri" => "https://github.com/ruby/rake" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Hiroshi SHIBATA".freeze, "Eric Hodel".freeze, "Jim Weirich".freeze] - s.bindir = "exe".freeze - s.date = "1980-01-02" - s.description = "Rake is a Make-like program implemented in Ruby. Tasks and dependencies are\nspecified in standard Ruby syntax.\nRake has the following features:\n * Rakefiles (rake's version of Makefiles) are completely defined in standard Ruby syntax.\n No XML files to edit. No quirky Makefile syntax to worry about (is that a tab or a space?)\n * Users can specify tasks with prerequisites.\n * Rake supports rule patterns to synthesize implicit tasks.\n * Flexible FileLists that act like arrays but know about manipulating file names and paths.\n * Supports parallel execution of tasks.\n".freeze - s.email = ["hsbt@ruby-lang.org".freeze, "drbrain@segment7.net".freeze, "".freeze] - s.executables = ["rake".freeze] - s.files = ["exe/rake".freeze] - s.homepage = "https://github.com/ruby/rake".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--main".freeze, "README.rdoc".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 2.3".freeze) - s.rubygems_version = "3.4.20".freeze - s.summary = "Rake is a Make-like program implemented in Ruby".freeze - - s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version -end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec deleted file mode 100644 index 0c94086..0000000 --- a/vendor/bundle/ruby/3.2.0/specifications/rspec-3.13.2.gemspec +++ /dev/null @@ -1,31 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: rspec 3.13.2 ruby lib - -Gem::Specification.new do |s| - s.name = "rspec".freeze - s.version = "3.13.2" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/tree/rspec-v3.13.2/rspec" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Myron Marston".freeze] - s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] - s.date = "1980-01-02" - s.description = "BDD for Ruby".freeze - s.email = "rspec@googlegroups.com".freeze - s.extra_rdoc_files = ["README.md".freeze] - s.files = ["README.md".freeze] - s.homepage = "https://rspec.info".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--charset=UTF-8".freeze] - s.rubygems_version = "3.4.20".freeze - s.summary = "rspec-3.13.2".freeze - - s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version - - s.specification_version = 4 - - s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) - s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) - s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) -end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec deleted file mode 100644 index 8bd860e..0000000 --- a/vendor/bundle/ruby/3.2.0/specifications/rspec-core-3.13.6.gemspec +++ /dev/null @@ -1,31 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: rspec-core 3.13.6 ruby lib - -Gem::Specification.new do |s| - s.name = "rspec-core".freeze - s.version = "3.13.6" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-core-v3.13.6/rspec-core/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-core-v3.13.6/rspec-core" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Chad Humphries".freeze, "Myron Marston".freeze] - s.bindir = "exe".freeze - s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] - s.date = "1980-01-02" - s.description = "BDD for Ruby. RSpec runner and example groups.".freeze - s.email = "rspec@googlegroups.com".freeze - s.executables = ["rspec".freeze] - s.files = ["exe/rspec".freeze] - s.homepage = "https://rspec.info".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--charset=UTF-8".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) - s.rubygems_version = "3.4.20".freeze - s.summary = "rspec-core-3.13.6".freeze - - s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version - - s.specification_version = 4 - - s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) -end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec deleted file mode 100644 index 780aba2..0000000 --- a/vendor/bundle/ruby/3.2.0/specifications/rspec-expectations-3.13.5.gemspec +++ /dev/null @@ -1,29 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: rspec-expectations 3.13.5 ruby lib - -Gem::Specification.new do |s| - s.name = "rspec-expectations".freeze - s.version = "3.13.5" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-expectations-v3.13.5/rspec-expectations/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-expectations-v3.13.5/rspec-expectations" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Myron Marston".freeze] - s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] - s.date = "1980-01-02" - s.description = "rspec-expectations provides a simple, readable API to express expected outcomes of a code example.".freeze - s.email = "rspec@googlegroups.com".freeze - s.homepage = "https://rspec.info".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--charset=UTF-8".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) - s.rubygems_version = "3.4.20".freeze - s.summary = "rspec-expectations-3.13.5".freeze - - s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version - - s.specification_version = 4 - - s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) - s.add_runtime_dependency(%q.freeze, [">= 1.2.0", "< 2.0"]) -end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec deleted file mode 100644 index cc6a2a8..0000000 --- a/vendor/bundle/ruby/3.2.0/specifications/rspec-mocks-3.13.7.gemspec +++ /dev/null @@ -1,29 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: rspec-mocks 3.13.7 ruby lib - -Gem::Specification.new do |s| - s.name = "rspec-mocks".freeze - s.version = "3.13.7" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-mocks-v3.13.7/rspec-mocks/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-mocks-v3.13.7/rspec-mocks" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Steven Baker".freeze, "David Chelimsky".freeze, "Myron Marston".freeze] - s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] - s.date = "1980-01-02" - s.description = "RSpec's 'test double' framework, with support for stubbing and mocking".freeze - s.email = "rspec@googlegroups.com".freeze - s.homepage = "https://rspec.info".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--charset=UTF-8".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) - s.rubygems_version = "3.4.20".freeze - s.summary = "rspec-mocks-3.13.7".freeze - - s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version - - s.specification_version = 4 - - s.add_runtime_dependency(%q.freeze, ["~> 3.13.0"]) - s.add_runtime_dependency(%q.freeze, [">= 1.2.0", "< 2.0"]) -end diff --git a/vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec b/vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec deleted file mode 100644 index a7a859f..0000000 --- a/vendor/bundle/ruby/3.2.0/specifications/rspec-support-3.13.6.gemspec +++ /dev/null @@ -1,29 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: rspec-support 3.13.6 ruby lib - -Gem::Specification.new do |s| - s.name = "rspec-support".freeze - s.version = "3.13.6" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/rspec/rspec/issues", "changelog_uri" => "https://github.com/rspec/rspec/blob/rspec-support-v3.13.6/rspec-support/Changelog.md", "documentation_uri" => "https://rspec.info/documentation/", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rspec", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/rspec/rspec/blob/rspec-support-v3.13.6/rspec-support" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["David Chelimsky".freeze, "Myron Marson".freeze, "Jon Rowe".freeze, "Sam Phippen".freeze, "Xaviery Shay".freeze, "Bradley Schaefer".freeze] - s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIFvjCCA6agAwIBAgIJAPXjfUbCjdXVMA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO\nMAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B\nCQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMjUwMjA2MTE0NjU2WhcNMjYw\nMjA2MTE0NjU2WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x\nEDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl\nYy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC\nIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI\nKMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C\ne/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0\ntQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc\n6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo\nmLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ\nefLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO\ns3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7\nXeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK\nblXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC\ngpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u\n2FUsqZbbJcCmkBrGposCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMA0GCSqGSIb3DQEBCwUAA4IC\nAQBGBr0ll2yLrkO6IeK5Q7qZFnANaUCKfi6Of9VztZJXgKAU5KAQxyOidGktoA5N\nlp+bFKudRkW8jSehqoNaNBdSZ9Bc07EGMXIhUFJZF9rq7Z2SKPwUm6EaSsBK13QR\nU4K6wuaw5ZJSFzklapoGOJRGnFlnNtlhNFY6+tTwCeblwZbcuYGyGY8+Rg7GbyVl\n3Tr4Gi1aS/qG/MDXKdE8HWm39dmaAMdbw6dg1VBd0JrX2VqH7xvE1dM/D3OlKrNp\ngNFRNJig3Y8qPjocZR0cGkhgZoC9wribWxHSNawZm4CoV3fja2HNx9QyM7BaB+as\nyuqAiBbA7vBcyc8nKATip3mxbyXYXoDD7nmO8JCPP7O/WsgG+U/B2a0kPdvYFoxE\nQ0Js3GtFCuMvL+0rifqdxBOLtu0Pw9q4RvToTJIl2IR6eTgCb82B1hw9qKf7PjuL\nBoEsYjjDhGw6FZvcJG8O6uj7aB+z4aF21YR74UGL7sq/RIPNNez5JI95jTGfqCPy\n6yo0w3zja3yg28QK3Fj+tbOHeSLv9SDQWi/1jiPprGzbxGvbVvjvX11YZc46vkmY\nAwP+qZPPf97FXXZGEGIYhhHpnj+Ltx9nCetRPiZ4rvYBcXgCWVQSg6eiEofrMwn/\nAKMCABhZ1Y2eATsfMgdkmIZk7JIPZiSi6eUxPiCMP9M/pw==\n-----END CERTIFICATE-----\n".freeze] - s.date = "1980-01-02" - s.description = "Support utilities for RSpec gems".freeze - s.email = "rspec-users@rubyforge.org".freeze - s.homepage = "https://rspec.info".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--charset=UTF-8".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) - s.rubygems_version = "3.4.20".freeze - s.summary = "rspec-support-3.13.6".freeze - - s.installed_by_version = "3.4.20" if s.respond_to? :installed_by_version - - s.specification_version = 4 - - s.add_development_dependency(%q.freeze, ["> 10.0.0"]) - s.add_development_dependency(%q.freeze, ["~> 1.1.0"]) -end