r_spec 1.0.0.beta1 → 1.0.0.beta6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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