Skip to content

Commit

Permalink
Add example group methods to Deferred::Examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepingkingstudios committed May 6, 2024
1 parent 45d354d commit 2f15b0b
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 86 deletions.
2 changes: 1 addition & 1 deletion lib/rspec/sleeping_king_studios/deferred/example.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
module RSpec::SleepingKingStudios::Deferred
# Value object representing a deferred RSpec example.
class Example < RSpec::SleepingKingStudios::Deferred::Call
# @return [Symbol, nil] the type of deferred call.
# (see RSpec::SleepingKingStudios::Deferred::Call#type)
def type
:example
end
Expand Down
14 changes: 14 additions & 0 deletions lib/rspec/sleeping_king_studios/deferred/example_group.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

require 'rspec/sleeping_king_studios/deferred'
require 'rspec/sleeping_king_studios/deferred/call'

module RSpec::SleepingKingStudios::Deferred
# Value object representing a deferred RSpec example group.
class ExampleGroup < RSpec::SleepingKingStudios::Deferred::Call
# (see RSpec::SleepingKingStudios::Deferred::Call#type)
def type
:example_group
end
end
end
162 changes: 86 additions & 76 deletions lib/rspec/sleeping_king_studios/deferred/examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

require 'rspec/sleeping_king_studios/deferred'
require 'rspec/sleeping_king_studios/deferred/example'
require 'rspec/sleeping_king_studios/deferred/example_group'

module RSpec::SleepingKingStudios::Deferred
# Defines a deferred example group for declaring shared tests.
Expand All @@ -13,6 +14,7 @@ module Definitions
# The defined ordering for calling deferred calls by type.
DEFERRED_CALL_ORDERING = %i[
example
example_group
].freeze

ORDERED_TYPES = Set.new(DEFERRED_CALL_ORDERING).freeze
Expand Down Expand Up @@ -42,8 +44,12 @@ def deferred_call_key(deferred_call)
deferred_call.type
end

def empty_ordered_calls
[*DEFERRED_CALL_ORDERING, nil].to_h { |key| [key, []] }
end

def ordered_deferred_calls # rubocop:disable Metrics/MethodLength
ancestors.reduce({}) do |memo, ancestor|
ancestors.reduce(empty_ordered_calls) do |memo, ancestor|
unless ancestor < RSpec::SleepingKingStudios::Deferred::Examples
return memo
end
Expand All @@ -52,7 +58,7 @@ def ordered_deferred_calls # rubocop:disable Metrics/MethodLength
do |deferred_call, calls|
key = deferred_call_key(deferred_call)

(calls[key] ||= []) << deferred_call
calls[key] << deferred_call

calls
end
Expand All @@ -64,26 +70,10 @@ def ordered_deferred_calls # rubocop:disable Metrics/MethodLength
module DSL
include RSpec::SleepingKingStudios::Deferred::Examples::Definitions

# Methods that define a deferred example.
EXAMPLE_METHODS = %i[
example
fexample
fit
focus
fspecify
it
pending
skip
specify
xexample
xit
xspecify
].freeze

class << self
private

def define_deferred_example(method_name)
def define_example_method(method_name)
define_method(method_name) do |*args, **kwargs, &block|
deferred_calls << RSpec::SleepingKingStudios::Deferred::Example.new(
method_name,
Expand All @@ -93,80 +83,100 @@ def define_deferred_example(method_name)
)
end
end

def define_example_group_method(method_name)
define_method(method_name) do |*args, **kwargs, &block|
deferred_calls <<
RSpec::SleepingKingStudios::Deferred::ExampleGroup.new(
method_name,
*args,
**kwargs,
&block
)
end
end
end

# @!macro [new] example_method
# @param doc_string [String] the example's doc string.
# @param flags [Array<Symbol>] metadata flags for the example. Will be
# transformed into metadata entries with true values.
# @param metadata [Hash] metadata for the example.
# @param block [Proc] the implementation of the example.
# @!macro [new] define_example_group_method
# @!method $1(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example group.
#
# @return [void]

# @!method example(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example.
# @param doc_string [String] the example group's doc string.
# @param flags [Array<Symbol>] metadata flags for the example group.
# Will be transformed into metadata entries with true values.
# @param metadata [Hash] metadata for the example group.
# @param block [Proc] the implementation of the example group.
#
# @!macro example_method
# @return [void]

# @!method fexample(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with focus: true.
# @!macro [new] define_example_method
# @!method $1(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example.
#
# @!macro example_method

# @!method fit(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with focus: true.
# @param doc_string [String] the example's doc string.
# @param flags [Array<Symbol>] metadata flags for the example. Will be
# transformed into metadata entries with true values.
# @param metadata [Hash] metadata for the example.
# @param block [Proc] the implementation of the example.
#
# @!macro example_method
# @return [void]

# @!method focus(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with focus: true.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :example

# @!method fspecify(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with focus: true.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :fexample

# @!method example(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :fit

# @!method pending(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with pending: true.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :focus

# @!method skip(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with skip: true.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :fspecify

# @!method specify(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :it

# @!method xexample(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with skip: 'Temporarily skipped ...'.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :pending

# @!method xit(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with skip: 'Temporarily skipped ...'.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :skip

# @!method xspecify(doc_string = nil, *flags, **metadata, &block)
# Defines a deferred example with skip: 'Temporarily skipped ...'.
#
# @!macro example_method
# @!macro define_example_method
define_example_method :specify

EXAMPLE_METHODS.each do |method_name|
define_deferred_example(method_name)
end
# @!macro define_example_method
define_example_method :xexample

# @!macro define_example_method
define_example_method :xit

# @!macro define_example_method
define_example_method :xspecify

# @!macro define_example_group_method
define_example_group_method :context

# @!macro define_example_group_method
define_example_group_method :describe

# @!macro define_example_group_method
define_example_group_method :example_group

# @!macro define_example_group_method
define_example_group_method :fcontext

# @!macro define_example_group_method
define_example_group_method :fdescribe

# @!macro define_example_group_method
define_example_group_method :xcontext

# @!macro define_example_group_method
define_example_group_method :xdescribe
end

# Callback invoked when the module is included in another module or class.
Expand Down
7 changes: 7 additions & 0 deletions spec/rspec/sleeping_king_studios/deferred/call_spec.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# frozen_string_literal: true

require 'rspec/sleeping_king_studios/concerns/example_constants'
require 'rspec/sleeping_king_studios/deferred/call'

require 'support/shared_examples/deferred_call_examples'

RSpec.describe RSpec::SleepingKingStudios::Deferred::Call do
extend RSpec::SleepingKingStudios::Concerns::ExampleConstants
include Spec::Support::SharedExamples::DeferredCallExamples

subject(:deferred) do
Expand All @@ -15,6 +17,11 @@
let(:arguments) { [] }
let(:keywords) { {} }
let(:block) { nil }
let(:receiver) { instance_double(Spec::Rocket, launch: nil) }

example_class 'Spec::Rocket' do |klass|
klass.define_method(:launch) { |*, **| nil }
end

include_examples 'should be a deferred call'

Expand Down
31 changes: 31 additions & 0 deletions spec/rspec/sleeping_king_studios/deferred/example_group_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

require 'rspec/sleeping_king_studios/concerns/example_constants'
require 'rspec/sleeping_king_studios/deferred/example_group'

require 'support/shared_examples/deferred_call_examples'

RSpec.describe RSpec::SleepingKingStudios::Deferred::ExampleGroup do
extend RSpec::SleepingKingStudios::Concerns::ExampleConstants
include Spec::Support::SharedExamples::DeferredCallExamples

subject(:deferred) do
described_class.new(method_name, *arguments, **keywords, &block)
end

let(:method_name) { :describe }
let(:arguments) { [] }
let(:keywords) { {} }
let(:block) { nil }
let(:receiver) { instance_double(Spec::ExampleGroup, describe: nil) }

example_class 'Spec::ExampleGroup' do |klass|
klass.define_method(:describe) { |*, **| nil }
end

include_examples 'should be a deferred call'

describe '#type' do
it { expect(deferred.type).to be :example_group }
end
end
9 changes: 8 additions & 1 deletion spec/rspec/sleeping_king_studios/deferred/example_spec.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
# frozen_string_literal: true

require 'rspec/sleeping_king_studios/concerns/example_constants'
require 'rspec/sleeping_king_studios/deferred/example'

require 'support/shared_examples/deferred_call_examples'

RSpec.describe RSpec::SleepingKingStudios::Deferred::Example do
extend RSpec::SleepingKingStudios::Concerns::ExampleConstants
include Spec::Support::SharedExamples::DeferredCallExamples

subject(:deferred) do
described_class.new(method_name, *arguments, **keywords, &block)
end

let(:method_name) { :launch }
let(:method_name) { :specify }
let(:arguments) { [] }
let(:keywords) { {} }
let(:block) { nil }
let(:receiver) { instance_double(Spec::ExampleGroup, specify: nil) }

example_class 'Spec::ExampleGroup' do |klass|
klass.define_method(:specify) { |*, **| nil }
end

include_examples 'should be a deferred call'

Expand Down
Loading

0 comments on commit 2f15b0b

Please sign in to comment.