r_spec 0.3.3 → 1.0.0.beta5

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
+ module RSpec
4
+ # Namespace for exceptions.
5
+ #
6
+ # @api private
7
+ module Error
8
+ end
9
+ end
10
+
11
+ require_relative File.join("error", "pending_expectation")
12
+ require_relative File.join("error", "undefined_described_class")
13
+ require_relative File.join("error", "undefined_subject")
@@ -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
+ warn " " + ::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
+ ).colored_string
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
+ module RSpec
4
+ # Namespace for `it` and `its` helper modules.
5
+ module ExpectationHelper
6
+ end
7
+ end
8
+
9
+ require_relative File.join("expectation_helper", "it")
10
+ require_relative File.join("expectation_helper", "its")
@@ -0,0 +1,99 @@
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 example namespaces.
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
+
81
+ # Mark a spec as pending, expectation results will be ignored.
82
+ #
83
+ # @param description [String] The reason why the example is pending.
84
+ #
85
+ # @return [nil] Write a message to STDOUT.
86
+ #
87
+ # @example Output a message to the console and return nil
88
+ # pending("something else getting finished") # => nil
89
+ #
90
+ # # Output to the console
91
+ # # Warning: something else getting finished.
92
+ #
93
+ # @api public
94
+ def pending(description)
95
+ Error::PendingExpectation.result(description)
96
+ end
97
+ end
98
+ end
99
+ 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
+ # `it` 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
+ # `its` 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
+ module RSpec
4
+ # Wraps the target of an expectation.
5
+ #
6
+ # @api private
7
+ module ExpectationTarget
8
+ # @param undefined_value A sentinel value to be able to tell when the user
9
+ # did not pass an argument. We can't use `nil` for that because `nil` is a
10
+ # valid value to pass.
11
+ # @param value [#object_id, nil] An actual value.
12
+ # @param block [#call, nil] A code to evaluate.
13
+ #
14
+ # @return [Block, Value] The wrapped target of an expectation.
15
+ def self.call(undefined_value, value, block)
16
+ if undefined_value.equal?(value)
17
+ raise ::ArgumentError, "Pass either an argument or a block" unless block
18
+
19
+ Block.new(block)
20
+ else
21
+ raise ::ArgumentError, "Can't pass both an argument and a block" if block
22
+
23
+ Value.new(value)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ require_relative File.join("expectation_target", "block")
30
+ require_relative File.join("expectation_target", "value")
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "expresenter"
4
+
5
+ module RSpec
6
+ module ExpectationTarget
7
+ # Abstract expectation target base class.
8
+ #
9
+ # @note `RSpec::ExpectationTarget::Base` is not intended to be instantiated
10
+ # directly by users. Use `expect` instead.
11
+ class Base
12
+ # Runs the given expectation, passing if `matcher` returns true.
13
+ #
14
+ # @example _Absolute requirement_ definition
15
+ # expect { "foo".upcase }.to eq("foo")
16
+ #
17
+ # @param matcher [#matches?] The matcher.
18
+ #
19
+ # @raise (see #result)
20
+ # @return (see #result)
21
+ #
22
+ # @api public
23
+ def to(matcher)
24
+ absolute_requirement(matcher: matcher, negate: false)
25
+ end
26
+
27
+ # Runs the given expectation, passing if `matcher` returns false.
28
+ #
29
+ # @example _Absolute prohibition_ definition
30
+ # expect { "foo".size }.not_to be(4)
31
+ #
32
+ # @param (see #to)
33
+ #
34
+ # @raise (see #result)
35
+ # @return (see #result)
36
+ #
37
+ # @api public
38
+ def not_to(matcher)
39
+ absolute_requirement(matcher: matcher, negate: true)
40
+ end
41
+
42
+ protected
43
+
44
+ # @param actual [#object_id] The actual value.
45
+ # @param error [Exception, nil] Any raised exception.
46
+ # @param got [Boolean, nil] Any returned value.
47
+ # @param matcher [#matches?] The matcher.
48
+ # @param negate [Boolean] The assertion is positive or negative.
49
+ # @param valid [Boolean] The result of an expectation.
50
+ #
51
+ # @return [nil] Write a message to STDOUT.
52
+ #
53
+ # @raise [SystemExit] Terminate execution immediately by calling
54
+ # `Kernel.exit(false)` with a failure message written to STDERR.
55
+ #
56
+ # @api private
57
+ def result(actual:, error:, got:, matcher:, negate:, valid:)
58
+ puts " " + ::Expresenter.call(valid).with(
59
+ actual: actual,
60
+ error: error,
61
+ expected: matcher.expected,
62
+ got: got,
63
+ negate: negate,
64
+ valid: valid,
65
+ matcher: matcher.class.to_sym,
66
+ level: :MUST
67
+ ).colored_string
68
+ rescue ::Expresenter::Fail => e
69
+ abort " #{e.colored_string}"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,60 @@
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
+ # Instantiate a new expectation target.
24
+ #
25
+ # @param block [#call] The code to evaluate.
26
+ def initialize(block)
27
+ super()
28
+
29
+ @callable = block
30
+ end
31
+
32
+ protected
33
+
34
+ # @param matcher [#matches?] The matcher.
35
+ # @param negate [Boolean] The assertion is positive or negative.
36
+ #
37
+ # @return [nil] Write a message to STDOUT.
38
+ #
39
+ # @raise [SystemExit] Terminate execution immediately by calling
40
+ # `Kernel.exit(false)` with a failure message written to STDERR.
41
+ def absolute_requirement(matcher:, negate:)
42
+ exam = ::Spectus::Exam.new(
43
+ callable: @callable,
44
+ isolation: false,
45
+ negate: negate,
46
+ matcher: matcher
47
+ )
48
+
49
+ result(
50
+ actual: exam.actual,
51
+ error: exam.exception,
52
+ got: exam.got,
53
+ matcher: matcher,
54
+ negate: negate,
55
+ valid: exam.valid?
56
+ )
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,53 @@
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
+ # Instantiate a new expectation target.
22
+ #
23
+ # @param actual [#object_id] The actual value.
24
+ def initialize(actual)
25
+ super()
26
+
27
+ @actual = actual
28
+ end
29
+
30
+ protected
31
+
32
+ # @param matcher [#matches?] The matcher.
33
+ # @param negate [Boolean] The assertion is positive or negative.
34
+ #
35
+ # @return [nil] Write a message to STDOUT.
36
+ #
37
+ # @raise [SystemExit] Terminate execution immediately by calling
38
+ # `Kernel.exit(false)` with a failure message written to STDERR.
39
+ def absolute_requirement(matcher:, negate:)
40
+ valid = negate ^ matcher.matches? { @actual }
41
+
42
+ result(
43
+ actual: @actual,
44
+ error: nil,
45
+ got: valid,
46
+ matcher: matcher,
47
+ negate: negate,
48
+ valid: valid
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end