Spectus

Build Status Code Climate Gem Version Inline docs Documentation

Expectation library with RFC 2119's requirement levels 🚥

Installation

Add this line to your application's Gemfile:

gem 'spectus'

And then execute:

$ bundle

Or install it yourself as:

$ gem install spectus

Expectation

An expectation is an assertion that is either true or false.

There are several scenarios:

Requirement levels MUST SHOULD MAY
Implemented & Matched true true true
Implemented & Not matched false true false
Implemented & Exception false false false
Not implemented false false true

Thus,

  • when an expectation is true, a Spectus::Result::Pass instance is returned;
  • when an expectation is false, a Spectus::Result::Fail exception is raised.

Both results share a common interface, and can be classified respectively as:

  • ✅ a success, ⚠️ a warning or 💡 an info;
  • ❌ a failure or 💥 an error.

Code Isolation

When executing expectations, side-effects may occur. Because they may or may not be desired, each requirement level has 2 versions:

  • if it does not end with !, its test is performed without isolation;
  • if it ends with !, its test is performed in isolation.

Example of test without isolation:

include Spectus
greeting = 'Hello, world!'
it { greeting.gsub!('world', 'Alice') }.MUST eql 'Hello, Alice!'
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
greeting # => "Hello, Alice!"

Example of test in isolation:

include Spectus
greeting = 'Hello, world!'
it { greeting.gsub!('world', 'Alice') }.MUST! eql 'Hello, Alice!'
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
greeting # => "Hello, world!"

Usage

To begin with, let's include Spectus:

include Spectus

Absolute Requirement

Given the "ルビー" object, when it receives valid_encoding? method, then it MUST be true:

it { 'ルビー'.valid_encoding? }.MUST be_true
# => Spectus::Result::Pass(actual: true, error: nil, expected: nil, got: true, matcher: :be_true, negate: false, level: :MUST, valid: true)

The result of the test shows that the spec passed.

Absolute Prohibition

Given the "foo" object, when it receives length method, then it MUST NOT raise the NoMethodError exception:

it { 'foo'.length }.MUST_NOT raise_exception NoMethodError
# => Spectus::Result::Pass(actual: 3, error: nil, expected: NoMethodError, got: true, matcher: :raise_exception, negate: true, level: :MUST, valid: true)

The result of the test shows that the spec passed.

Given the BasicObject object, when it receives superclass method, then it SHOULD return the explicit blank class NilClass:

it { BasicObject.superclass }.SHOULD equal NilClass
# => Spectus::Result::Pass(actual: nil, error: nil, expected: NilClass, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)

Instead of the expected NilClass class, its sole instance (which is nil) was returned. However, because there isn't any exception, the result of the test shows that the spec passed.

Given the "1" object, when it receives +(1) method, then it SHOULD NOT return the "11" value:

it { '1' + 1 }.SHOULD_NOT eql '11'
# raise Spectus::Result::Fail(actual: nil, error: #<TypeError: no implicit conversion of Integer into String>, expected: "11", got: nil, matcher: :eql, negate: true, level: :SHOULD, valid: false)

There was a TypeError exception, the result of the test shows that the spec failed.

Optional

Given the "foo" object, when it receives blank? method, then it MAY be false:

it { 'foo'.blank? }.MAY be_false
# => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for "foo":String>, expected: nil, got: nil, matcher: :be_false, negate: false, level: :MAY, valid: false)

The optional blank? method is not implemented (unlike in Ruby on Rails, for instance), so the result of the test shows that the spec passed.

More Examples

A full list of unit tests can be viewed here: test.rb

Contact

Versioning

Spectus follows Semantic Versioning 2.0.

License

The gem is available as open source under the terms of the MIT License.


This project is sponsored by:
Sashite