module Spectator::DSL::Matchers

Direct including types

Defined in:

spectator/dsl/matchers.cr

Macro Summary

Macro Detail

macro all(matcher) #

Verifies that all elements of a collection satisfy some matcher. The collection should implement Enumerable.

Examples:

array = [1, 2, 3, 4]
expect(array).to all(be_even)  # Fails.
expect(array).to all(be_lt(5)) # Passes.

[View source]
macro be #

Indicates that some value when compared to another satisfies an operator. An operator can follow, such as: <, <=, >, or >=. See Spectator::Matchers::TruthyMatcher for a full list of operators.

Examples:

expect(1 + 1).to be > 1
expect(5).to be >= 3

Additionally, a value can just "be" truthy by omitting an operator.

expect("foo").to be
# is the same as:
expect("foo").to be_truthy

[View source]
macro be(expected) #

Indicates that some object should be the same as another. This checks if two references are the same. The Reference#same? method is used for this check.

Examples:

obj = "foobar"
expect(obj).to be(obj)
expect(obj.dup).to_not be(obj)

[View source]
macro be_a(expected) #

Indicates that some value should be of a specified type. The Object#is_a? method is used for this check. A type name or type union should be used for expected.

Examples:

expect("foo").to be_a(String)

x = Random.rand(2) == 0 ? "foobar" : 5
expect(x).to be_a(Int32 | String)

[View source]
macro be_a_kind_of(expected) #

Indicates that some value should be of a specified type. The Object#is_a? method is used for this check. A type name or type union should be used for expected. This method is identical to #be_a, and exists just to improve grammar.

Examples:

expect(123).to be_a_kind_of(Int)

[View source]
macro be_an(expected) #

Indicates that some value should be of a specified type. The Object#is_a? method is used for this check. A type name or type union should be used for expected. This method is identical to #be_a, and exists just to improve grammar.

Examples:

expect(123).to be_an(Int32)

[View source]
macro be_an_instance_of(expected) #

Indicates that some value should be of a specified type. The value's runtime type is checked. A type name or type union should be used for expected. This method is identical to #be_an_instance_of, and exists just to improve grammar.

Examples:

expect(123).to be_an_instance_of(Int32)

[View source]
macro be_between(min, max) #

Indicates that some value should be between a lower and upper-bound.

Example:

expect(7).to be_between(1, 10)

Additionally, an "inclusive" or "exclusive" suffix can be added. These modify the upper-bound on the range being checked against. By default, the range is inclusive.

Examples:

expect(days).to be_between(28, 31).inclusive # 28, 29, 30, or 31
expect(100).to be_between(97, 101).exclusive # 97, 98, 99, or 100 (not 101)

[View source]
macro be_close(expected, delta) #

Indicates that some value should be within a delta of an expected value.

Example:

expect(pi).to be_close(3.14159265359, 0.0000001)

This is functionally equivalent to:

be_within(expected).of(delta)

[View source]
macro be_empty #

Indicates that some collection should be empty.

Example:

expect([]).to be_empty

[View source]
macro be_false #

Indicates that some value should be false.

Examples:

expect("foo".nil?).to be_false
expect(%i[a b c].empty?).to be_false

[View source]
macro be_falsey #

Indicates that some value should be falsey. This means that the value is either false or nil.

Examples:

expect(false).to be_falsey
expect(nil).to be_falsey

[View source]
macro be_ge(expected) #

Indicates that some value should be greater than or equal to another. The >= operator is used for this check. The value passed to this method is the value expected to be smaller or equal.

Example:

expect(3 + 1).to be_ge(3)

[View source]
macro be_gt(expected) #

Indicates that some value should be greater than another. The > operator is used for this check. The value passed to this method is the value expected to be smaller.

Example:

expect(3 + 1).to be_gt(3)

[View source]
macro be_instance_of(expected) #

Indicates that some value should be of a specified type. The value's runtime type is checked. A type name or type union should be used for expected.

Examples:

expect(123).to be_instance_of(Int32)

[View source]
macro be_kind_of(expected) #

Indicates that some value should be of a specified type. The Object#is_a? method is used for this check. A type name or type union should be used for expected. This method is identical to #be_a, and exists just to improve grammar.

Examples:

expect(123).to be_kind_of(Int)

[View source]
macro be_le(expected) #

Indicates that some value should be less than or equal to another. The <= operator is used for this check. The value passed to this method is the value expected to be larger or equal.

Example:

expect(3 - 1).to be_le(3)

[View source]
macro be_lt(expected) #

Indicates that some value should be less than another. The < operator is used for this check. The value passed to this method is the value expected to be larger.

Example:

expect(3 - 1).to be_lt(3)

[View source]
macro be_nil #

Indicates that some value should or should not be nil.

Examples:

expect(error).to be_nil
expect(input).to_not be_nil

[View source]
macro be_true #

Indicates that some value should be true.

Examples:

expect(nil.nil?).to be_true
expect(%i[a b c].any?).to be_true

[View source]
macro be_truthy #

Indicates that some value should be truthy. This means that the value is not false and not nil.

Examples:

expect(123).to be_truthy
expect(true).to be_truthy

[View source]
macro be_within(expected) #

Indicates that some value should be contained within another. This checker can be used in one of two ways.

The first: the expected argument can be anything that implements the includes? method. This is typically a Range, but can also be Enumerable.

Examples:

expect(:foo).to be_within(%i[foo bar baz])
expect(7).to be_within(1..10)

The other way is to use this is with the "of" keyword. This creates a lower and upper bound centered around the value of the expected argument. This usage is helpful for comparisons on floating-point numbers.

Examples:

expect(50.0).to be_within(0.01).of(50.0)
expect(speed).to be_within(5).of(speed_limit)

NOTE The of suffix must be used if the expected argument does not implement an includes? method.

Additionally, for this second usage, an "inclusive" or "exclusive" suffix can be added. These modify the upper-bound on the range being checked against. By default, the range is inclusive.

Examples:

expect(days).to be_within(1).of(30).inclusive # 29, 30, or 31
expect(100).to be_within(2).of(99).exclusive  # 97, 98, 99, or 100 (not 101)

NOTE Do not attempt to mix the two use cases. It likely won't work and will result in a compilation error.


[View source]
macro change(&expression) #

Indicates that some expression's value should change after taking an action.

Examples:

i = 0
expect { i += 1 }.to change { i }
expect { i += 0 }.to_not change { i }
i = 0
expect { i += 5 }.to change { i }.from(0).to(5)
i = 0
expect { i += 5 }.to change { i }.to(5)
i = 0
expect { i += 5 }.to change { i }.from(0)
i = 0
expect { i += 42 }.to change { i }.by(42)

The block short-hand syntax can be used here. It will reference the current subject.

expect { subject << :foo }.to change(&.size).by(1)

[View source]
macro compile_as(expected) #

Indicates that some value should be of a specified type at compile time. The value's compile time type is checked. This can test is a variable or value returned by a method is inferred to the expected type.

Examples:

value = 42 || "foobar"
expect(value).to compile_as(Int32 | String)

[View source]
macro contain(*expected) #

Indicates that some value or set should contain another value. This is typically used on a String or Array (any Enumerable works). The expected argument can be a String or Char when the actual type (being compared against) is a String. For Enumerable types, items are compared using the underlying implementation. In both cases, the includes? method is used.

Examples:

expect("foobar").to contain("foo")
expect("foobar").to contain('o')
expect(%i[a b c]).to contain(:b)

Additionally, multiple arguments can be specified.

expect("foobarbaz").to contain("foo", "bar")
expect(%i[a b c]).to contain(:a, :b)

[View source]
macro contain_elements(expected) #

Indicates that some value or set should contain specific items. This is typically used on a String or Array (any Enumerable works). The expected argument can be a String or Char when the actual type (being compared against) is a String. For Enumerable types, items are compared using the underlying implementation. In both cases, the includes? method is used.

This is identical to #contain, but accepts an array (or enumerable type) instead of multiple arguments.

Examples:

expect("foobar").to contain_elements(["foo", "bar"])
expect("foobar").to contain_elements(['a', 'b'])
expect(%i[a b c]).to contain_elements(%i[a b])

[View source]
macro contain_exactly(*expected) #

Indicates that some set should contain some values in any order.

Example:

expect([1, 2, 3]).to contain_exactly(3, 2, 1)

[View source]
macro cover(*expected) #

Indicates that some range (or collection) should contain another value. This is typically used on a Range (although any Enumerable works). The includes? method is used.

Examples:

expect(1..10).to contain(5)
expect((1..)).to contain(100)
expect(..100).to contain(50)

Additionally, multiple arguments can be specified.

expect(1..10).to contain(2, 3)
expect(..100).to contain(0, 50)

[View source]
macro end_with(expected) #

Indicates that some value or set should end with another value. This is typically used on a String or Array (any Indexable works). The expected argument can be a String, Char, or Regex when the actual type (being compared against) is a String. For Indexable types, only the last item is inspected. It is compared with the === operator, so that values, types, regular expressions, and others can be tested.

Examples:

expect("foobar").to end_with("bar")
expect("foobar").to end_with('r')
expect("FOOBAR").to end_with(/bar/i)

expect(%i[a b c]).to end_with(:c)
expect(%i[a b c]).to end_with(Symbol)
expect(%w[foo bar]).to end_with(/bar/)

[View source]
macro eq(expected) #

Indicates that some value should equal another. The == operator is used for this check. The value passed to this method is the expected value.

Example:

expect(1 + 2).to eq(3)

[View source]
macro expect_raises(&block) #

Indicates that some block should raise an error.

Examples:

expect_raises { raise "foobar" }

[View source]
macro expect_raises(type, &block) #

Indicates that some block should raise an error with a given type. The type parameter should be an exception type.

Examples:

hash = {"foo" => "bar"}
expect_raises(KeyError) { hash["baz"] }.to raise_error(KeyError)

[View source]
macro expect_raises(type, message, &block) #

Indicates that some block should raise an error with a given message and type. The type is the exception type expected to be raised. The message is a string or regex to match to exception message against. This method is included for compatibility with Crystal's default spec.

Examples:

hash = {"foo" => "bar"}
expect_raises(KeyError, /baz/) { hash["baz"] }
expect_raises(ArgumentError, "foobar") { raise ArgumentError.new("foobar") }

[View source]
macro has_key(expected) #

Indicates that some set, such as a Hash, has a given key. The has_key? method is used for this check.

Examples:

expect({foo: "bar"}).to have_key(:foo)
expect({"lucky" => 7}).to have_key("lucky")

[View source]
macro has_value(expected) #

Indicates that some set, such as a Hash, has a given value. The has_value? method is used for this check.

Examples:

expect({foo: "bar"}).to have_value("bar")
expect({"lucky" => 7}).to have_value(7)

[View source]
macro have(*expected) #

Indicates that some value or set should contain another value. This is similar to #contain, but uses a different method for matching. Typically a String or Array (any Enumerable works) is checked against. The expected argument can be a String or Char when the actual type (being compared against) is a String. The includes? method is used for this case. For Enumerable types, each item is inspected until one matches. The === operator is used for this case, which allows for equality, type, regex, and other matches.

Examples:

expect("foobar").to have("foo")
expect("foobar").to have('o')

expect(%i[a b c]).to have(:b)
expect(%w[FOO BAR BAZ]).to have(/bar/i)
expect([1, 2, 3, :a, :b, :c]).to have(Int32)

Additionally, multiple arguments can be specified.

expect("foobarbaz").to have("foo", "bar")
expect(%i[a b c]).to have(:a, :b)
expect(%w[FOO BAR BAZ]).to have(/foo/i, String)

[View source]
macro have_attributes(**expected) #

Indicates that some value should have a set of attributes matching some conditions. A list of named arguments are expected. The names correspond to the attributes in the instance to check. The values are conditions to check with the === operator against the attribute's value.

Examples:

expect("foobar").to have_attributes(size: 6, upcase: "FOOBAR")
expect(%i[a b c]).to have_attributes(size: 1..5, first: Symbol)

[View source]
macro have_elements(expected) #

Indicates that some value or set should contain specific items. This is similar to #contain_elements, but uses a different method for matching. Typically a String or Array (any Enumerable works) is checked against. The expected argument can be a String or Char when the actual type (being compared against) is a String. The includes? method is used for this case. For Enumerable types, each item is inspected until one matches. The === operator is used for this case, which allows for equality, type, regex, and other matches.

Examples:

expect("foobar").to have_elements(["foo", "bar"])
expect("foobar").to have_elements(['a', 'b'])

expect(%i[a b c]).to have_elements(%i[b c])
expect(%w[FOO BAR BAZ]).to have_elements([/FOO/, /bar/i])
expect([1, 2, 3, :a, :b, :c]).to have_elements([Int32, Symbol])

[View source]
macro have_key(expected) #

Indicates that some set, such as a Hash, has a given key. The has_key? method is used for this check.

Examples:

expect({foo: "bar"}).to have_key(:foo)
expect({"lucky" => 7}).to have_key("lucky")

[View source]
macro have_received(method) #

Indicates that a mock or double (stubbable type) should receive a message (have a method called). The method is the name of the method expected to be called.

expect(dbl).to have_received(:foo)

[View source]
macro have_size(expected) #

Indicates that some set should have a specified size.

Example:

expect([1, 2, 3]).to have_size(3)

[View source]
macro have_size_of(expected) #

Indicates that some set should have the same size (number of elements) as another set.

Example:

expect([1, 2, 3]).to have_size_of(%i[x y z])

[View source]
macro have_value(expected) #

Indicates that some set, such as a Hash, has a given value. The has_value? method is used for this check.

Examples:

expect({foo: "bar"}).to have_value("bar")
expect({"lucky" => 7}).to have_value(7)

[View source]
macro match(expected) #

Indicates that some value should match another. The === (case equality) operator is used for this check. Typically a regular expression is used. This has identical behavior as a "when" condition in a case block.

Examples:

expect("foo").to match(/foo|bar/)
expect("BAR").to match(/foo|bar/i)
expect(1 + 2).to match(3)
expect(5).to match(Int32) # Using `#be_a` instead is recommended here.
expect({:foo, 5}).to match({Symbol, Int32})

[View source]
macro match_array(expected) #

Indicates that some set should contain the same values in any order as another set. This is the same as #contain_exactly, but takes an array as an argument.

Example:

expect([1, 2, 3]).to match_array([3, 2, 1])

[View source]
macro method_missing(call) #

Used to create predicate matchers. Any missing method that starts with 'be_' or 'have_' will be handled. All other method names will be ignored and raise a compile-time error.

This can be used to simply check a predicate method that ends in '?'. For instance:

expect("foobar").to be_ascii_only
# Is equivalent to:
expect("foobar".ascii_only?).to be_true

expect("foobar").to_not have_back_references
# Is equivalent to:
expect("foobar".has_back_references?).to_not be_true

[View source]
macro ne(expected) #

Indicates that some value should not equal another. The != operator is used for this check. The value passed to this method is the unexpected value.

Example:

expect(1 + 2).to ne(5)

[View source]
macro raise_error #

Indicates that some block should raise an error.

Examples:

expect { raise "foobar" }.to raise_error

[View source]
macro raise_error(type_or_message) #

Indicates that some block should raise an error with a given message or type. The type_or_message parameter should be an exception type or a string or regex to match the exception's message against.

Examples:

hash = {"foo" => "bar"}
expect { hash["baz"] }.to raise_error(KeyError)
expect { hash["baz"] }.to raise_error(/baz/)
expect { raise "foobar" }.to raise_error("foobar")

[View source]
macro raise_error(type, message) #

Indicates that some block should raise an error with a given message and type. The type is the exception type expected to be raised. The message is a string or regex to match to exception message against.

Examples:

hash = {"foo" => "bar"}
expect { hash["baz"] }.to raise_error(KeyError, /baz/)
expect { raise ArgumentError.new("foobar") }.to raise_error(ArgumentError, "foobar")

[View source]
macro respond_to(*expected) #

Indicates that some value should respond to a method call. One or more method names can be provided.

Examples:

expect("foobar").to respond_to(:downcase)
expect(%i[a b c]).to respond_to(:size, :first)

[View source]
macro start_with(expected) #

Indicates that some value or set should start with another value. This is typically used on a String or Array (any Enumerable works). The expected argument can be a String, Char, or Regex when the actual type (being compared against) is a String. For Enumerable types, only the first item is inspected. It is compared with the === operator, so that values, types, regular expressions, and others can be tested.

Examples:

expect("foobar").to start_with("foo")
expect("foobar").to start_with('f')
expect("FOOBAR").to start_with(/foo/i)

expect(%i[a b c]).to start_with(:a)
expect(%i[a b c]).to start_with(Symbol)
expect(%w[foo bar]).to start_with(/foo/)

[View source]