r_spec 1.0.0.beta1 → 1.0.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative File.join("error", "pending_expectation")
4
+ require_relative File.join("error", "undefined_described_class")
5
+ require_relative File.join("error", "undefined_subject")
6
+
7
+ module RSpec
8
+ # Namespace for exceptions.
9
+ #
10
+ # @api private
11
+ module Error
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "expresenter"
4
+
5
+ module RSpec
6
+ module Error
7
+ # Exception for pending expectations.
8
+ #
9
+ # @api private
10
+ class PendingExpectation < ::RuntimeError
11
+ # @param message [String] The not implemented expectation description.
12
+ #
13
+ # @return [nil] Write a pending expectation to STDOUT.
14
+ def self.result(message)
15
+ ::Expresenter.call(true).with(
16
+ actual: new(message),
17
+ error: nil,
18
+ expected: self,
19
+ got: false,
20
+ matcher: :raise_exception,
21
+ negate: true,
22
+ level: :SHOULD,
23
+ valid: false
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Error
5
+ # Exception for undefined described classes.
6
+ #
7
+ # @api private
8
+ class UndefinedDescribedClass < ::RuntimeError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Error
5
+ # Exception for undefined subjects.
6
+ #
7
+ # @api private
8
+ class UndefinedSubject < ::RuntimeError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative File.join("expectation_helper", "it")
4
+ require_relative File.join("expectation_helper", "its")
5
+
6
+ module RSpec
7
+ # Namespace for `it` and `its` helper modules.
8
+ module ExpectationHelper
9
+ end
10
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "matchi/rspec"
4
+
5
+ require_relative File.join("..", "error", "pending_expectation")
6
+
7
+ module RSpec
8
+ module ExpectationHelper
9
+ # Abstract expectation helper base module.
10
+ #
11
+ # This module defines a number of methods to create expectations, which are
12
+ # automatically included into examples.
13
+ #
14
+ # It also includes a collection of expectation matchers 🤹
15
+ #
16
+ # @example Equivalence matcher
17
+ # matcher = eql("foo") # => Matchi::Matcher::Eql.new("foo")
18
+ # matcher.matches? { "foo" } # => true
19
+ # matcher.matches? { "bar" } # => false
20
+ #
21
+ # matcher = eq("foo") # => Matchi::Matcher::Eq.new("foo")
22
+ # matcher.matches? { "foo" } # => true
23
+ # matcher.matches? { "bar" } # => false
24
+ #
25
+ # @example Identity matcher
26
+ # object = "foo"
27
+ #
28
+ # matcher = equal(object) # => Matchi::Matcher::Equal.new(object)
29
+ # matcher.matches? { object } # => true
30
+ # matcher.matches? { "foo" } # => false
31
+ #
32
+ # matcher = be(object) # => Matchi::Matcher::Be.new(object)
33
+ # matcher.matches? { object } # => true
34
+ # matcher.matches? { "foo" } # => false
35
+ #
36
+ # @example Regular expressions matcher
37
+ # matcher = match(/^foo$/) # => Matchi::Matcher::Match.new(/^foo$/)
38
+ # matcher.matches? { "foo" } # => true
39
+ # matcher.matches? { "bar" } # => false
40
+ #
41
+ # @example Expecting errors matcher
42
+ # matcher = raise_exception(NameError) # => Matchi::Matcher::RaiseException.new(NameError)
43
+ # matcher.matches? { Boom } # => true
44
+ # matcher.matches? { true } # => false
45
+ #
46
+ # @example Truth matcher
47
+ # matcher = be_true # => Matchi::Matcher::BeTrue.new
48
+ # matcher.matches? { true } # => true
49
+ # matcher.matches? { false } # => false
50
+ # matcher.matches? { nil } # => false
51
+ # matcher.matches? { 4 } # => false
52
+ #
53
+ # @example Untruth matcher
54
+ # matcher = be_false # => Matchi::Matcher::BeFalse.new
55
+ # matcher.matches? { false } # => true
56
+ # matcher.matches? { true } # => false
57
+ # matcher.matches? { nil } # => false
58
+ # matcher.matches? { 4 } # => false
59
+ #
60
+ # @example Nil matcher
61
+ # matcher = be_nil # => Matchi::Matcher::BeNil.new
62
+ # matcher.matches? { nil } # => true
63
+ # matcher.matches? { false } # => false
64
+ # matcher.matches? { true } # => false
65
+ # matcher.matches? { 4 } # => false
66
+ #
67
+ # @example Type/class matcher
68
+ # matcher = be_instance_of(String) # => Matchi::Matcher::BeInstanceOf.new(String)
69
+ # matcher.matches? { "foo" } # => true
70
+ # matcher.matches? { 4 } # => false
71
+ #
72
+ # matcher = be_an_instance_of(String) # => Matchi::Matcher::BeAnInstanceOf.new(String)
73
+ # matcher.matches? { "foo" } # => true
74
+ # matcher.matches? { 4 } # => false
75
+ #
76
+ # @see https://github.com/fixrb/matchi
77
+ # @see https://github.com/fixrb/matchi-rspec
78
+ module Base
79
+ include ::Matchi::Helper
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative File.join("..", "expectation_target")
5
+
6
+ module RSpec
7
+ module ExpectationHelper
8
+ # {RSpec::DSL#it}'s expectation helper module.
9
+ module It
10
+ include Base
11
+
12
+ # Create an expectation for a spec.
13
+ #
14
+ # @param value [#object_id, nil] An actual value.
15
+ # @param block [#call, nil] A code to evaluate.
16
+ #
17
+ # @return [Block, Value] The wrapped target of an expectation.
18
+ #
19
+ # @example
20
+ # expect("foo") # => #<RSpec::ExpectationTarget::Value:0x00007fb6b82311a0 @actual="foo">
21
+ # expect { Boom } # => #<RSpec::ExpectationTarget::Block:0x00007fb6b8263df8 @callable=#<Proc:0x00007fb6b8263e20>>
22
+ #
23
+ # @api public
24
+ def expect(value = self.class.superclass, &block)
25
+ ExpectationTarget.call(self.class.superclass, value, block)
26
+ end
27
+
28
+ # Wraps the target of an expectation with the subject as actual value.
29
+ #
30
+ # @return [Block] The wrapped target of an expectation.
31
+ #
32
+ # @example
33
+ # is_expected # => #<RSpec::ExpectationTarget::Block:0x00007fb6b8263df8 @callable=#<Proc:0x00007fb6b8263e20>>
34
+ #
35
+ # @api public
36
+ def is_expected
37
+ expect { subject }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative File.join("..", "expectation_target", "block")
5
+
6
+ module RSpec
7
+ module ExpectationHelper
8
+ # {RSpec::DSL#its}'s expectation helper module.
9
+ module Its
10
+ include Base
11
+
12
+ # Wraps the target of an expectation with the actual value.
13
+ #
14
+ # @return [Block] The wrapped target of an expectation.
15
+ #
16
+ # @example
17
+ # is_expected # => #<RSpec::ExpectationTarget::Block:0x00007fb6b8263df8 @callable=#<Proc:0x00007fb6b8263e20>>
18
+ #
19
+ # @api public
20
+ def is_expected
21
+ ExpectationTarget::Block.new(method(:actual))
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative File.join("expectation_target", "block")
4
+ require_relative File.join("expectation_target", "value")
5
+
6
+ module RSpec
7
+ # Wraps the target of an expectation.
8
+ #
9
+ # @api private
10
+ module ExpectationTarget
11
+ # @param undefined_value A sentinel value to be able to tell when the user
12
+ # did not pass an argument. We can't use `nil` for that because `nil` is a
13
+ # valid value to pass.
14
+ # @param value [#object_id, nil] An actual value.
15
+ # @param block [#call, nil] A code to evaluate.
16
+ #
17
+ # @return [Block, Value] The wrapped target of an expectation.
18
+ def self.call(undefined_value, value, block)
19
+ if undefined_value.equal?(value)
20
+ raise ::ArgumentError, "Pass either an argument or a block" unless block
21
+
22
+ Block.new(block)
23
+ else
24
+ raise ::ArgumentError, "Can't pass both an argument and a block" if block
25
+
26
+ Value.new(value)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "expresenter"
4
+
5
+ require_relative File.join("..", "console")
6
+
7
+ module RSpec
8
+ module ExpectationTarget
9
+ # Abstract expectation target base class.
10
+ #
11
+ # @note `RSpec::ExpectationTarget::Base` is not intended to be instantiated
12
+ # directly by users. Use `expect` instead.
13
+ class Base
14
+ # Instantiate a new expectation target.
15
+ #
16
+ # @param actual [#object_id] The actual value of the code to evaluate.
17
+ def initialize(actual)
18
+ @actual = actual
19
+ end
20
+
21
+ # Runs the given expectation, passing if `matcher` returns true.
22
+ #
23
+ # @example _Absolute requirement_ definition
24
+ # expect { "foo".upcase }.to eq("foo")
25
+ #
26
+ # @param matcher [#matches?] The matcher.
27
+ #
28
+ # @raise (see #result)
29
+ # @return (see #result)
30
+ #
31
+ # @api public
32
+ def to(matcher)
33
+ absolute_requirement(matcher: matcher, negate: false)
34
+ end
35
+
36
+ # Runs the given expectation, passing if `matcher` returns false.
37
+ #
38
+ # @example _Absolute prohibition_ definition
39
+ # expect { "foo".size }.not_to be(4)
40
+ #
41
+ # @param (see #to)
42
+ #
43
+ # @raise (see #result)
44
+ # @return (see #result)
45
+ #
46
+ # @api public
47
+ def not_to(matcher)
48
+ absolute_requirement(matcher: matcher, negate: true)
49
+ end
50
+
51
+ protected
52
+
53
+ # @param actual [#object_id] The actual value.
54
+ # @param error [Exception, nil] Any raised exception.
55
+ # @param got [Boolean, nil] Any returned value.
56
+ # @param matcher [#matches?] The matcher.
57
+ # @param negate [Boolean] The assertion is positive or negative.
58
+ # @param valid [Boolean] The result of an expectation.
59
+ #
60
+ # @return [nil] Write a message to STDOUT.
61
+ #
62
+ # @raise [SystemExit] Terminate execution immediately by calling
63
+ # `Kernel.exit(false)` with a failure message written to STDERR.
64
+ #
65
+ # @api private
66
+ def result(actual:, error:, got:, matcher:, negate:, valid:)
67
+ Console.passed_spec ::Expresenter.call(valid).with(
68
+ actual: actual,
69
+ error: error,
70
+ expected: matcher.expected,
71
+ got: got,
72
+ negate: negate,
73
+ valid: valid,
74
+ matcher: matcher.class.to_sym,
75
+ level: :MUST
76
+ )
77
+ rescue ::Expresenter::Fail => e
78
+ Console.failed_spec(e)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spectus/exam"
4
+
5
+ require_relative "base"
6
+
7
+ module RSpec
8
+ module ExpectationTarget
9
+ # Wraps the target of an expectation with a block.
10
+ #
11
+ # @example
12
+ # expect { something } # => ExpectationTarget::Block wrapping something
13
+ #
14
+ # # used with `to`
15
+ # expect { actual }.to be(42)
16
+ #
17
+ # # with `not_to`
18
+ # expect { actual }.not_to be(4)
19
+ #
20
+ # @note `RSpec::ExpectationTarget::Block` is not intended to be instantiated
21
+ # directly by users. Use `expect` instead.
22
+ class Block < Base
23
+ protected
24
+
25
+ # @param matcher [#matches?] The matcher.
26
+ # @param negate [Boolean] The assertion is positive or negative.
27
+ #
28
+ # @return [nil] Write a message to STDOUT.
29
+ #
30
+ # @raise [SystemExit] Terminate execution immediately by calling
31
+ # `Kernel.exit(false)` with a failure message written to STDERR.
32
+ def absolute_requirement(matcher:, negate:)
33
+ exam = ::Spectus::Exam.new(
34
+ callable: @actual,
35
+ isolation: false,
36
+ negate: negate,
37
+ matcher: matcher
38
+ )
39
+
40
+ result(
41
+ actual: exam.actual,
42
+ error: exam.exception,
43
+ got: exam.got,
44
+ matcher: matcher,
45
+ negate: negate,
46
+ valid: exam.valid?
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module RSpec
6
+ module ExpectationTarget
7
+ # Wraps the target of an expectation with a value.
8
+ #
9
+ # @example
10
+ # expect(something) # => ExpectationTarget::Value wrapping something
11
+ #
12
+ # # used with `to`
13
+ # expect(actual).to be(42)
14
+ #
15
+ # # with `not_to`
16
+ # expect(actual).not_to be(4)
17
+ #
18
+ # @note `RSpec::ExpectationTarget::Value` is not intended to be instantiated
19
+ # directly by users. Use `expect` instead.
20
+ class Value < Base
21
+ protected
22
+
23
+ # @param matcher [#matches?] The matcher.
24
+ # @param negate [Boolean] The assertion is positive or negative.
25
+ #
26
+ # @return [nil] Write a message to STDOUT.
27
+ #
28
+ # @raise [SystemExit] Terminate execution immediately by calling
29
+ # `Kernel.exit(false)` with a failure message written to STDERR.
30
+ def absolute_requirement(matcher:, negate:)
31
+ valid = negate ^ matcher.matches? { @actual }
32
+
33
+ result(
34
+ actual: @actual,
35
+ error: nil,
36
+ got: valid,
37
+ matcher: matcher,
38
+ negate: negate,
39
+ valid: valid
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end