From 750159c226bae2ba61d4705cc46ed7a65e02353f Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Tue, 30 Jul 2024 05:36:38 -0400 Subject: [PATCH 1/3] Implement RSpec::SleepingKingStudios::Sandbox. --- CHANGELOG.md | 4 + README.md | 47 ++++ lib/rspec/sleeping_king_studios/sandbox.rb | 79 +++++++ .../sandbox/erroring_examples_spec.fixture.rb | 5 + .../sandbox/failing_examples_spec.fixture.rb | 9 + .../more_passing_examples_spec.fixture.rb | 9 + .../sandbox/passing_examples_spec.fixture.rb | 13 ++ .../sandbox/result_spec.rb | 75 +++++++ .../sleeping_king_studios/sandbox_spec.rb | 203 ++++++++++++++++++ 9 files changed, 444 insertions(+) create mode 100644 lib/rspec/sleeping_king_studios/sandbox.rb create mode 100644 spec/rspec/sleeping_king_studios/sandbox/erroring_examples_spec.fixture.rb create mode 100644 spec/rspec/sleeping_king_studios/sandbox/failing_examples_spec.fixture.rb create mode 100644 spec/rspec/sleeping_king_studios/sandbox/more_passing_examples_spec.fixture.rb create mode 100644 spec/rspec/sleeping_king_studios/sandbox/passing_examples_spec.fixture.rb create mode 100644 spec/rspec/sleeping_king_studios/sandbox/result_spec.rb create mode 100644 spec/rspec/sleeping_king_studios/sandbox_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index a90753a..c0aaa8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ Implemented the `let?` memoized helper, which defines a helper method if there i Implemented deferred examples, which provide an alternative implementation for sharing specifications between projects. +### Sandbox + +Implemented `RSpec::SleepingKingStudios::Sandbox` for running test files in an isolated environment. + ## 2.7.0 ### Concerns diff --git a/README.md b/README.md index 27300a1..09841a3 100644 --- a/README.md +++ b/README.md @@ -1009,6 +1009,53 @@ Creates a value spy that watches the value of a method call or block. The spy al **Chaining:** None. +## Sandbox + +The `RSpec::SleepingKingStudios::Sandbox` module allows for running a spec file or files in an isolated environment and capturing the results. This can be useful for testing code meant to enhance your tests, such as a custom RSpec matcher or a shared example group. + +First, define a spec file to run. As a recommended convention, spec files to be run in a sandbox should be given the `spec.fixture.rb` suffix to ensure they are not accidentally run with the main test suite. + +```ruby +# frozen_string_literal: true + +# In spec/rocket_spec.fixture.rb: +RSpec.describe Rocket do + describe '#launch' do + it 'should launch the rocket' do + expect { subject.launch }.to change(subject, :launched?).to be true + end + end +end +``` + +Defining fixture files rather than generating temporary files is recommended for performance reasons, but both approaches are possible. Once the file is defined, it can be run in a sandbox: + +```ruby +result = RSpec::SleepingKingStudios::Sandbox.run('spec/rocket_spec.fixture.rb') + +result.class #=> RSpec::SleepingKingStudios::Sandbox::Result +result.output #=> """ +# Rocket +# #launch +# should launch the rocket +# +# 1 example, 0 failures +# """ +result.status #=> 1 +result.summary #=> 1 example, 0 failures +result.example_descriptions #=> [ +# 'Rocket#launch should launch the rocket' +# ] +``` + +The `.run` method returns an instance of `RSpec::SleepingKingStudios::Sandbox::Result`, which wraps the result of running the specified spec files. It defines the following methods: + +- `#errors`: The output captured from STDERR when running the files. +- `#example_descriptions`: The full description for each evaluated example. +- `#json`: The json output from running the files. +- `#output`: The output captured from STDOUT when running the files. The specs are run with the `--format=doc` flag, so this will include the individual examples as well as the summary. +- `#summary`: The summary line for the tests. + ## Deferred Examples `RSpec::SleepingKingStudios::Deferred` provides a mechanism for defining specifications that can be reused and shared between projects. For example, a library could use deferred examples to define an interface and test a reference implementation; projects that use that library could then use the published deferred examples to validate their own implementations of that interface. diff --git a/lib/rspec/sleeping_king_studios/sandbox.rb b/lib/rspec/sleeping_king_studios/sandbox.rb new file mode 100644 index 0000000..014cc45 --- /dev/null +++ b/lib/rspec/sleeping_king_studios/sandbox.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require 'stringio' + +require 'rspec/sleeping_king_studios' + +module RSpec::SleepingKingStudios + # Helper for running RSpec files in isolation. + # + # Sandboxed files can be used to test enhancements to RSpec itself, such as + # custom matchers or shared or deferred example groups. + module Sandbox + # Value class for the result of calling a sandboxed spec file. + Result = Struct.new(:output, :errors, :json, :status, keyword_init: true) do + # @return [Array] the full description for each run example. + def example_descriptions + json['examples'].map { |hsh| hsh['full_description'] } + end + + # @return [String] the summary of the sandboxed spec run. + def summary + json['summary_line'] + end + end + + class << self + # Runs the specified spec files in a sandbox. + # + # The examples and other RSpec code in the files will *not* be added to + # the current RSpec process. + # + # @param files [Array] the file names or patterns for the spec + # files to run. + # + # @return [RSpec::SleepingKingStudios::Result] the status and output of + # the spec run. + def run(*files) # rubocop:disable Metrics/MethodLength + if files.empty? + raise ArgumentError, 'must specify at least one file or pattern' + end + + err = StringIO.new + out = StringIO.new + status = nil + args = format_args(*files) + + RSpec::Core::Sandbox.sandboxed do |config| + config.filter_run_when_matching :focus + + status = RSpec::Core::Runner.run(args, err, out) + end + + build_result(err:, out:, status:) + end + + private + + def build_result(err:, out:, status:) + *output, raw_json = out.string.lines + + Result.new( + output: output.join, + errors: err.string, + json: JSON.parse(raw_json), + status: + ) + end + + def format_args(*files) + [ + '--format=json', + '--format=doc', + '--order=defined', + "--pattern=#{files.join(',')}" + ] + end + end + end +end diff --git a/spec/rspec/sleeping_king_studios/sandbox/erroring_examples_spec.fixture.rb b/spec/rspec/sleeping_king_studios/sandbox/erroring_examples_spec.fixture.rb new file mode 100644 index 0000000..b79c951 --- /dev/null +++ b/spec/rspec/sleeping_king_studios/sandbox/erroring_examples_spec.fixture.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +RSpec.describe Array do + include_examples 'should be Enumerable' +end diff --git a/spec/rspec/sleeping_king_studios/sandbox/failing_examples_spec.fixture.rb b/spec/rspec/sleeping_king_studios/sandbox/failing_examples_spec.fixture.rb new file mode 100644 index 0000000..2b61259 --- /dev/null +++ b/spec/rspec/sleeping_king_studios/sandbox/failing_examples_spec.fixture.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +RSpec.describe TrueClass do + it { expect(true).to be nil } + + it { expect(true).to be false } + + it { expect(true).to be true } +end diff --git a/spec/rspec/sleeping_king_studios/sandbox/more_passing_examples_spec.fixture.rb b/spec/rspec/sleeping_king_studios/sandbox/more_passing_examples_spec.fixture.rb new file mode 100644 index 0000000..c781b8b --- /dev/null +++ b/spec/rspec/sleeping_king_studios/sandbox/more_passing_examples_spec.fixture.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +RSpec.describe Hash do + subject { { ok: true } } + + describe '#keys' do + it { expect(subject.keys).to contain_exactly(:ok) } + end +end diff --git a/spec/rspec/sleeping_king_studios/sandbox/passing_examples_spec.fixture.rb b/spec/rspec/sleeping_king_studios/sandbox/passing_examples_spec.fixture.rb new file mode 100644 index 0000000..4ea48ce --- /dev/null +++ b/spec/rspec/sleeping_king_studios/sandbox/passing_examples_spec.fixture.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +RSpec.describe Array do + subject { %i[one two three] } + + describe '#count' do + it { expect(subject.count).to be 3 } + end + + describe '#empty?' do + it { expect(subject.empty?).to be false } + end +end diff --git a/spec/rspec/sleeping_king_studios/sandbox/result_spec.rb b/spec/rspec/sleeping_king_studios/sandbox/result_spec.rb new file mode 100644 index 0000000..7c6876c --- /dev/null +++ b/spec/rspec/sleeping_king_studios/sandbox/result_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'rspec/sleeping_king_studios/examples/property_examples' +require 'rspec/sleeping_king_studios/sandbox' + +RSpec.describe RSpec::SleepingKingStudios::Sandbox::Result do + include RSpec::SleepingKingStudios::Examples::PropertyExamples + + subject(:result) do + described_class.new( + errors:, + json:, + output:, + status: + ) + end + + let(:output) do + <<~OUTPUT + Spec::Models::Rocket + #launch + should launch the rocket + should set the launch site + OUTPUT + end + let(:errors) { '' } + let(:status) { 0 } + let(:json) do + # rubocop:disable RSpec/LineLength + { + 'examples' => [ + { + 'full_description' => 'Spec::Models::Rocket#launch should launch the rocket', + }, + { + 'full_description' => 'Spec::Models::Rocket#launch should set the launch site', + }, + ], + 'summary_line' => '2 examples, 0 failures' + } + # rubocop:enable RSpec/LineLength + end + + describe '#errors' do + include_examples 'should define reader', :errors, -> { errors } + end + + describe '#example_descriptions' do + let(:expected) do + json['examples'].map { |hsh| hsh['full_description'] } + end + + include_examples 'should define reader', + :example_descriptions, + -> { expected } + end + + describe '#json' do + include_examples 'should define reader', :json, -> { json } + end + + describe '#output' do + include_examples 'should define reader', :output, -> { output } + end + + describe '#status' do + include_examples 'should define reader', :status, -> { status } + end + + describe '#summary' do + let(:expected) { json['summary_line'] } + + include_examples 'should define reader', :summary, -> { expected } + end +end diff --git a/spec/rspec/sleeping_king_studios/sandbox_spec.rb b/spec/rspec/sleeping_king_studios/sandbox_spec.rb new file mode 100644 index 0000000..91e47e9 --- /dev/null +++ b/spec/rspec/sleeping_king_studios/sandbox_spec.rb @@ -0,0 +1,203 @@ +# frozen_string_literal: true + +require 'rspec/sleeping_king_studios/sandbox' + +RSpec.describe RSpec::SleepingKingStudios::Sandbox do + describe '.run' do + shared_examples 'should return a result' do + it { expect(result).to be_a described_class::Result } + + it { expect(result.output.strip).to start_with(expected_output) } + + it { expect(result.errors).to be == expected_errors } + + it { expect(result.status).to be == expected_status } + + it { expect(result.summary).to be == expected_summary } + + it { expect(result.example_descriptions).to be == expected_examples } + end + + let(:expected_output) { '' } + let(:expected_summary) { '' } + let(:expected_errors) { '' } + let(:expected_examples) { [] } + let(:expected_status) { 0 } + let(:files) { [] } + let(:result) { described_class.run(*files) } + + it 'should define the class method' do + expect(described_class) + .to respond_to(:run) + .with_unlimited_arguments + end + + describe 'with an empty Array' do + let(:error_message) do + 'must specify at least one file or pattern' + end + + it 'should raise an exception' do + expect { described_class.run } + .to raise_error ArgumentError, error_message + end + end + + describe 'with a pattern that does not match any files' do + let(:files) { ['tmp/invalid_spec.xyz'] } + let(:expected_output) { 'No examples found.' } + let(:expected_summary) { '0 examples, 0 failures' } + + include_examples 'should return a result' + end + + describe 'with a pattern that matches a file with erroring examples' do + let(:files) do + # rubocop:disable Layout/LineLength + [ + 'spec/rspec/sleeping_king_studios/sandbox/erroring_examples_spec.fixture.rb' + ] + # rubocop:enable Layout/LineLength + end + let(:expected_output) { 'An error occurred while loading' } + let(:expected_summary) do + '0 examples, 0 failures, 1 error occurred outside of examples' + end + let(:expected_status) { 1 } + + include_examples 'should return a result' + end + + describe 'with a pattern that matches a file with failing examples' do + let(:files) do + # rubocop:disable Layout/LineLength + [ + 'spec/rspec/sleeping_king_studios/sandbox/failing_examples_spec.fixture.rb' + ] + # rubocop:enable Layout/LineLength + end + let(:expected_output) do + <<~OUTPUT + TrueClass + is expected to equal nil (FAILED - 1) + is expected to equal false (FAILED - 2) + is expected to equal true + OUTPUT + end + let(:expected_examples) do + [ + 'TrueClass is expected to equal nil', + 'TrueClass is expected to equal false', + 'TrueClass is expected to equal true' + ] + end + let(:expected_summary) do + '3 examples, 2 failures' + end + let(:expected_status) { 1 } + + include_examples 'should return a result' + end + + describe 'with a pattern that matches a file with passing examples' do + let(:files) do + # rubocop:disable Layout/LineLength + [ + 'spec/rspec/sleeping_king_studios/sandbox/passing_examples_spec.fixture.rb' + ] + # rubocop:enable Layout/LineLength + end + let(:expected_output) do + <<~OUTPUT + Array + #count + is expected to equal 3 + #empty? + is expected to equal false + OUTPUT + end + let(:expected_examples) do + [ + 'Array#count is expected to equal 3', + 'Array#empty? is expected to equal false' + ] + end + let(:expected_summary) do + '2 examples, 0 failures' + end + + include_examples 'should return a result' + end + + describe 'with a pattern that matches multiple files' do + let(:files) do + # rubocop:disable Layout/LineLength + [ + 'spec/rspec/sleeping_king_studios/sandbox/*passing_examples_spec.fixture.rb' + ] + # rubocop:enable Layout/LineLength + end + let(:expected_output) do + <<~OUTPUT + Hash + #keys + is expected to contain exactly :ok + + Array + #count + is expected to equal 3 + #empty? + is expected to equal false + OUTPUT + end + let(:expected_examples) do + [ + 'Hash#keys is expected to contain exactly :ok', + 'Array#count is expected to equal 3', + 'Array#empty? is expected to equal false' + ] + end + let(:expected_summary) do + '3 examples, 0 failures' + end + + include_examples 'should return a result' + end + + describe 'with multiple file patterns' do + let(:files) do + # rubocop:disable Layout/LineLength + [ + 'spec/rspec/sleeping_king_studios/sandbox/more_passing_examples_spec.fixture.rb', + 'spec/rspec/sleeping_king_studios/sandbox/passing_examples_spec.fixture.rb' + ] + # rubocop:enable Layout/LineLength + end + let(:expected_output) do + <<~OUTPUT + Hash + #keys + is expected to contain exactly :ok + + Array + #count + is expected to equal 3 + #empty? + is expected to equal false + OUTPUT + end + let(:expected_examples) do + [ + 'Hash#keys is expected to contain exactly :ok', + 'Array#count is expected to equal 3', + 'Array#empty? is expected to equal false' + ] + end + let(:expected_summary) do + '3 examples, 0 failures' + end + + include_examples 'should return a result' + end + end +end From 45dff32b5102fcaf642ffb7ba372f76f9d0fd3c2 Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Tue, 30 Jul 2024 06:04:09 -0400 Subject: [PATCH 2/3] Fix RuboCop configuration. --- .rubocop.yml | 5 ++++- lib/rspec/sleeping_king_studios.rb | 1 + spec/integration/deferred/custom_spec.fixture.rb | 2 +- spec/integration/deferred/example_groups_spec.fixture.rb | 2 +- spec/integration/deferred/examples_spec.fixture.rb | 2 +- spec/integration/deferred/helpers_spec.fixture.rb | 2 +- spec/integration/deferred/hooks_inheritance_spec.fixture.rb | 2 +- spec/integration/deferred/hooks_ordering_spec.fixture.rb | 2 +- spec/integration/deferred/inheritance_spec.fixture.rb | 2 +- spec/integration/deferred/missing_spec.fixture.rb | 2 +- spec/integration/deferred/optional_helpers_spec.fixture.rb | 2 +- .../deferred/parameterized_focused_spec.fixture.rb | 2 +- .../deferred/parameterized_skipped_spec.fixture.rb | 2 +- spec/integration/deferred/shared_examples_spec.fixture.rb | 2 +- spec/integration/deferred/wrapped_contexts_spec.fixture.rb | 4 ++-- 15 files changed, 19 insertions(+), 15 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fcca24f..41903ef 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -16,6 +16,7 @@ AllCops: - lib/rspec/sleeping_king_studios/configuration.rb - lib/rspec/sleeping_king_studios/deferred.rb - lib/rspec/sleeping_king_studios/deferred/**/* + - lib/rspec/sleeping_king_studios/sandbox.rb - lib/rspec/sleeping_king_studios/version.rb - spec/rspec/configuration_spec.rb - spec/integration/concerns/**/* @@ -24,10 +25,11 @@ AllCops: - spec/rspec/sleeping_king_studios/concerns/memoized_helpers_spec.rb - spec/rspec/sleeping_king_studios/configuration_spec.rb - spec/rspec/sleeping_king_studios/deferred/**/* + - lib/rspec/sleeping_king_studios/sandbox_spec.rb + - lib/rspec/sleeping_king_studios/sandbox/**/* - spec/rspec/sleeping_king_studios/support/shared_examples/deferred_call_examples.rb - spec/spec_helper.rb - spec/support/integration/**/*.rb - - spec/support/sandbox.rb - '*.thor' Exclude: - 'tmp/**/*' @@ -38,6 +40,7 @@ RSpec: - '**/*_examples.rb' - '**/*_contract.rb' - '**/*_spec.rb' + - '**/*_spec.fixture.rb' Layout/ArgumentAlignment: EnforcedStyle: with_fixed_indentation diff --git a/lib/rspec/sleeping_king_studios.rb b/lib/rspec/sleeping_king_studios.rb index 77c6a45..47689ea 100644 --- a/lib/rspec/sleeping_king_studios.rb +++ b/lib/rspec/sleeping_king_studios.rb @@ -7,6 +7,7 @@ module RSpec module SleepingKingStudios autoload :Concerns, 'rspec/sleeping_king_studios/concerns' autoload :Deferred, 'rspec/sleeping_king_studios/deferred' + autoload :Sandbox, 'rspec/sleeping_king_studios/sandbox' # @return [String] the path to the installed gem. def self.gem_path diff --git a/spec/integration/deferred/custom_spec.fixture.rb b/spec/integration/deferred/custom_spec.fixture.rb index e81ac84..15cdb3a 100644 --- a/spec/integration/deferred/custom_spec.fixture.rb +++ b/spec/integration/deferred/custom_spec.fixture.rb @@ -3,7 +3,7 @@ require 'support/integration/deferred/program_examples' require 'support/models/rocket' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup class << self alias_method :custom_example, :specify diff --git a/spec/integration/deferred/example_groups_spec.fixture.rb b/spec/integration/deferred/example_groups_spec.fixture.rb index 01c5f7a..74ae813 100644 --- a/spec/integration/deferred/example_groups_spec.fixture.rb +++ b/spec/integration/deferred/example_groups_spec.fixture.rb @@ -3,7 +3,7 @@ require 'support/integration/deferred/launch_examples' require 'support/models/rocket' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup subject(:rocket) { described_class.new('Imp IV') } include Spec::Integration::Deferred::LaunchExamples diff --git a/spec/integration/deferred/examples_spec.fixture.rb b/spec/integration/deferred/examples_spec.fixture.rb index c8da043..23ff636 100644 --- a/spec/integration/deferred/examples_spec.fixture.rb +++ b/spec/integration/deferred/examples_spec.fixture.rb @@ -6,7 +6,7 @@ RSpec.describe Spec::Models::Rocket do subject(:rocket) { described_class.new('Imp IV') } - describe '#name' do + describe '#name' do # rubocop:disable RSpec/EmptyExampleGroup include Spec::Integration::Deferred::NamingExamples end end diff --git a/spec/integration/deferred/helpers_spec.fixture.rb b/spec/integration/deferred/helpers_spec.fixture.rb index 390c1d4..f81679e 100644 --- a/spec/integration/deferred/helpers_spec.fixture.rb +++ b/spec/integration/deferred/helpers_spec.fixture.rb @@ -2,7 +2,7 @@ require 'support/integration/deferred/payload_examples' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup subject(:rocket) { described_class.new('Imp IV') } include Spec::Integration::Deferred::PayloadExamples diff --git a/spec/integration/deferred/hooks_inheritance_spec.fixture.rb b/spec/integration/deferred/hooks_inheritance_spec.fixture.rb index 7d5b8ec..21b4917 100644 --- a/spec/integration/deferred/hooks_inheritance_spec.fixture.rb +++ b/spec/integration/deferred/hooks_inheritance_spec.fixture.rb @@ -2,6 +2,6 @@ require 'support/integration/deferred/hooks_inheritance_examples' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup include Spec::Integration::Deferred::HooksInheritanceExamples end diff --git a/spec/integration/deferred/hooks_ordering_spec.fixture.rb b/spec/integration/deferred/hooks_ordering_spec.fixture.rb index 97a9650..6c5383c 100644 --- a/spec/integration/deferred/hooks_ordering_spec.fixture.rb +++ b/spec/integration/deferred/hooks_ordering_spec.fixture.rb @@ -2,6 +2,6 @@ require 'support/integration/deferred/hooks_ordering_examples' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup include Spec::Integration::Deferred::HooksOrderingExamples end diff --git a/spec/integration/deferred/inheritance_spec.fixture.rb b/spec/integration/deferred/inheritance_spec.fixture.rb index 64758e6..b031b8f 100644 --- a/spec/integration/deferred/inheritance_spec.fixture.rb +++ b/spec/integration/deferred/inheritance_spec.fixture.rb @@ -3,7 +3,7 @@ require 'support/integration/deferred/rocket_examples' require 'support/models/rocket' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup subject(:rocket) { described_class.new('Imp IV') } let(:expected_type) { :rocket } diff --git a/spec/integration/deferred/missing_spec.fixture.rb b/spec/integration/deferred/missing_spec.fixture.rb index cd4ce90..4b1c7ce 100644 --- a/spec/integration/deferred/missing_spec.fixture.rb +++ b/spec/integration/deferred/missing_spec.fixture.rb @@ -3,7 +3,7 @@ require 'support/integration/deferred/ordinal_examples' require 'support/models/rocket' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup class << self alias_method :custom_example, :specify diff --git a/spec/integration/deferred/optional_helpers_spec.fixture.rb b/spec/integration/deferred/optional_helpers_spec.fixture.rb index 4984c24..9c3d52c 100644 --- a/spec/integration/deferred/optional_helpers_spec.fixture.rb +++ b/spec/integration/deferred/optional_helpers_spec.fixture.rb @@ -2,7 +2,7 @@ require 'support/integration/deferred/orbit_examples' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup subject(:rocket) { described_class.new('Imp IV') } include Spec::Integration::Deferred::OrbitExamples diff --git a/spec/integration/deferred/parameterized_focused_spec.fixture.rb b/spec/integration/deferred/parameterized_focused_spec.fixture.rb index f1b6b43..d313a03 100644 --- a/spec/integration/deferred/parameterized_focused_spec.fixture.rb +++ b/spec/integration/deferred/parameterized_focused_spec.fixture.rb @@ -10,7 +10,7 @@ finclude_deferred 'should be a SpaceVehicle' - fwrap_deferred 'should behave like a rocket' + fwrap_deferred 'should behave like a rocket' # rubocop:disable RSpec/Focus it { expect(rocket.type).to be :submarine } end diff --git a/spec/integration/deferred/parameterized_skipped_spec.fixture.rb b/spec/integration/deferred/parameterized_skipped_spec.fixture.rb index e78ef02..8bdbc9f 100644 --- a/spec/integration/deferred/parameterized_skipped_spec.fixture.rb +++ b/spec/integration/deferred/parameterized_skipped_spec.fixture.rb @@ -10,5 +10,5 @@ xinclude_deferred 'should be a SpaceVehicle' - xwrap_deferred 'should behave like a rocket' + xwrap_deferred 'should behave like a rocket' # rubocop:disable RSpec/PendingWithoutReason end diff --git a/spec/integration/deferred/shared_examples_spec.fixture.rb b/spec/integration/deferred/shared_examples_spec.fixture.rb index 9369911..1e03135 100644 --- a/spec/integration/deferred/shared_examples_spec.fixture.rb +++ b/spec/integration/deferred/shared_examples_spec.fixture.rb @@ -2,7 +2,7 @@ require 'support/integration/deferred/crew_examples' -RSpec.describe Spec::Models::Rocket do +RSpec.describe Spec::Models::Rocket do # rubocop:disable RSpec/EmptyExampleGroup subject(:rocket) { described_class.new('Imp IV') } include Spec::Integration::Deferred::CrewExamples diff --git a/spec/integration/deferred/wrapped_contexts_spec.fixture.rb b/spec/integration/deferred/wrapped_contexts_spec.fixture.rb index dd745ef..ae88d49 100644 --- a/spec/integration/deferred/wrapped_contexts_spec.fixture.rb +++ b/spec/integration/deferred/wrapped_contexts_spec.fixture.rb @@ -24,11 +24,11 @@ end context 'when the rocket has multiple payloads' do + let(:expected_payload) { { booster: true, satellite: true } } + include_deferred 'when the payload includes a booster' include_deferred 'when the payload includes a satellite' - let(:expected_payload) { { booster: true, satellite: true } } - it { expect(rocket.payload).to be == expected_payload } end end From b6d1d996f81664c026e3335a3f1a0a649f533f9b Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Tue, 30 Jul 2024 14:40:49 -0400 Subject: [PATCH 3/3] Remove legacy Sandbox implementation. --- lib/rspec/sleeping_king_studios/sandbox.rb | 2 + spec/integration/deferred/custom_spec.rb | 4 +- .../deferred/example_groups_spec.rb | 4 +- spec/integration/deferred/examples_spec.rb | 4 +- spec/integration/deferred/helpers_spec.rb | 4 +- .../deferred/hooks_inheritance_spec.rb | 3 +- .../deferred/hooks_ordering_spec.rb | 3 +- spec/integration/deferred/inheritance_spec.rb | 4 +- spec/integration/deferred/missing_spec.rb | 4 +- .../deferred/optional_helpers_spec.rb | 4 +- .../deferred/parameterized_examples_spec.rb | 4 +- .../deferred/parameterized_focused_spec.rb | 4 +- .../deferred/parameterized_skipped_spec.rb | 4 +- .../deferred/shared_examples_spec.rb | 4 +- .../deferred/wrapped_contexts_spec.rb | 4 +- spec/support/sandbox.rb | 46 ------------------- 16 files changed, 16 insertions(+), 86 deletions(-) delete mode 100644 spec/support/sandbox.rb diff --git a/lib/rspec/sleeping_king_studios/sandbox.rb b/lib/rspec/sleeping_king_studios/sandbox.rb index 014cc45..def22a1 100644 --- a/lib/rspec/sleeping_king_studios/sandbox.rb +++ b/lib/rspec/sleeping_king_studios/sandbox.rb @@ -2,6 +2,8 @@ require 'stringio' +require 'rspec/core/sandbox' + require 'rspec/sleeping_king_studios' module RSpec::SleepingKingStudios diff --git a/spec/integration/deferred/custom_spec.rb b/spec/integration/deferred/custom_spec.rb index 9bd04f8..d264d08 100644 --- a/spec/integration/deferred/custom_spec.rb +++ b/spec/integration/deferred/custom_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/custom_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/example_groups_spec.rb b/spec/integration/deferred/example_groups_spec.rb index 8beffae..84d7830 100644 --- a/spec/integration/deferred/example_groups_spec.rb +++ b/spec/integration/deferred/example_groups_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/example_groups_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/examples_spec.rb b/spec/integration/deferred/examples_spec.rb index 117912d..5e8e714 100644 --- a/spec/integration/deferred/examples_spec.rb +++ b/spec/integration/deferred/examples_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/examples_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/helpers_spec.rb b/spec/integration/deferred/helpers_spec.rb index 2f784d8..75e4410 100644 --- a/spec/integration/deferred/helpers_spec.rb +++ b/spec/integration/deferred/helpers_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/helpers_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/hooks_inheritance_spec.rb b/spec/integration/deferred/hooks_inheritance_spec.rb index 932aba7..28dae8a 100644 --- a/spec/integration/deferred/hooks_inheritance_spec.rb +++ b/spec/integration/deferred/hooks_inheritance_spec.rb @@ -3,14 +3,13 @@ require 'rspec/sleeping_king_studios/deferred/examples' require 'support/integration/deferred/hooks_inheritance_examples' -require 'support/sandbox' RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/hooks_inheritance_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:recorded) do Spec::Integration::Deferred::HooksInheritanceExamples::Recorder diff --git a/spec/integration/deferred/hooks_ordering_spec.rb b/spec/integration/deferred/hooks_ordering_spec.rb index 06a8f52..b40c09f 100644 --- a/spec/integration/deferred/hooks_ordering_spec.rb +++ b/spec/integration/deferred/hooks_ordering_spec.rb @@ -3,14 +3,13 @@ require 'rspec/sleeping_king_studios/deferred/examples' require 'support/integration/deferred/hooks_ordering_examples' -require 'support/sandbox' RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/hooks_ordering_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:recorded) do Spec::Integration::Deferred::HooksOrderingExamples::Recorder diff --git a/spec/integration/deferred/inheritance_spec.rb b/spec/integration/deferred/inheritance_spec.rb index 093f26a..7fa437c 100644 --- a/spec/integration/deferred/inheritance_spec.rb +++ b/spec/integration/deferred/inheritance_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/inheritance_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/missing_spec.rb b/spec/integration/deferred/missing_spec.rb index 61eebe4..bc1f593 100644 --- a/spec/integration/deferred/missing_spec.rb +++ b/spec/integration/deferred/missing_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/missing_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/optional_helpers_spec.rb b/spec/integration/deferred/optional_helpers_spec.rb index 1d11e3b..79e18ce 100644 --- a/spec/integration/deferred/optional_helpers_spec.rb +++ b/spec/integration/deferred/optional_helpers_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/optional_helpers_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/parameterized_examples_spec.rb b/spec/integration/deferred/parameterized_examples_spec.rb index 3358716..ad38647 100644 --- a/spec/integration/deferred/parameterized_examples_spec.rb +++ b/spec/integration/deferred/parameterized_examples_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/parameterized_examples_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/parameterized_focused_spec.rb b/spec/integration/deferred/parameterized_focused_spec.rb index 12cc0a8..cb6b040 100644 --- a/spec/integration/deferred/parameterized_focused_spec.rb +++ b/spec/integration/deferred/parameterized_focused_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/parameterized_focused_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/parameterized_skipped_spec.rb b/spec/integration/deferred/parameterized_skipped_spec.rb index 91bc16e..6fff800 100644 --- a/spec/integration/deferred/parameterized_skipped_spec.rb +++ b/spec/integration/deferred/parameterized_skipped_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/parameterized_skipped_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/shared_examples_spec.rb b/spec/integration/deferred/shared_examples_spec.rb index de95163..76f7c90 100644 --- a/spec/integration/deferred/shared_examples_spec.rb +++ b/spec/integration/deferred/shared_examples_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/shared_examples_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/integration/deferred/wrapped_contexts_spec.rb b/spec/integration/deferred/wrapped_contexts_spec.rb index db8ec45..a6a79f9 100644 --- a/spec/integration/deferred/wrapped_contexts_spec.rb +++ b/spec/integration/deferred/wrapped_contexts_spec.rb @@ -2,14 +2,12 @@ require 'rspec/sleeping_king_studios/deferred/examples' -require 'support/sandbox' - RSpec.describe RSpec::SleepingKingStudios::Deferred::Examples do let(:fixture_file) do %w[spec/integration/deferred/wrapped_contexts_spec.fixture.rb] end let(:result) do - Spec::Support::Sandbox.run(fixture_file) + RSpec::SleepingKingStudios::Sandbox.run(fixture_file) end let(:expected_examples) do <<~EXAMPLES.lines.map(&:strip) diff --git a/spec/support/sandbox.rb b/spec/support/sandbox.rb deleted file mode 100644 index 4ce9465..0000000 --- a/spec/support/sandbox.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'stringio' - -require 'rspec/core/sandbox' - -module Spec::Support - module Sandbox - Result = Struct.new(:doc, :errors, :json, :status, keyword_init: true) do - def example_descriptions - json['examples'].map { |hsh| hsh['full_description'] } - end - - def summary - json['summary_line'] - end - end - - def self.run(*files) # rubocop:disable Metrics/MethodLength - err = StringIO.new - out = StringIO.new - status = nil - args = [ - '--format=json', - '--format=doc', - '--order=defined', - "--pattern=#{files.join(',')}" - ] - - RSpec::Core::Sandbox.sandboxed do |config| - config.filter_run_when_matching :focus - - status = RSpec::Core::Runner.run(args, err, out) - end - - *doc, raw_json = out.string.lines - - Result.new( - doc: doc.join, - errors: err.string, - json: JSON.parse(raw_json), - status: - ) - end - end -end