r_spec 1.0.0.beta2 → 1.0.0.beta7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative File.join("error", "pending_expectation")
4
+ require_relative File.join("error", "reserved_method")
5
+ require_relative File.join("error", "undefined_described_class")
6
+ require_relative File.join("error", "undefined_subject")
7
+
8
+ module RSpec
9
+ # Namespace for exceptions.
10
+ #
11
+ # @api private
12
+ module Error
13
+ end
14
+ 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 reserved methods.
6
+ #
7
+ # @api private
8
+ class ReservedMethod < ::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 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 {Dsl.it} and {Dsl.its}'s helper modules.
8
+ module ExpectationHelper
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "shared"
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 Shared
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 "shared"
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 Shared
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,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 Shared
79
+ include ::Matchi::Helper
80
+ end
81
+ end
82
+ end
@@ -1,93 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "expresenter"
3
+ require_relative File.join("expectation_target", "block")
4
+ require_relative File.join("expectation_target", "value")
4
5
 
5
6
  module RSpec
6
7
  # Wraps the target of an expectation.
7
8
  #
8
- # @example
9
- # expect(something) # => ExpectationTarget wrapping something
10
- #
11
- # # used with `to`
12
- # expect(actual).to be(42)
13
- #
14
- # # with `not_to`
15
- # expect(actual).not_to be(4)
16
- #
17
- # @note `ExpectationTarget` is not intended to be instantiated directly by
18
- # users. Use `expect` instead.
19
- class ExpectationTarget
20
- # Instantiate a new expectation target.
21
- #
22
- # @param actual [#object_id] The actual value.
23
- #
24
- # @api private
25
- def initialize(actual)
26
- @actual = actual
27
- end
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
28
21
 
29
- # Runs the given expectation, passing if `matcher` returns true.
30
- #
31
- # @example _Absolute requirement_ definition
32
- # expect("foo".upcase).to eq("foo")
33
- #
34
- # @param matcher [#matches?] The matcher.
35
- #
36
- # @raise (see #result)
37
- # @return (see #result)
38
- def to(matcher)
39
- absolute_requirement(matcher: matcher, negate: false)
40
- end
22
+ Block.new(block)
23
+ else
24
+ raise ::ArgumentError, "Can't pass both an argument and a block" if block
41
25
 
42
- # Runs the given expectation, passing if `matcher` returns false.
43
- #
44
- # @example _Absolute prohibition_ definition
45
- # expect("foo".size).not_to be(4)
46
- #
47
- # @param (see #to)
48
- #
49
- # @raise (see #result)
50
- # @return (see #result)
51
- def not_to(matcher)
52
- absolute_requirement(matcher: matcher, negate: true)
53
- end
54
-
55
- protected
56
-
57
- # @param matcher [#matches?] The matcher.
58
- # @param negate [Boolean] Positive or negative assertion?
59
- #
60
- # @raise (see #result)
61
- # @return (see #result)
62
- def absolute_requirement(matcher:, negate:)
63
- result(
64
- matcher: matcher,
65
- negate: negate,
66
- passed: negate ^ matcher.matches? { @actual }
67
- )
68
- end
69
-
70
- # @param matcher [#matches?] The matcher.
71
- # @param negate [Boolean] Positive or negative assertion?
72
- # @param passed [Boolean] The result of an expectation.
73
- #
74
- # @return [nil] Write a message to STDOUT.
75
- #
76
- # @raise [SystemExit] Terminate execution immediately by calling
77
- # `Kernel.exit(false)` with a failure message written to STDERR.
78
- def result(matcher:, negate:, passed:)
79
- puts " " + ::Expresenter.call(passed).with(
80
- actual: @actual,
81
- error: nil,
82
- expected: matcher.expected,
83
- got: passed,
84
- negate: negate,
85
- valid: passed,
86
- matcher: matcher.class.to_sym,
87
- level: :MUST
88
- ).colored_string
89
- rescue ::Expresenter::Fail => e
90
- abort " #{e.colored_string}"
26
+ Value.new(value)
27
+ end
91
28
  end
92
29
  end
93
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