r_spec 1.0.0.beta2 → 1.0.0.beta7

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,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