mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Merge branch 'specs' of gitlab.com:arctic-fox/spectator into specs
This commit is contained in:
commit
b25388a165
9 changed files with 264 additions and 17 deletions
99
spec/rspec/expectations/contain_matcher_spec.cr
Normal file
99
spec/rspec/expectations/contain_matcher_spec.cr
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
# In Ruby, this is the `include` matcher.
|
||||||
|
# However, `include` is a reserved keyword in Crystal.
|
||||||
|
# So instead, it is `contain` in Spectator.
|
||||||
|
Spectator.describe "`contain` matcher" do
|
||||||
|
context "array usage" do
|
||||||
|
describe [1, 3, 7] do
|
||||||
|
it { is_expected.to contain(1) }
|
||||||
|
it { is_expected.to contain(3) }
|
||||||
|
it { is_expected.to contain(7) }
|
||||||
|
it { is_expected.to contain(1, 7) }
|
||||||
|
it { is_expected.to contain(1, 3, 7) }
|
||||||
|
|
||||||
|
# Utility matcher method `a_kind_of` is not supported.
|
||||||
|
# it { is_expected.to contain(a_kind_of(Int)) }
|
||||||
|
|
||||||
|
# TODO: Compound matchers aren't supported.
|
||||||
|
# it { is_expected.to contain(be_odd.and be < 10) }
|
||||||
|
|
||||||
|
# TODO: Fix behavior and cleanup output.
|
||||||
|
# This syntax is allowed, but produces a wrong result and bad output.
|
||||||
|
xit { is_expected.to contain(be_odd) }
|
||||||
|
xit { is_expected.not_to contain(be_even) }
|
||||||
|
|
||||||
|
it { is_expected.not_to contain(17) }
|
||||||
|
it { is_expected.not_to contain(43, 100) }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.to contain(4) }
|
||||||
|
xit { is_expected.to contain(be_even) }
|
||||||
|
xit { is_expected.not_to contain(1) }
|
||||||
|
xit { is_expected.not_to contain(3) }
|
||||||
|
xit { is_expected.not_to contain(7) }
|
||||||
|
xit { is_expected.not_to contain(1, 3, 7) }
|
||||||
|
|
||||||
|
# both of these should fail since it contains 1 but not 9
|
||||||
|
xit { is_expected.to contain(1, 9) }
|
||||||
|
xit { is_expected.not_to contain(1, 9) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "string usage" do
|
||||||
|
describe "a string" do
|
||||||
|
it { is_expected.to contain("str") }
|
||||||
|
it { is_expected.to contain("a", "str", "ng") }
|
||||||
|
it { is_expected.not_to contain("foo") }
|
||||||
|
it { is_expected.not_to contain("foo", "bar") }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.to contain("foo") }
|
||||||
|
xit { is_expected.not_to contain("str") }
|
||||||
|
xit { is_expected.to contain("str", "foo") }
|
||||||
|
xit { is_expected.not_to contain("str", "foo") }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "hash usage" do
|
||||||
|
# A hash can't be described inline here for some reason.
|
||||||
|
# So it is placed in the subject instead.
|
||||||
|
describe ":a => 7, :b => 5" do
|
||||||
|
subject { {:a => 7, :b => 5} }
|
||||||
|
|
||||||
|
# Hash syntax is changed here from `:a => 7` to `a: 7`.
|
||||||
|
xit { is_expected.to contain(:a) }
|
||||||
|
xit { is_expected.to contain(:b, :a) }
|
||||||
|
|
||||||
|
# TODO: This hash-like syntax isn't supported.
|
||||||
|
# it { is_expected.to contain(a: 7) }
|
||||||
|
# it { is_expected.to contain(b: 5, a: 7) }
|
||||||
|
xit { is_expected.not_to contain(:c) }
|
||||||
|
xit { is_expected.not_to contain(:c, :d) }
|
||||||
|
# it { is_expected.not_to contain(d: 2) }
|
||||||
|
# it { is_expected.not_to contain(a: 5) }
|
||||||
|
# it { is_expected.not_to contain(b: 7, a: 5) }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.not_to contain(:a) }
|
||||||
|
xit { is_expected.not_to contain(:b, :a) }
|
||||||
|
# it { is_expected.not_to contain(a: 7) }
|
||||||
|
# it { is_expected.not_to contain(a: 7, b: 5) }
|
||||||
|
xit { is_expected.to contain(:c) }
|
||||||
|
xit { is_expected.to contain(:c, :d) }
|
||||||
|
# it { is_expected.to contain(d: 2) }
|
||||||
|
# it { is_expected.to contain(a: 5) }
|
||||||
|
# it { is_expected.to contain(a: 5, b: 7) }
|
||||||
|
|
||||||
|
# Mixed cases--the hash contains one but not the other.
|
||||||
|
# All 4 of these cases should fail.
|
||||||
|
xit { is_expected.to contain(:a, :d) }
|
||||||
|
xit { is_expected.not_to contain(:a, :d) }
|
||||||
|
# it { is_expected.to contain(a: 7, d: 3) }
|
||||||
|
# it { is_expected.not_to contain(a: 7, d: 3) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
33
spec/rspec/expectations/end_with_matcher_spec.cr
Normal file
33
spec/rspec/expectations/end_with_matcher_spec.cr
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
# Examples taken from:
|
||||||
|
# https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/end-with-matcher
|
||||||
|
# and modified to fit Spectator and Crystal.
|
||||||
|
Spectator.describe "`end_with` matcher" do
|
||||||
|
context "string usage" do
|
||||||
|
describe "this string" do
|
||||||
|
it { is_expected.to end_with "string" }
|
||||||
|
it { is_expected.not_to end_with "stringy" }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.not_to end_with "string" }
|
||||||
|
xit { is_expected.to end_with "stringy" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "array usage" do
|
||||||
|
describe [0, 1, 2, 3, 4] do
|
||||||
|
it { is_expected.to end_with 4 }
|
||||||
|
# TODO: Add support for multiple items at the end of an array.
|
||||||
|
# it { is_expected.to end_with 3, 4 }
|
||||||
|
it { is_expected.not_to end_with 3 }
|
||||||
|
# it { is_expected.not_to end_with 0, 1, 2, 3, 4, 5 }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.not_to end_with 4 }
|
||||||
|
xit { is_expected.to end_with 3 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
37
spec/rspec/expectations/have_attributes_matcher_spec.cr
Normal file
37
spec/rspec/expectations/have_attributes_matcher_spec.cr
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
# Examples taken from:
|
||||||
|
# https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/have-attributes-matcher
|
||||||
|
# and modified to fit Spectator and Crystal.
|
||||||
|
Spectator.describe "`have_attributes` matcher" do
|
||||||
|
context "basic usage" do
|
||||||
|
# Use `record` instead of `Struct.new`.
|
||||||
|
record Person, name : String, age : Int32
|
||||||
|
|
||||||
|
describe Person.new("Jim", 32) do
|
||||||
|
# Changed some syntax for Ruby hashes to Crystal named tuples.
|
||||||
|
|
||||||
|
# Spectator doesn't support helper matchers like `a_string_starting_with` and `a_value <`.
|
||||||
|
# But maybe in the future it will.
|
||||||
|
it { is_expected.to have_attributes(name: "Jim") }
|
||||||
|
# it { is_expected.to have_attributes(name: a_string_starting_with("J") ) }
|
||||||
|
it { is_expected.to have_attributes(age: 32) }
|
||||||
|
# it { is_expected.to have_attributes(age: (a_value > 30) ) }
|
||||||
|
it { is_expected.to have_attributes(name: "Jim", age: 32) }
|
||||||
|
# it { is_expected.to have_attributes(name: a_string_starting_with("J"), age: (a_value > 30) ) }
|
||||||
|
it { is_expected.not_to have_attributes(name: "Bob") }
|
||||||
|
it { is_expected.not_to have_attributes(age: 10) }
|
||||||
|
# it { is_expected.not_to have_attributes(age: (a_value < 30) ) }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.to have_attributes(name: "Bob") }
|
||||||
|
xit { is_expected.to have_attributes(name: 10) }
|
||||||
|
|
||||||
|
# fails if any of the attributes don't match
|
||||||
|
xit { is_expected.to have_attributes(name: "Bob", age: 32) }
|
||||||
|
xit { is_expected.to have_attributes(name: "Jim", age: 10) }
|
||||||
|
xit { is_expected.to have_attributes(name: "Bob", age: 10) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
30
spec/rspec/expectations/match_matcher_spec.cr
Normal file
30
spec/rspec/expectations/match_matcher_spec.cr
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
# Examples taken from:
|
||||||
|
# https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/match-matcher
|
||||||
|
# and modified to fit Spectator and Crystal.
|
||||||
|
Spectator.describe "`match` matcher" do
|
||||||
|
context "string usage" do
|
||||||
|
describe "a string" do
|
||||||
|
it { is_expected.to match(/str/) }
|
||||||
|
it { is_expected.not_to match(/foo/) }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.not_to match(/str/) }
|
||||||
|
xit { is_expected.to match(/foo/) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "regular expression usage" do
|
||||||
|
describe /foo/ do
|
||||||
|
it { is_expected.to match("food") }
|
||||||
|
it { is_expected.not_to match("drinks") }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.not_to match("food") }
|
||||||
|
xit { is_expected.to match("drinks") }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
33
spec/rspec/expectations/start_with_matcher_spec.cr
Normal file
33
spec/rspec/expectations/start_with_matcher_spec.cr
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
# Examples taken from:
|
||||||
|
# https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/start-with-matcher
|
||||||
|
# and modified to fit Spectator and Crystal.
|
||||||
|
Spectator.describe "`start_with` matcher" do
|
||||||
|
context "with a string" do
|
||||||
|
describe "this string" do
|
||||||
|
it { is_expected.to start_with "this" }
|
||||||
|
it { is_expected.not_to start_with "that" }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.not_to start_with "this" }
|
||||||
|
xit { is_expected.to start_with "that" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with an array" do
|
||||||
|
describe [0, 1, 2, 3, 4] do
|
||||||
|
it { is_expected.to start_with 0 }
|
||||||
|
# TODO: Add support for multiple items at the beginning of an array.
|
||||||
|
# it { is_expected.to start_with(0, 1) }
|
||||||
|
it { is_expected.not_to start_with(2) }
|
||||||
|
# it { is_expected.not_to start_with(0, 1, 2, 3, 4, 5) }
|
||||||
|
|
||||||
|
# deliberate failures
|
||||||
|
# TODO: Add support for expected failures.
|
||||||
|
xit { is_expected.not_to start_with 0 }
|
||||||
|
xit { is_expected.to start_with 3 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,6 +16,12 @@ module Spectator::Matchers
|
||||||
expected.value === actual.value
|
expected.value === actual.value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Overload that takes a regex so that the operands are flipped.
|
||||||
|
# This mimics RSpec's behavior.
|
||||||
|
private def match?(actual : TestExpression(Regex)) : Bool forall T
|
||||||
|
actual.value === expected.value
|
||||||
|
end
|
||||||
|
|
||||||
# Message displayed when the matcher isn't satisifed.
|
# Message displayed when the matcher isn't satisifed.
|
||||||
#
|
#
|
||||||
# This is only called when `#match?` returns false.
|
# This is only called when `#match?` returns false.
|
||||||
|
|
|
@ -23,7 +23,8 @@ module Spectator::Matchers
|
||||||
|
|
||||||
# Actually performs the test against the expression.
|
# Actually performs the test against the expression.
|
||||||
def match(actual : TestExpression(T)) : MatchData forall T
|
def match(actual : TestExpression(T)) : MatchData forall T
|
||||||
if (value = actual.value).responds_to?(:ends_with?)
|
value = actual.value
|
||||||
|
if value.is_a?(String) || value.responds_to?(:ends_with?)
|
||||||
match_ends_with(value, actual.label)
|
match_ends_with(value, actual.label)
|
||||||
else
|
else
|
||||||
match_last(value, actual.label)
|
match_last(value, actual.label)
|
||||||
|
@ -33,10 +34,11 @@ module Spectator::Matchers
|
||||||
# Performs the test against the expression, but inverted.
|
# Performs the test against the expression, but inverted.
|
||||||
# A successful match with `#match` should normally fail for this method, and vice-versa.
|
# A successful match with `#match` should normally fail for this method, and vice-versa.
|
||||||
def negated_match(actual : TestExpression(T)) : MatchData forall T
|
def negated_match(actual : TestExpression(T)) : MatchData forall T
|
||||||
if actual.value.responds_to?(:ends_with?)
|
value = actual.value
|
||||||
negated_match_ends_with(actual)
|
if value.is_a?(String) || value.responds_to?(:ends_with?)
|
||||||
|
negated_match_ends_with(value, actual.label)
|
||||||
else
|
else
|
||||||
negated_match_last(actual)
|
negated_match_last(value, actual.label)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -72,11 +74,11 @@ module Spectator::Matchers
|
||||||
|
|
||||||
# Checks whether the actual value does not end with the expected value.
|
# Checks whether the actual value does not end with the expected value.
|
||||||
# This method expects (and uses) the `#ends_with?` method on the value.
|
# This method expects (and uses) the `#ends_with?` method on the value.
|
||||||
private def negated_match_ends_with(actual)
|
private def negated_match_ends_with(actual_value, actual_label)
|
||||||
if actual.value.ends_with?(expected.value)
|
if actual_value.ends_with?(expected.value)
|
||||||
FailedMatchData.new(description, "#{actual.label} ends with #{expected.label} (using #ends_with?)",
|
FailedMatchData.new(description, "#{actual_label} ends with #{expected.label} (using #ends_with?)",
|
||||||
expected: expected.value.inspect,
|
expected: "Not #{expected.value.inspect}",
|
||||||
actual: actual.value.inspect
|
actual: actual_value.inspect
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
SuccessfulMatchData.new(description)
|
SuccessfulMatchData.new(description)
|
||||||
|
@ -85,13 +87,13 @@ module Spectator::Matchers
|
||||||
|
|
||||||
# Checks whether the last element of the value is not the expected value.
|
# Checks whether the last element of the value is not the expected value.
|
||||||
# This method expects that the actual value is a set (enumerable).
|
# This method expects that the actual value is a set (enumerable).
|
||||||
private def negated_match_last(actual)
|
private def negated_match_last(actual_value, actual_label)
|
||||||
list = actual.value.to_a
|
list = actual_value.to_a
|
||||||
last = list.last
|
last = list.last
|
||||||
|
|
||||||
if expected.value === last
|
if expected.value === last
|
||||||
FailedMatchData.new(description, "#{actual.label} ends with #{expected.label} (using expected === last)",
|
FailedMatchData.new(description, "#{actual_label} ends with #{expected.label} (using expected === last)",
|
||||||
expected: expected.value.inspect,
|
expected: "Not #{expected.value.inspect}",
|
||||||
actual: last.inspect,
|
actual: last.inspect,
|
||||||
list: list.inspect
|
list: list.inspect
|
||||||
)
|
)
|
||||||
|
|
|
@ -90,6 +90,11 @@ module Spectator::Matchers
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def with_message(message : T) forall T
|
||||||
|
value = TestValue.new(message)
|
||||||
|
ExceptionMatcher(ExceptionType, T).new(value)
|
||||||
|
end
|
||||||
|
|
||||||
# Runs a block of code and returns the exception it threw.
|
# Runs a block of code and returns the exception it threw.
|
||||||
# If no exception was thrown, *nil* is returned.
|
# If no exception was thrown, *nil* is returned.
|
||||||
private def capture_exception
|
private def capture_exception
|
||||||
|
|
|
@ -22,7 +22,8 @@ module Spectator::Matchers
|
||||||
|
|
||||||
# Actually performs the test against the expression.
|
# Actually performs the test against the expression.
|
||||||
def match(actual : TestExpression(T)) : MatchData forall T
|
def match(actual : TestExpression(T)) : MatchData forall T
|
||||||
if (value = actual.value).responds_to?(:starts_with?)
|
value = actual.value
|
||||||
|
if value.is_a?(String) || value.responds_to?(:starts_with?)
|
||||||
match_starts_with(value, actual.label)
|
match_starts_with(value, actual.label)
|
||||||
else
|
else
|
||||||
match_first(value, actual.label)
|
match_first(value, actual.label)
|
||||||
|
@ -32,7 +33,8 @@ module Spectator::Matchers
|
||||||
# Performs the test against the expression, but inverted.
|
# Performs the test against the expression, but inverted.
|
||||||
# A successful match with `#match` should normally fail for this method, and vice-versa.
|
# A successful match with `#match` should normally fail for this method, and vice-versa.
|
||||||
def negated_match(actual : TestExpression(T)) : MatchData forall T
|
def negated_match(actual : TestExpression(T)) : MatchData forall T
|
||||||
if (value = actual.value).responds_to?(:starts_with?)
|
value = actual.value
|
||||||
|
if value.is_a?(String) || value.responds_to?(:starts_with?)
|
||||||
negated_match_starts_with(value, actual.label)
|
negated_match_starts_with(value, actual.label)
|
||||||
else
|
else
|
||||||
negated_match_first(value, actual.label)
|
negated_match_first(value, actual.label)
|
||||||
|
@ -74,7 +76,7 @@ module Spectator::Matchers
|
||||||
private def negated_match_starts_with(actual_value, actual_label)
|
private def negated_match_starts_with(actual_value, actual_label)
|
||||||
if actual_value.starts_with?(expected.value)
|
if actual_value.starts_with?(expected.value)
|
||||||
FailedMatchData.new(description, "#{actual_label} starts with #{expected.label} (using #starts_with?)",
|
FailedMatchData.new(description, "#{actual_label} starts with #{expected.label} (using #starts_with?)",
|
||||||
expected: expected.value.inspect,
|
expected: "Not #{expected.value.inspect}",
|
||||||
actual: actual_value.inspect
|
actual: actual_value.inspect
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
@ -90,7 +92,7 @@ module Spectator::Matchers
|
||||||
|
|
||||||
if expected.value === first
|
if expected.value === first
|
||||||
FailedMatchData.new(description, "#{actual_label} starts with #{expected.label} (using expected === first)",
|
FailedMatchData.new(description, "#{actual_label} starts with #{expected.label} (using expected === first)",
|
||||||
expected: expected.value.inspect,
|
expected: "Not #{expected.value.inspect}",
|
||||||
actual: first.inspect,
|
actual: first.inspect,
|
||||||
list: list.inspect
|
list: list.inspect
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue