Class: RSpec::Dsl

Inherits:
Object
  • Object
show all
Defined in:
lib/r_spec/dsl.rb

Overview

Abstract class for handling the domain-specific language.

Class Method Summary collapse

Class Method Details

.after(&block) ⇒ Object

Executes the given block after each spec in the current context runs.

Examples:

require "r_spec"

RSpec.describe Integer do
  after do
    puts "That is the answer to everything."
  end

  it { expect(42).to be 42 }
end

# Output to the console
#   Success: expected to be 42.
#   That is the answer to everything.

Parameters:

  • block (Proc)

    The content to execute at the class initialization.



73
74
75
76
77
78
79
80
# File 'lib/r_spec/dsl.rb', line 73

def self.after(&block)
  define_method(AFTER_METHOD) do
    instance_exec(&block)
    super()
  end

  private AFTER_METHOD
end

.before(&block) ⇒ Object

Executes the given block before each spec in the current context runs.

Examples:

require "r_spec"

RSpec.describe Integer do
  before do
    @value = 123
  end

  it { expect(@value).to be 123 }

  describe "nested" do
    before do
      @value -= 81
    end

    it { expect(@value).to be 42 }
  end

  it { expect(@value).to be 123 }
end

# Output to the console
#   Success: expected to be 123.
#   Success: expected to be 42.
#   Success: expected to be 123.

Parameters:

  • block (Proc)

    The content to execute at the class initialization.



46
47
48
49
50
51
52
53
# File 'lib/r_spec/dsl.rb', line 46

def self.before(&block)
  define_method(BEFORE_METHOD) do
    super()
    instance_eval(&block)
  end

  private BEFORE_METHOD
end

.context(_description, &block) ⇒ Object

Defines an example group that establishes a specific context, like _empty array_ versus _array with elements_.

Unlike describe, the block is evaluated in isolation in order to scope possible side effects inside its context.

Examples:

require "r_spec"

RSpec.describe "web resource" do
  context "when resource is not found" do
    pending "responds with 404"
  end

  context "when resource is found" do
    pending "responds with 200"
  end
end

# Output to the console
#   Warning: responds with 404.
#   Warning: responds with 200.

Parameters:

  • _description (String)

    A description that usually begins with “when”, “with” or “without”.

  • block (Proc)

    The block to define the specs.



183
184
185
186
# File 'lib/r_spec/dsl.rb', line 183

def self.context(_description, &block)
  desc = ::Class.new(self)
  ::Aw.fork! { desc.instance_eval(&block) }
end

.describe(const, &block) ⇒ Object

Defines an example group that describes a unit to be tested.

Examples:

require "r_spec"

RSpec.describe String do
  describe "+" do
    it("concats") { expect("foo" + "bar").to eq "foobar" }
  end
end

# Output to the console
#   Success: expected to eq "foobar".

Parameters:

  • const (Module, String)

    A module to include in block context.

  • block (Proc)

    The block to define the specs.



151
152
153
154
155
# File 'lib/r_spec/dsl.rb', line 151

def self.describe(const, &block)
  desc = ::Class.new(self)
  desc.let(:described_class) { const } if const.is_a?(::Module)
  desc.instance_eval(&block)
end

.it(_name = nil, &block) ⇒ nil

Defines a concrete test case.

The test is performed by the block supplied to ‘&block`.

It can be used inside a describe or context section.

Examples:

The integer after 41

require "r_spec"

RSpec.describe Integer do
  it { expect(41.next).to be 42 }
end

# Output to the console
#   Success: expected to be 42.

A division by zero

require "r_spec"

RSpec.describe Integer do
  subject { 41 }

  it { is_expected.to be_an_instance_of described_class }

  it "raises an error" do
    expect { subject / 0 }.to raise_exception ZeroDivisionError
  end
end

# Output to the console
#   Success: expected 41 to be an instance of Integer.
#   Success: divided by 0.

Parameters:

  • _name (String, nil) (defaults to: nil)

    The name of the spec.

  • block (Proc)

    An expectation to evaluate.

Returns:

  • (nil)

    Write a message to STDOUT.

Raises:

  • (SystemExit)

    Terminate execution immediately by calling ‘Kernel.exit(false)` with a failure message written to STDERR.



226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/r_spec/dsl.rb', line 226

def self.it(_name = nil, &block)
  raise ::ArgumentError, "Missing example block" unless block

  example = ::Class.new(self) { include ExpectationHelper::It }.new
  example.instance_eval(&block)
rescue ::SystemExit
  Console.source(*block.source_location)

  exit false
ensure
  example&.send(AFTER_METHOD)
end

.its(attribute, *args, **kwargs, &block) ⇒ nil

Use the its method to define a single spec that specifies the actual value of an attribute of the subject using ExpectationHelper::Its#is_expected.

Examples:

The integer after 41

require "r_spec"

RSpec.describe Integer do
  subject { 41 }

  its(:next) { is_expected.to be 42 }
end

# Output to the console
#   Success: expected to be 42.

A division by zero

require "r_spec"

RSpec.describe Integer do
  subject { 41 }

  its(:/, 0) { is_expected.to raise_exception ZeroDivisionError }
end

# Output to the console
#   Success: divided by 0.

A spec without subject

require "r_spec"

RSpec.describe Integer do
  its(:boom) { is_expected.to raise_exception RSpec::Error::UndefinedSubject }
end

# Output to the console
#   Success: subject not explicitly defined.

Parameters:

  • attribute (String, Symbol)

    The property to call to subject.

  • args (Array)

    An optional list of arguments.

  • kwargs (Hash)

    An optional list of keyword arguments.

  • block (Proc)

    An expectation to evaluate.

Returns:

  • (nil)

    Write a message to STDOUT.

Raises:

  • (SystemExit)

    Terminate execution immediately by calling ‘Kernel.exit(false)` with a failure message written to STDERR.



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/r_spec/dsl.rb', line 284

def self.its(attribute, *args, **kwargs, &block)
  raise ::ArgumentError, "Missing example block" unless block

  example = ::Class.new(self) do
    include ExpectationHelper::Its

    define_method(:actual) do
      subject.public_send(attribute, *args, **kwargs)
    end
  end.new

  example.instance_eval(&block)
rescue ::SystemExit
  Console.source(*block.source_location)

  exit false
ensure
  example&.send(AFTER_METHOD)
end

.let(name, *args, **kwargs, &block) ⇒ Symbol

Sets a user-defined property.

Examples:

require "r_spec"

RSpec.describe "Name stories" do
  let(:name) { "Bob" }

  it { expect(name).to eq "Bob" }

  context "with last name" do
    let(:name) { "#{super()} Smith" }

    it { expect(name).to eq "Bob Smith" }
  end
end

# Output to the console
#   Success: expected to eq "Bob".
#   Success: expected to eq "Bob Smith".

Parameters:

  • name (String, Symbol)

    The name of the property.

  • block (Proc)

    The content of the method to define.

Returns:

  • (Symbol)

    A private method that define the block content.

Raises:



107
108
109
110
111
# File 'lib/r_spec/dsl.rb', line 107

def self.let(name, *args, **kwargs, &block)
  raise Error::ReservedMethod if [BEFORE_METHOD, AFTER_METHOD].include?(name.to_sym)

  private define_method(name, *args, **kwargs, &block)
end

.pending(message) ⇒ nil

Defines a pending test case.

‘&block` is never evaluated. It can be used to describe behaviour that is not yet implemented.

Examples:

require "r_spec"

RSpec.describe "an example" do
  pending "is implemented but waiting" do
    expect something to be finished
  end

  pending "is not yet implemented and waiting"
end

# Output to the console
#   Warning: is implemented but waiting.
#   Warning: is not yet implemented and waiting.

Parameters:

  • message (String)

    The reason why the example is pending.

Returns:

  • (nil)

    Write a message to STDOUT.



329
330
331
# File 'lib/r_spec/dsl.rb', line 329

def self.pending(message)
  Console.passed_spec Error::PendingExpectation.result(message)
end

.subject(&block) ⇒ Symbol

Sets a user-defined property named #subject.

Examples:

require "r_spec"

RSpec.describe Array do
  subject { [1, 2, 3] }

  it "has the prescribed elements" do
    expect(subject).to eq([1, 2, 3])
  end
end

# Output to the console
#   Success: expected to eq [1, 2, 3].

Parameters:

  • block (Proc)

    The subject to set.

Returns:

  • (Symbol)

    A #subject method that define the block content.



131
132
133
# File 'lib/r_spec/dsl.rb', line 131

def self.subject(&block)
  let(__method__, &block)
end