Spectus

Build Status Coverage Status Dependency Status Gem Version Inline docs Documentation License

An expectation library with some built-in matchers for Ruby.

Contact

Rubies

Spectus is supported by Ruby (MRI) 2+.

Installation

Add this line to your application's Gemfile:

gem 'spectus'

And then execute:

$ bundle

Or install it yourself as:

$ gem install spectus

Why would I want this library?

  • It's ~200 lines of fast and KISS code.
  • Atomic state transitions, immutable objects, thread-safe.
  • Generic and consistent DSL for assertions.

API

The Spectus DSL provides the expect method. It takes a block parameter and responds to:

  • to(definition)
  • not_to(definition)

Then it returns true, false, or a cached exception.

Usage

class Duck
  def walks
    "Klop klop!"
  end

  def swims
    "Swoosh..."
  end

  def quacks
    puts "Quaaaaaack!"
  end
end

@bird = Duck.new

When I see a #<Duck:0x007f96b285d6d0> that ...

require 'spectus'
extend Spectus::DSL

expectation_1 = expect { @bird.walks  }.to eql: "Klop klop!"
expectation_2 = expect { @bird.swims  }.to eql: "Swoosh..."
expectation_3 = expect { @bird.quacks }.to capture_stdout: "Quaaaaaack!\n"
expectation_4 = expect { @bird.speaks }.to raise_exception: NoMethodError

case (expectation_1 == true &&
      expectation_2 == true &&
      expectation_3 == true &&
      expectation_4 == true)
  when true then puts "I call that #{@bird} a duck."
  else warn 'WAT?'
end

I call that #<Duck:0x007f96b285d6d0> a duck.

Built-in matchers

Standard error

expect { warn 'foo' }.to capture_stderr: "foo\n" # => true

Standard output

expect { puts 'foo' }.to capture_stdout: "foo\n" # => true

Equivalence

expect { 'foo' }.to eql: 'foo' # => true

Identity

expect { :foo }.to equal: :foo # => true

Regular expressions

expect { 'foo' }.to({match: /^foo$/}) # => true

Expecting errors

expect { Foo }.to raise_exception: NameError # => true

Custom matchers

Custom matchers can also be defined for expressing expectations.

Be prime

The following expression...

require 'prime'
expect { Prime.prime? 42 }.to equal: false # => true

...could be refactored into:

expect { 42 }.not_to :be_prime # => true

It can be done with this custom matcher:

require 'prime'

module Spectus
  module Matcher
    class BePrime
      def matches?
        Prime.prime? yield
      end
    end
  end
end

Be the answer

The following expression...

expect { 42 }.to equal: 42 # => true

...could be refactored into:

expect { 42 }.to :be_the_answer # => true

It can be done with this custom matcher:

module Spectus
  module Matcher
    class BeTheAnswer
      def matches?
        42.equal? yield
      end
    end
  end
end

Start with

The following expression...

expect { 'foobar' }.to match: /^foo/ # => true

...could be refactored into:

expect { 'foobar' }.to start_with: 'foo' # => true

It can be done with this custom matcher:

module Spectus
  module Matcher
    class StartWith
      def initialize expected
        @expected = expected
      end

      def matches?
        !Regexp.new("^#{@expected}").match(yield).nil?
      end
    end
  end
end

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Versioning

Spectus follows Semantic Versioning 2.0

© 2014 Cyril Wack