Skip to content

Commit

Permalink
Implement Deferred::Provider.defined_deferred_examples?
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepingkingstudios committed Aug 29, 2024
1 parent b093c42 commit e4dd4bb
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 2 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,24 @@ RSpec.describe Car do
end
```

Finally, `Deferred::Consumer` includes the shortcuts `#finclude_deferred` and `#fwrap_deferred` to automatically focus deferred examples, or `#xinclude_deferred` and `#xwrap_deferred` to skip deferred examples.
`Deferred::Consumer` also includes the shortcuts `#finclude_deferred` and `#fwrap_deferred` to automatically focus deferred examples, or `#xinclude_deferred` and `#xwrap_deferred` to skip deferred examples.

The `defined_deferred_examples?` and `defined_deferred_context?` methods allow checking for the presence of a deferred example group.

```ruby
RSpec.describe Boat do
include RSpec::SleepingKingStudios::Deferred::Consumer
include VehicleExamples
subject(:boat) { described_class.new }
if defined_deferred_examples?('should be a water Vehicle')
include_deferred 'should be a water Vehicle'
else
pending 'deferred examples "should be a water Vehicle" is not defined'
end
end
```

## Shared Examples

Expand Down
31 changes: 31 additions & 0 deletions lib/rspec/sleeping_king_studios/deferred/provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ def defined_deferred_examples
@defined_deferred_examples ||= {}
end

# Checks if the given deferred example group is defined.
#
# @param description [String] the name of the deferred examples.
#
# @return [true, false] true if a deferred example group with the given
# description is defined in the current context; otherwise false.
def defined_deferred_examples?(description)
ancestors.any? do |ancestor|
next false unless ancestor.respond_to?(:defined_deferred_examples)

ancestor.deferred_definition_exists?(description) ||
ancestor.deferred_module_exists?(description)
end
end
alias defined_deferred_context? defined_deferred_examples?

# @api private
def find_deferred_examples(description)
tools.assertions.validate_name(description, as: 'description')
Expand All @@ -72,6 +88,21 @@ def find_deferred_examples(description)

protected

def deferred_definition_exists?(description)
defined_deferred_examples.key?(description)
end

def deferred_module_exists?(description)
constants(false)
.any? do |const_name|
value = const_get(const_name)

next false unless module_is_deferred_examples?(value)

return true if matches_description?(description, const_name, value)
end
end

def find_deferred_definition(description)
defined_deferred_examples.fetch(description, nil)
end
Expand Down
1 change: 1 addition & 0 deletions spec/rspec/sleeping_king_studios/deferred/provider_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

RSpec.describe RSpec::SleepingKingStudios::Deferred::Provider do
extend RSpec::SleepingKingStudios::Concerns::ExampleConstants
include RSpec::SleepingKingStudios::Matchers::Macros
include Spec::Support::SharedExamples::DeferredRegistryExamples

subject(:registry) { described_class }
Expand Down
89 changes: 88 additions & 1 deletion spec/support/shared_examples/deferred_registry_examples.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# frozen_string_literal: true

require 'rspec/sleeping_king_studios/concerns/shared_example_group'
require 'rspec/sleeping_king_studios/matchers/core/have_aliased_method'

require 'support/shared_examples'

module Spec::Support::SharedExamples
module DeferredRegistryExamples
extend RSpec::SleepingKingStudios::Concerns::SharedExampleGroup
extend RSpec::SleepingKingStudios::Concerns::SharedExampleGroup
include RSpec::SleepingKingStudios::Matchers::Macros

shared_context 'when the parent registry has deferred examples' do
let(:ancestor_deferred_examples) do
Expand Down Expand Up @@ -203,6 +205,91 @@ module DeferredRegistryExamples
end
end

describe '.defined_deferred_examples?' do
it 'should define the class method' do
expect(described_class)
.to respond_to(:defined_deferred_examples?)
.with(1).argument
end

it 'should alias the method' do
expect(described_class)
.to have_aliased_method(:defined_deferred_examples?)
.as(:defined_deferred_context?)
end

describe 'with a non-matching description' do
let(:description) { 'should do nothing' }

it 'should return false' do
expect(described_class.defined_deferred_examples?(description))
.to be false
end
end

context 'when the parent registry has deferred examples' do
include_context 'when the parent registry has deferred examples'

describe 'with a non-matching description' do
let(:description) { 'should do nothing' }

it 'should return false' do
expect(described_class.defined_deferred_examples?(description))
.to be false
end
end

describe 'with a description matching a definition' do
let(:description) { 'should do a thing' }

it 'should return true' do
expect(described_class.defined_deferred_examples?(description))
.to be true
end
end

describe 'with a description matching a module' do
let(:description) { 'should behave like a BasicObject' }

it 'should return true' do
expect(described_class.defined_deferred_examples?(description))
.to be true
end
end
end

context 'when the registry has deferred examples' do
include_context 'when the registry has deferred examples'

describe 'with a non-matching description' do
let(:description) { 'should do nothing' }

it 'should return false' do
expect(described_class.defined_deferred_examples?(description))
.to be false
end
end

describe 'with a description matching a definition' do
let(:description) { 'should do something' }

it 'should return true' do
expect(described_class.defined_deferred_examples?(description))
.to be true
end
end

describe 'with a description matching a module' do
let(:description) { 'should act as expected' }

it 'should return true' do
expect(described_class.defined_deferred_examples?(description))
.to be true
end
end
end
end

describe '.find_deferred_examples' do
it 'should define the class method' do
expect(described_class)
Expand Down

0 comments on commit e4dd4bb

Please sign in to comment.