spectus 3.3.4 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8767313f403c0f015d1316eabbf06f124ef4ecb136f8edf3529d533602622a8c
4
- data.tar.gz: 419a5c0e93edac33135d305e9e384fea7d6ca305d68f9bd268f89d4ead020d3c
3
+ metadata.gz: 45d1a638f042621d43b991c15aea5311a0b370c82f63d37c8fefa6e0a29dba8b
4
+ data.tar.gz: 5bc2409a8d4daeb2e69ca70ac3c6e7d209f4c47a40088c859b545929a2841018
5
5
  SHA512:
6
- metadata.gz: 368fb8f488627e6c5b225bd66416ce4a3c8f61aaab0ce0a68ec6d2f354978393299399ccc4f9ea2c8e719b336764b9b7cededa4f6f237a7e5ad9a1495deb47ef
7
- data.tar.gz: a5e56d1e3c6058f6df75bea0b5d564b0eb2cb6eea620ac9d445bea29a0a45e17302cdddf7cb9b5f7d18609c0b1334527f2495eef264bfb5d9041da453ec1055e
6
+ metadata.gz: 8a5cea6a4c057897592889e4215963176011906d940367e2e62404302ba87bc2fa1550716aba9fe00b8896375f3cb6b4785b2c7d74338c17c3df745c3da4ffb6
7
+ data.tar.gz: 5ad609a281efbde26dacc5e57c3ec0955ce431755bd206aa2617a2bbbba7740bb6730bd22603dfc2ac3159c60f8fea003e9bb0a097ac5755bd01fbb88ac47648
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Spectus
2
2
 
3
- [![Build Status](https://api.travis-ci.org/fixrb/spectus.svg?branch=main)](https://travis-ci.org/fixrb/spectus)
4
- [![Gem Version](https://badge.fury.io/rb/spectus.svg)](https://rubygems.org/gems/spectus)
5
- [![Documentation](https://img.shields.io/:yard-docs-38c800.svg)](https://rubydoc.info/gems/spectus/frames)
3
+ [![Version](https://img.shields.io/github/v/tag/fixrb/spectus?label=Version&logo=github)](https://github.com/fixrb/spectus/releases)
4
+ [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/fixrb/spectus/main)
5
+ [![CI](https://github.com/fixrb/spectus/workflows/CI/badge.svg?branch=main)](https://github.com/fixrb/spectus/actions?query=workflow%3Aci+branch%3Amain)
6
+ [![RuboCop](https://github.com/fixrb/spectus/workflows/RuboCop/badge.svg?branch=main)](https://github.com/fixrb/spectus/actions?query=workflow%3Arubocop+branch%3Amain)
7
+ [![License](https://img.shields.io/github/license/fixrb/spectus?label=License&logo=github)](https://github.com/fixrb/spectus/raw/main/LICENSE.md)
6
8
 
7
9
  > Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) requirement levels 🚥
8
10
 
@@ -26,168 +28,90 @@ Or install it yourself as:
26
28
  gem install spectus
27
29
  ```
28
30
 
29
- ## Overview
30
-
31
- Assuming that an expectation is an assertion that is either `true` or `false`,
32
- qualifying it with `MUST`, `SHOULD` and `MAY`, we can draw up several scenarios:
33
-
34
- | Requirement levels | **MUST** | **SHOULD** | **MAY** |
35
- | ------------------------- | -------- | ---------- | ------- |
36
- | Implemented & Matched | `true` | `true` | `true` |
37
- | Implemented & Not matched | `false` | `true` | `false` |
38
- | Implemented & Exception | `false` | `false` | `false` |
39
- | Not implemented | `false` | `false` | `true` |
40
-
41
- When an expectation is evaluated by Spectus,
42
-
43
- * in case of a _passed_ expectation, a `Spectus::Result::Pass` instance is _returned_;
44
- * in case of a _failed_ expectation, a `Spectus::Result::Fail` exception is _raised_.
45
-
46
31
  ## Usage
47
32
 
48
- The __Spectus__ library is basically a module containing an `it` instance method that accept a block representing the actual value to be evaluated through an expectation.
33
+ The __Spectus__ library is basically a module defining methods that can be used to qualify expectations in specifications.
49
34
 
50
- The `Spectus` module can be included inside a class and used as follows:
35
+ To make __Spectus__ available:
51
36
 
52
37
  ```ruby
53
38
  require "spectus"
54
-
55
- class Spec
56
- include ::Spectus
57
-
58
- attr_reader :subject
59
-
60
- def initialize(subject)
61
- @subject = subject
62
- end
63
-
64
- def test_a
65
- it { subject.upcase }.MUST eql "FOO"
66
- end
67
-
68
- def test_b
69
- it { subject.blank? }.MAY be_true
70
- end
71
-
72
- def test_c
73
- it { subject.length }.SHOULD equal 42
74
- end
75
- end
76
39
  ```
77
40
 
78
- ```ruby
79
- t = Spec.new("foo")
80
-
81
- t.test_a # => Spectus::Result::Pass(actual: "FOO", error: nil, expected: "FOO", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
82
-
83
- t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for "foo":String>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY, valid: false)
41
+ For convenience, we will also instantiate some matchers from the [Matchi library](https://github.com/fixrb/matchi):
84
42
 
85
- t.test_c # => Spectus::Result::Pass(actual: 3, error: nil, expected: 42, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
43
+ ```sh
44
+ gem install matchi
86
45
  ```
87
46
 
88
47
  ```ruby
89
- t = Spec.new(4)
90
-
91
- t.test_a # => raises an exception:
92
- # Traceback (most recent call last):
93
- # 6: from ./bin/console:8:in `<main>'
94
- # 5: from (irb):23
95
- # 4: from (irb):11:in `test_a'
96
- # 3: from /Users/cyril/github/fixrb/spectus/lib/spectus/expectation_target.rb:34:in `MUST'
97
- # 2: from /Users/cyril/github/fixrb/spectus/lib/spectus/requirement_level/base.rb:38:in `call'
98
- # 1: from /Users/cyril/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/expresenter-1.2.1/lib/expresenter/fail.rb:19:in `with'
99
- # Spectus::Result::Fail (NoMethodError: undefined method `upcase' for 4:Integer)
100
-
101
- t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for 4:Integer>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY, valid: false)
102
-
103
- t.test_c # => raises an exception:
104
- # Traceback (most recent call last):
105
- # 6: from ./bin/console:8:in `<main>'
106
- # 5: from (irb):25
107
- # 4: from (irb):19:in `test_c'
108
- # 3: from /Users/cyril/github/fixrb/spectus/lib/spectus/expectation_target.rb:100:in `SHOULD'
109
- # 2: from /Users/cyril/github/fixrb/spectus/lib/spectus/requirement_level/base.rb:38:in `call'
110
- # 1: from /Users/cyril/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/expresenter-1.2.1/lib/expresenter/fail.rb:19:in `with'
111
- # Spectus::Result::Fail (NoMethodError: undefined method `length' for 4:Integer.)
48
+ require "matchi"
112
49
  ```
113
50
 
114
- ## More examples
51
+ All examples here assume that this has been done.
115
52
 
116
53
  ### Absolute Requirement
117
54
 
118
- Given the "`ルビー`" object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
55
+ There is exactly one bat:
119
56
 
120
57
  ```ruby
121
- require "spectus"
122
-
123
- include Spectus
124
-
125
- it { "ルビー".valid_encoding? }.MUST be_true
126
- # => Spectus::Result::Pass(actual: true, error: nil, expected: nil, got: true, matcher: :be_true, negate: false, level: :MUST, valid: true)
58
+ definition = Spectus.must Matchi::Be.new(1)
59
+ definition.call { "🦇".size }
60
+ # => Expresenter::Pass(actual: 1, definition: "be 1", error: nil, expected: 1, got: true, negate: false, level: :MUST)
127
61
  ```
128
62
 
129
- The result of the test shows that the spec passed.
63
+ The test is passed.
130
64
 
131
65
  ### Absolute Prohibition
132
66
 
133
- Given the "`foo`" object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
67
+ Truth and lies:
134
68
 
135
69
  ```ruby
136
- require "spectus"
137
-
138
- include Spectus
139
-
140
- it { "foo".length }.MUST_NOT raise_exception NoMethodError
141
- # => Spectus::Result::Pass(actual: 3, error: nil, expected: NoMethodError, got: true, matcher: :raise_exception, negate: true, level: :MUST, valid: true)
70
+ definition = Spectus.must_not Matchi::Be.new(true)
71
+ definition.call { false }
72
+ # => Expresenter::Pass(actual: false, definition: "be true", error: nil, expected: true, got: true, negate: true, level: :MUST)
142
73
  ```
143
74
 
144
- The result of the test shows that the spec passed.
145
-
146
75
  ### Recommended
147
76
 
148
- Given the `BasicObject` object, when it receives `superclass` method, then it **SHOULD** return the explicit blank class `NilClass`:
77
+ A well-known joke. The addition of `0.1` and `0.2` is deadly precise:
149
78
 
150
79
  ```ruby
151
- require "spectus"
152
-
153
- include Spectus
154
-
155
- it { BasicObject.superclass }.SHOULD equal NilClass
156
- # => Spectus::Result::Pass(actual: nil, error: nil, expected: NilClass, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
80
+ definition = Spectus.should Matchi::Be.new(0.3)
81
+ definition.call { 0.1 + 0.2 }
82
+ # => Expresenter::Pass(actual: 0.30000000000000004, definition: "be 0.3", error: nil, expected: 0.3, got: false, negate: false, level: :SHOULD)
157
83
  ```
158
84
 
159
- Instead of the expected `NilClass` class, its sole instance (which is `nil`) was returned.
160
- However, because there isn't any exception, the result of the test shows that the spec passed.
161
-
162
85
  ### Not Recommended
163
86
 
164
- Given the "`1`" object, when it receives `+(1)` method, then it **SHOULD NOT** return the "`11`" value:
87
+ This should not be wrong:
165
88
 
166
89
  ```ruby
167
- require "spectus"
90
+ definition = Spectus.should_not Matchi::Match.new("123456")
168
91
 
169
- include Spectus
92
+ definition.call do
93
+ require "securerandom"
170
94
 
171
- it { "1" + 1 }.SHOULD_NOT eql "11"
172
- # raise Spectus::Result::Fail(actual: nil, error: #<TypeError: no implicit conversion of Integer into String>, expected: "11", got: nil, matcher: :eql, negate: true, level: :SHOULD, valid: false)
95
+ SecureRandom.hex(3)
96
+ end
97
+ # => Expresenter::Pass(actual: "bb5716", definition: "match \"123456\"", error: nil, expected: "123456", got: true, negate: true, level: :SHOULD)
173
98
  ```
174
99
 
175
- There was a `TypeError` exception, the result of the test shows that the spec failed.
100
+ In any case, as long as there are no exceptions, the test passes.
176
101
 
177
102
  ### Optional
178
103
 
179
- Given the "`foo`" object, when it receives `blank?` method, then it **MAY** be `false`:
104
+ An empty array is blank, right?
180
105
 
181
106
  ```ruby
182
- require "spectus"
183
-
184
- include Spectus
185
-
186
- it { "foo".blank? }.MAY be_false
187
- # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for "foo":String>, expected: nil, got: nil, matcher: :be_false, negate: false, level: :MAY, valid: false)
107
+ definition = Spectus.may Matchi::Be.new(true)
108
+ definition.call { [].blank? }
109
+ # => Expresenter::Pass(actual: nil, definition: "be true", error: #<NoMethodError: undefined method `blank?' for []:Array>, expected: true, got: nil, negate: false, level: :MAY)
188
110
  ```
189
111
 
190
- The optional `blank?` method is not implemented (unlike in [Ruby on Rails](https://api.rubyonrails.org/classes/Object.html#method-i-blank-3F), for instance), so the result of the test shows that the spec passed.
112
+ My bad! ActiveSupport was not imported. 🤦‍♂️
113
+
114
+ Anyways, the test passes because the exception produced is `NoMethodError`, meaning that the functionality is not implemented.
191
115
 
192
116
  ## Code Isolation
193
117
 
@@ -200,26 +124,24 @@ Because they may or may not be desired, each requirement level has 2 versions:
200
124
  Example of test without isolation:
201
125
 
202
126
  ```ruby
203
- require "spectus"
127
+ greeting = "Hello, world!"
204
128
 
205
- include Spectus
129
+ definition = Spectus.must Matchi::Eq.new("Hello, Alice!")
130
+ definition.call { greeting.gsub!("world", "Alice") }
131
+ # => Expresenter::Pass(actual: "Hello, Alice!", definition: "eq \"Hello, Alice!\"", error: nil, expected: "Hello, Alice!", got: true, negate: false, level: :MUST)
206
132
 
207
- greeting = "Hello, world!"
208
- it { greeting.gsub!("world", "Alice") }.MUST eql "Hello, Alice!"
209
- # => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
210
133
  greeting # => "Hello, Alice!"
211
134
  ```
212
135
 
213
136
  Example of test in isolation:
214
137
 
215
138
  ```ruby
216
- require "spectus"
139
+ greeting = "Hello, world!"
217
140
 
218
- include Spectus
141
+ definition = Spectus.must! Matchi::Eq.new("Hello, Alice!")
142
+ definition.call { greeting.gsub!("world", "Alice") }
143
+ # => Expresenter::Pass(actual: "Hello, Alice!", definition: "eq \"Hello, Alice!\"", error: nil, expected: "Hello, Alice!", got: true, negate: false, level: :MUST)
219
144
 
220
- greeting = "Hello, world!"
221
- it { greeting.gsub!("world", "Alice") }.MUST! eql "Hello, Alice!"
222
- # => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
223
145
  greeting # => "Hello, world!"
224
146
  ```
225
147
 
@@ -227,6 +149,7 @@ greeting # => "Hello, world!"
227
149
 
228
150
  * Home page: https://github.com/fixrb/spectus
229
151
  * Bugs/issues: https://github.com/fixrb/spectus/issues
152
+ * Blog post: https://batman.buzz/a-spectus-tutorial-expectations-with-rfc-2119-compliance-1fc769861c1
230
153
 
231
154
  ## Versioning
232
155
 
@@ -234,7 +157,7 @@ __Spectus__ follows [Semantic Versioning 2.0](https://semver.org/).
234
157
 
235
158
  ## License
236
159
 
237
- The [gem](https://rubygems.org/gems/spectus) is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
160
+ The [gem](https://rubygems.org/gems/spectus) is available as open source under the terms of the [MIT License](https://github.com/fixrb/spectus/raw/main/LICENSE.md).
238
161
 
239
162
  ***
240
163
 
data/lib/spectus.rb CHANGED
@@ -1,114 +1,207 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "matchi/helper"
4
-
5
- require_relative File.join("spectus", "expectation_target")
3
+ require_relative File.join("spectus", "requirement")
6
4
 
7
5
  # Namespace for the Spectus library.
8
6
  #
9
- # This module defines the {#it} method to create expectations, which can be
10
- # automatically included into classes.
11
- #
12
- # @example
13
- # class Spec
14
- # include ::Spectus
15
- #
16
- # attr_reader :subject
17
- #
18
- # def initialize(subject)
19
- # @subject = subject
20
- # end
21
- #
22
- # def test_a
23
- # it { subject.upcase }.MUST eql "FOO"
24
- # end
25
- #
26
- # def test_b
27
- # it { subject.blank? }.MAY be_true
28
- # end
29
- #
30
- # def test_c
31
- # it { subject.length }.SHOULD equal 42
32
- # end
33
- # end
34
- #
35
- # t = Spec.new("foo")
36
- # t.test_a # => Spectus::Result::Pass(actual: "FOO", error: nil, expected: "FOO", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
37
- # t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for "foo":String>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY, valid: false)
38
- # t.test_c # => Spectus::Result::Pass(actual: 3, error: nil, expected: 42, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
39
- #
40
- # Or even directly used like this.
41
- #
42
- # @example
43
- # require 'spectus'
44
- #
45
- # include Spectus
46
- #
47
- # it { 42 }.MUST equal 42 # => #<Spectus::Result::Pass...>
48
- #
49
- # It also includes a collection of expectation matchers 🤹
50
- #
51
- # @example Equivalence matcher
52
- # matcher = eql("foo") # => Matchi::Matcher::Eql.new("foo")
53
- # matcher.matches? { "foo" } # => true
54
- # matcher.matches? { "bar" } # => false
55
- #
56
- # @example Identity matcher
57
- # object = "foo"
58
- #
59
- # matcher = equal(object) # => Matchi::Matcher::Equal.new(object)
60
- # matcher.matches? { object } # => true
61
- # matcher.matches? { "foo" } # => false
62
- #
63
- # @example Regular expressions matcher
64
- # matcher = match(/^foo$/) # => Matchi::Matcher::Match.new(/^foo$/)
65
- # matcher.matches? { "foo" } # => true
66
- # matcher.matches? { "bar" } # => false
67
- #
68
- # @example Expecting errors matcher
69
- # matcher = raise_exception(NameError) # => Matchi::Matcher::RaiseException.new(NameError)
70
- # matcher.matches? { Boom } # => true
71
- # matcher.matches? { true } # => false
72
- #
73
- # @example Truth matcher
74
- # matcher = be_true # => Matchi::Matcher::BeTrue.new
75
- # matcher.matches? { true } # => true
76
- # matcher.matches? { false } # => false
77
- # matcher.matches? { nil } # => false
78
- # matcher.matches? { 4 } # => false
79
- #
80
- # @example Untruth matcher
81
- # matcher = be_false # => Matchi::Matcher::BeFalse.new
82
- # matcher.matches? { false } # => true
83
- # matcher.matches? { true } # => false
84
- # matcher.matches? { nil } # => false
85
- # matcher.matches? { 4 } # => false
86
- #
87
- # @example Nil matcher
88
- # matcher = be_nil # => Matchi::Matcher::BeNil.new
89
- # matcher.matches? { nil } # => true
90
- # matcher.matches? { false } # => false
91
- # matcher.matches? { true } # => false
92
- # matcher.matches? { 4 } # => false
93
- #
94
- # @example Type/class matcher
95
- # matcher = be_an_instance_of(String) # => Matchi::Matcher::BeAnInstanceOf.new(String)
96
- # matcher.matches? { "foo" } # => true
97
- # matcher.matches? { 4 } # => false
98
- #
99
- # @see https://github.com/fixrb/matchi
7
+ # This module defines methods that can be used to qualify expectations in
8
+ # specifications.
100
9
  module Spectus
101
- include ::Matchi::Helper
10
+ # This method mean that the definition is an absolute requirement of the
11
+ # specification.
12
+ #
13
+ # @example An absolute requirement definition
14
+ # require "spectus"
15
+ # require "matchi/eq"
16
+ #
17
+ # Spectus.must Matchi::Eq.new("FOO")
18
+ # # => #<MUST Matchi::Eq("FOO") isolate=false negate=false>
19
+ #
20
+ # @param matcher [#matches?] The matcher.
21
+ #
22
+ # @return [Requirement::Required] An absolute requirement level instance.
23
+ #
24
+ # @api public
25
+ def self.must(matcher)
26
+ Requirement::Required.new(
27
+ isolate: false,
28
+ negate: false,
29
+ matcher: matcher
30
+ )
31
+ end
32
+
33
+ # @example An absolute requirement definition with isolation
34
+ # require "spectus"
35
+ # require "matchi/eq"
36
+ #
37
+ # Spectus.must! Matchi::Eq.new("FOO")
38
+ # # => #<MUST Matchi::Eq("FOO") isolate=true negate=false>
39
+ #
40
+ # @see must
41
+ def self.must!(matcher)
42
+ Requirement::Required.new(
43
+ isolate: true,
44
+ negate: false,
45
+ matcher: matcher
46
+ )
47
+ end
48
+
49
+ # This method mean that the definition is an absolute prohibition of the specification.
50
+ #
51
+ # @example An absolute prohibition definition
52
+ # require "spectus"
53
+ # require "matchi/be"
54
+ #
55
+ # Spectus.must_not Matchi::Be.new(42)
56
+ # # => #<MUST Matchi::Be(42) isolate=false negate=true>
57
+ #
58
+ # @param matcher [#matches?] The matcher.
59
+ #
60
+ # @return [Requirement::Required] An absolute prohibition level instance.
61
+ def self.must_not(matcher)
62
+ Requirement::Required.new(
63
+ isolate: false,
64
+ negate: true,
65
+ matcher: matcher
66
+ )
67
+ end
68
+
69
+ # @example An absolute prohibition definition with isolation
70
+ # require "spectus"
71
+ # require "matchi/be"
72
+ #
73
+ # Spectus.must_not! Matchi::Be.new(42)
74
+ # # => #<MUST Matchi::Be(42) isolate=true negate=true>
75
+ #
76
+ # @see must_not
77
+ def self.must_not!(matcher)
78
+ Requirement::Required.new(
79
+ isolate: true,
80
+ negate: true,
81
+ matcher: matcher
82
+ )
83
+ end
84
+
85
+ # This method mean that there may exist valid reasons in particular
86
+ # circumstances to ignore a particular item, but the full implications must be
87
+ # understood and carefully weighed before choosing a different course.
88
+ #
89
+ # @example A recommended definition
90
+ # require "spectus"
91
+ # require "matchi/be"
92
+ #
93
+ # Spectus.should Matchi::Be.new(true)
94
+ # # => #<SHOULD Matchi::Be(true) isolate=false negate=false>
95
+ #
96
+ # @param matcher [#matches?] The matcher.
97
+ #
98
+ # @return [Requirement::Recommended] A recommended requirement level instance.
99
+ def self.should(matcher)
100
+ Requirement::Recommended.new(
101
+ isolate: false,
102
+ negate: false,
103
+ matcher: matcher
104
+ )
105
+ end
106
+
107
+ # @example A recommended definition with isolation
108
+ # require "spectus"
109
+ # require "matchi/be"
110
+ #
111
+ # Spectus.should! Matchi::Be.new(true)
112
+ # # => #<SHOULD Matchi::Be(true) isolate=true negate=false>
113
+ #
114
+ # @see should
115
+ def self.should!(matcher)
116
+ Requirement::Recommended.new(
117
+ isolate: true,
118
+ negate: false,
119
+ matcher: matcher
120
+ )
121
+ end
102
122
 
103
- # Expectations are built with this method.
123
+ # This method mean that there may exist valid reasons in particular
124
+ # circumstances when the particular behavior is acceptable or even useful, but
125
+ # the full implications should be understood and the case carefully weighed
126
+ # before implementing any behavior described with this label.
127
+ #
128
+ # @example A not recommended definition
129
+ # require "spectus"
130
+ # require "matchi/raise_exception"
131
+ #
132
+ # Spectus.should_not Matchi::RaiseException.new(NoMethodError)
133
+ # # => #<SHOULD Matchi::RaiseException(NoMethodError) isolate=false negate=true>
134
+ #
135
+ # @param matcher [#matches?] The matcher.
136
+ #
137
+ # @return [Requirement::Recommended] A not recommended requirement level
138
+ # instance.
139
+ def self.should_not(matcher)
140
+ Requirement::Recommended.new(
141
+ isolate: false,
142
+ negate: true,
143
+ matcher: matcher
144
+ )
145
+ end
146
+
147
+ # @example A not recommended definition with isolation
148
+ # require "spectus"
149
+ # require "matchi/raise_exception"
150
+ #
151
+ # Spectus.should_not! Matchi::RaiseException.new(NoMethodError)
152
+ # # => #<SHOULD Matchi::RaiseException(NoMethodError) isolate=true negate=true>
104
153
  #
105
- # @example An _absolute requirement_ definition.
106
- # it { 42 }.MUST equal 42 # => #<Spectus::Result::Pass...>
154
+ # @see should_not
155
+ def self.should_not!(matcher)
156
+ Requirement::Recommended.new(
157
+ isolate: true,
158
+ negate: true,
159
+ matcher: matcher
160
+ )
161
+ end
162
+
163
+ # This method mean that an item is truly optional.
164
+ # One vendor may choose to include the item because a particular marketplace
165
+ # requires it or because the vendor feels that it enhances the product while
166
+ # another vendor may omit the same item. An implementation which does not
167
+ # include a particular option must be prepared to interoperate with another
168
+ # implementation which does include the option, though perhaps with reduced
169
+ # functionality. In the same vein an implementation which does include a
170
+ # particular option must be prepared to interoperate with another
171
+ # implementation which does not include the option (except, of course, for the
172
+ # feature the option provides).
173
+ #
174
+ # @example An optional definition
175
+ # require "spectus"
176
+ # require "matchi/match"
177
+ #
178
+ # Spectus.may Matchi::Match.new(/^foo$/)
179
+ # # => #<MAY Matchi::Match(/^foo$/) isolate=false negate=false>
180
+ #
181
+ # @param matcher [#matches?] The matcher.
182
+ #
183
+ # @return [Requirement::Optional] An optional requirement level instance.
184
+ def self.may(matcher)
185
+ Requirement::Optional.new(
186
+ isolate: false,
187
+ negate: false,
188
+ matcher: matcher
189
+ )
190
+ end
191
+
192
+ # @example An optional definition with isolation
193
+ # require "spectus"
194
+ # require "matchi/match"
107
195
  #
108
- # @param input [Proc] The code to test.
196
+ # Spectus.may! Matchi::Match.new(/^foo$/)
197
+ # # => #<MAY Matchi::Match(/^foo$/) isolate=true negate=false>
109
198
  #
110
- # @return [ExpectationTarget] The expectation target.
111
- def it(&input)
112
- ExpectationTarget.new(&input)
199
+ # @see may
200
+ def self.may!(matcher)
201
+ Requirement::Optional.new(
202
+ isolate: true,
203
+ negate: false,
204
+ matcher: matcher
205
+ )
113
206
  end
114
207
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spectus
4
+ # Namespace for the results.
5
+ #
6
+ # @api private
7
+ module Requirement
8
+ end
9
+ end
10
+
11
+ require_relative File.join("requirement", "required")
12
+ require_relative File.join("requirement", "recommended")
13
+ require_relative File.join("requirement", "optional")
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "expresenter"
4
+ require "test_tube"
5
+
6
+ module Spectus
7
+ # Namespace for the requirement levels.
8
+ module Requirement
9
+ # Requirement level's base class.
10
+ class Base
11
+ # Initialize the requirement level class.
12
+ #
13
+ # @param isolate [Boolean] Compute actual in a subprocess.
14
+ # @param matcher [#matches?] The matcher.
15
+ # @param negate [Boolean] Invert the matcher or not.
16
+ def initialize(isolate:, matcher:, negate:)
17
+ @isolate = isolate
18
+ @matcher = matcher
19
+ @negate = negate
20
+ end
21
+
22
+ # Test result.
23
+ #
24
+ # @raise [::Expresenter::Fail] A failed spec exception.
25
+ # @return [::Expresenter::Pass] A passed spec instance.
26
+ #
27
+ # @see https://github.com/fixrb/expresenter
28
+ #
29
+ # @api public
30
+ def call(&block)
31
+ test = ::TestTube.invoke(isolate: @isolate, matcher: @matcher, negate: @negate, &block)
32
+
33
+ ::Expresenter.call(passed?(test)).with(
34
+ actual: test.actual,
35
+ definition: @matcher.to_s,
36
+ error: test.error,
37
+ expected: @matcher.expected,
38
+ got: test.got,
39
+ level: self.class.level,
40
+ negate: @negate
41
+ )
42
+ end
43
+
44
+ # :nocov:
45
+
46
+ # A string containing a human-readable representation of the definition.
47
+ #
48
+ # @example The human-readable representation of an absolute requirement.
49
+ # require "spectus"
50
+ # require "matchi/be"
51
+ #
52
+ # definition = Spectus.must Matchi::Be.new(1)
53
+ # definition.inspect
54
+ # # => "#<MUST Matchi::Be(1) isolate=false negate=false>"
55
+ #
56
+ # @return [String] The human-readable representation of the definition.
57
+ #
58
+ # @api public
59
+ def inspect
60
+ "#<#{self.class.level} #{@matcher.inspect} isolate=#{@isolate} negate=#{@negate}>"
61
+ end
62
+
63
+ # :nocov:
64
+
65
+ private
66
+
67
+ # Code experiment result.
68
+ #
69
+ # @param test [::TestTube::Base] The state of the experiment.
70
+ #
71
+ # @see https://github.com/fixrb/test_tube
72
+ #
73
+ # @return [Boolean] The result of the test (passed or failed).
74
+ def passed?(test)
75
+ test.got.equal?(true)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Spectus
6
+ module Requirement
7
+ # Optional requirement level.
8
+ class Optional < Base
9
+ # Key word for use in RFCs to indicate requirement levels.
10
+ #
11
+ # @return [Symbol] The requirement level.
12
+ def self.level
13
+ :MAY
14
+ end
15
+
16
+ private
17
+
18
+ # Code experiment result.
19
+ #
20
+ # @param (see Base#passed?)
21
+ #
22
+ # @return (see Base#passed?)
23
+ def passed?(test)
24
+ super || test.error.is_a?(::NoMethodError)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Spectus
6
+ module Requirement
7
+ # Recommended and not recommended requirement levels.
8
+ class Recommended < Base
9
+ # Key word for use in RFCs to indicate requirement levels.
10
+ #
11
+ # @return [Symbol] The requirement level.
12
+ def self.level
13
+ :SHOULD
14
+ end
15
+
16
+ private
17
+
18
+ # Code experiment result.
19
+ #
20
+ # @param (see Base#passed?)
21
+ #
22
+ # @return (see Base#passed?)
23
+ def passed?(test)
24
+ super || test.error.nil?
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Spectus
6
+ module Requirement
7
+ # Absolute requirement and absolute prohibition levels.
8
+ class Required < Base
9
+ # Key word for use in RFCs to indicate requirement levels.
10
+ #
11
+ # @return [Symbol] The requirement level.
12
+ def self.level
13
+ :MUST
14
+ end
15
+ end
16
+ end
17
+ end
metadata CHANGED
@@ -1,59 +1,59 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectus
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.4
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-16 00:00:00.000000000 Z
11
+ date: 2021-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: defi
14
+ name: expresenter
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.5
19
+ version: 1.4.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.5
26
+ version: 1.4.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: expresenter
28
+ name: test_tube
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.2.1
33
+ version: 2.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.2.1
40
+ version: 2.1.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: matchi
42
+ name: brutal
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 2.1.0
48
- type: :runtime
47
+ version: '0'
48
+ type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 2.1.0
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: brutal
56
+ name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: matchi
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -187,15 +187,11 @@ files:
187
187
  - LICENSE.md
188
188
  - README.md
189
189
  - lib/spectus.rb
190
- - lib/spectus/exam.rb
191
- - lib/spectus/expectation_target.rb
192
- - lib/spectus/requirement_level/base.rb
193
- - lib/spectus/requirement_level/may.rb
194
- - lib/spectus/requirement_level/must.rb
195
- - lib/spectus/requirement_level/should.rb
196
- - lib/spectus/result.rb
197
- - lib/spectus/result/fail.rb
198
- - lib/spectus/result/pass.rb
190
+ - lib/spectus/requirement.rb
191
+ - lib/spectus/requirement/base.rb
192
+ - lib/spectus/requirement/optional.rb
193
+ - lib/spectus/requirement/recommended.rb
194
+ - lib/spectus/requirement/required.rb
199
195
  homepage: https://github.com/fixrb/spectus
200
196
  licenses:
201
197
  - MIT
data/lib/spectus/exam.rb DELETED
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "defi"
4
-
5
- module Spectus
6
- # This class evaluate the expectation with the passed block.
7
- class Exam
8
- # Execute the untested code from the passed block against the matcher.
9
- #
10
- # rubocop:disable Lint/RescueException
11
- #
12
- # @param callable [#call] The callable object to test.
13
- # @param isolation [Boolean] Compute actual in isolation?
14
- # @param negate [Boolean] Positive or negative assertion?
15
- # @param matcher [#matches?] The matcher.
16
- def initialize(callable:, isolation:, negate:, matcher:)
17
- @got = negate ^ matcher.matches? do
18
- value = if isolation
19
- send_call.to!(callable)
20
- else
21
- send_call.to(callable)
22
- end
23
-
24
- @actual = value.object
25
-
26
- value.call
27
- end
28
- rescue ::Exception => e
29
- @actual = nil
30
- @exception = e
31
- end
32
- # rubocop:enable Lint/RescueException
33
-
34
- # @return [#object_id] The actual value.
35
- attr_reader :actual
36
-
37
- # @return [Exception, nil] An exception.
38
- attr_reader :exception
39
-
40
- # @return [Boolean, nil] Report to the spec requirement level if the
41
- # expectation is true or false.
42
- attr_reader :got
43
-
44
- # @return [Defi::Challenge] The challenge for the callable object.
45
- def send_call
46
- ::Defi.send(:call)
47
- end
48
-
49
- # Report to the spec requirement level if the test pass or fail.
50
- #
51
- # @return [Boolean] Report if the test pass or fail?
52
- def valid?
53
- exception.nil? ? got : false
54
- end
55
- end
56
- end
@@ -1,202 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative File.join("requirement_level", "must")
4
- require_relative File.join("requirement_level", "should")
5
- require_relative File.join("requirement_level", "may")
6
-
7
- module Spectus
8
- # Wraps the target of an expectation.
9
- #
10
- # @example
11
- # it { actual value } # => ExpectationTarget wrapping the block
12
- class ExpectationTarget
13
- # Create a new expectation target
14
- #
15
- # @param callable [Proc] The object to test.
16
- def initialize(&callable)
17
- @callable = callable
18
- end
19
-
20
- # rubocop:disable Naming/MethodName
21
-
22
- # This word, or the terms "REQUIRED" or "SHALL", mean that the
23
- # definition is an absolute requirement of the specification.
24
- #
25
- # @example _Absolute requirement_ definition
26
- # it { "foo".upcase }.MUST eql 'FOO'
27
- #
28
- # @param matcher [#matches?] The matcher.
29
- #
30
- # @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
31
- # pass or fail.
32
- def MUST(matcher)
33
- RequirementLevel::Must.new(
34
- callable: callable,
35
- isolation: false,
36
- negate: false,
37
- matcher: matcher
38
- ).call
39
- end
40
-
41
- # @example _Absolute requirement_ definition with isolation
42
- # it { "foo".upcase }.MUST! eql 'FOO'
43
- #
44
- # @see MUST
45
- def MUST!(matcher)
46
- RequirementLevel::Must.new(
47
- callable: callable,
48
- isolation: true,
49
- negate: false,
50
- matcher: matcher
51
- ).call
52
- end
53
-
54
- # This phrase, or the phrase "SHALL NOT", mean that the
55
- # definition is an absolute prohibition of the specification.
56
- #
57
- # @example _Absolute prohibition_ definition
58
- # it { "foo".size }.MUST_NOT equal 42
59
- #
60
- # @param matcher [#matches?] The matcher.
61
- #
62
- # @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
63
- # pass or fail.
64
- def MUST_NOT(matcher)
65
- RequirementLevel::Must.new(
66
- callable: callable,
67
- isolation: false,
68
- negate: true,
69
- matcher: matcher
70
- ).call
71
- end
72
-
73
- # @example _Absolute prohibition_ definition with isolation
74
- # it { "foo".size }.MUST_NOT! equal 42
75
- #
76
- # @see MUST_NOT
77
- def MUST_NOT!(matcher)
78
- RequirementLevel::Must.new(
79
- callable: callable,
80
- isolation: true,
81
- negate: true,
82
- matcher: matcher
83
- ).call
84
- end
85
-
86
- # This word, or the adjective "RECOMMENDED", mean that there
87
- # may exist valid reasons in particular circumstances to ignore a
88
- # particular item, but the full implications must be understood and
89
- # carefully weighed before choosing a different course.
90
- #
91
- # @example _Recommended_ definition
92
- # it { "foo".valid_encoding? }.SHOULD equal true
93
- #
94
- # @param matcher [#matches?] The matcher.
95
- #
96
- # @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
97
- # pass or fail.
98
- def SHOULD(matcher)
99
- RequirementLevel::Should.new(
100
- callable: callable,
101
- isolation: false,
102
- negate: false,
103
- matcher: matcher
104
- ).call
105
- end
106
-
107
- # @example _Recommended_ definition with isolation
108
- # it { "foo".valid_encoding? }.SHOULD! equal true
109
- #
110
- # @see SHOULD
111
- def SHOULD!(matcher)
112
- RequirementLevel::Should.new(
113
- callable: callable,
114
- isolation: true,
115
- negate: false,
116
- matcher: matcher
117
- ).call
118
- end
119
-
120
- # This phrase, or the phrase "NOT RECOMMENDED" mean that
121
- # there may exist valid reasons in particular circumstances when the
122
- # particular behavior is acceptable or even useful, but the full
123
- # implications should be understood and the case carefully weighed
124
- # before implementing any behavior described with this label.
125
- #
126
- # @example _Not recommended_ definition
127
- # it { "".blank? }.SHOULD_NOT raise_exception NoMethodError
128
- #
129
- # @param matcher [#matches?] The matcher.
130
- #
131
- # @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
132
- # pass or fail.
133
- def SHOULD_NOT(matcher)
134
- RequirementLevel::Should.new(
135
- callable: callable,
136
- isolation: false,
137
- negate: true,
138
- matcher: matcher
139
- ).call
140
- end
141
-
142
- # @example _Not recommended_ definition with isolation
143
- # it { "".blank? }.SHOULD_NOT! raise_exception NoMethodError
144
- #
145
- # @see SHOULD_NOT
146
- def SHOULD_NOT!(matcher)
147
- RequirementLevel::Should.new(
148
- callable: callable,
149
- isolation: true,
150
- negate: true,
151
- matcher: matcher
152
- ).call
153
- end
154
-
155
- # This word, or the adjective "OPTIONAL", mean that an item is
156
- # truly optional. One vendor may choose to include the item because a
157
- # particular marketplace requires it or because the vendor feels that
158
- # it enhances the product while another vendor may omit the same item.
159
- # An implementation which does not include a particular option MUST be
160
- # prepared to interoperate with another implementation which does
161
- # include the option, though perhaps with reduced functionality. In the
162
- # same vein an implementation which does include a particular option
163
- # MUST be prepared to interoperate with another implementation which
164
- # does not include the option (except, of course, for the feature the
165
- # option provides.)
166
- #
167
- # @example _Optional_ definition
168
- # it { "foo".bar }.MAY match /^foo$/
169
- #
170
- # @param matcher [#matches?] The matcher.
171
- #
172
- # @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec pass or fail.
173
- def MAY(matcher)
174
- RequirementLevel::May.new(
175
- callable: callable,
176
- isolation: false,
177
- negate: false,
178
- matcher: matcher
179
- ).call
180
- end
181
-
182
- # @example _Optional_ definition with isolation
183
- # it { "foo".bar }.MAY! match /^foo$/
184
- #
185
- # @see MAY
186
- def MAY!(matcher)
187
- RequirementLevel::May.new(
188
- callable: callable,
189
- isolation: true,
190
- negate: false,
191
- matcher: matcher
192
- ).call
193
- end
194
-
195
- # rubocop:enable Naming/MethodName
196
-
197
- protected
198
-
199
- # @return [#call] The callable object to test.
200
- attr_reader :callable
201
- end
202
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative File.join("..", "exam")
4
- require_relative File.join("..", "result")
5
-
6
- module Spectus
7
- # Namespace for the requirement levels.
8
- module RequirementLevel
9
- # Requirement level's base class.
10
- class Base
11
- # Initialize the requirement level class.
12
- #
13
- # @param callable [#call] The callable object to test.
14
- # @param isolation [Boolean] Compute actual in isolation?
15
- # @param negate [Boolean] Positive or negative assertion?
16
- # @param matcher [#matches?] The matcher.
17
- def initialize(callable:, isolation:, negate:, matcher:)
18
- @negate = negate
19
- @matcher = matcher
20
-
21
- @exam = Exam.new(
22
- callable: callable,
23
- isolation: isolation,
24
- negate: negate,
25
- matcher: matcher
26
- )
27
- end
28
-
29
- # @return [#Exam] The exam.
30
- attr_reader :exam
31
-
32
- # @return [#matches?] The matcher that performed a boolean comparison
33
- # between the actual value and the expected value.
34
- attr_reader :matcher
35
-
36
- # The result of the expectation.
37
- #
38
- # @raise [Spectus::Result::Fail] The expectation failed.
39
- # @return [Spectus::Result::Pass] The expectation passed.
40
- def call
41
- Result.call(pass?).with(
42
- actual: exam.actual,
43
- error: exam.exception,
44
- expected: matcher.expected,
45
- got: exam.got,
46
- negate: negate?,
47
- valid: exam.valid?,
48
- matcher: matcher.class.to_sym,
49
- level: level
50
- )
51
- end
52
-
53
- protected
54
-
55
- # @return [Symbol] The requirement level.
56
- def level
57
- self.class.name.split("::").fetch(-1).upcase.to_sym
58
- end
59
-
60
- # @note The boolean comparison between the actual value and the expected
61
- # value can be evaluated to a negative assertion.
62
- #
63
- # @return [Boolean] Positive or negative assertion?
64
- def negate?
65
- @negate
66
- end
67
- end
68
- end
69
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "must"
4
-
5
- module Spectus
6
- module RequirementLevel
7
- # May requirement level's class.
8
- class May < Must
9
- # Evaluate the expectation.
10
- #
11
- # @return [Boolean] Report if the low expectation pass or fail?
12
- def pass?
13
- super || exam.exception.is_a?(::NoMethodError)
14
- end
15
- end
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "base"
4
-
5
- module Spectus
6
- module RequirementLevel
7
- # Must requirement level's class.
8
- class Must < Base
9
- # Evaluate the expectation.
10
- #
11
- # @return [Boolean] Report if the high expectation pass or fail?
12
- def pass?
13
- exam.valid?
14
- end
15
- end
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "must"
4
-
5
- module Spectus
6
- module RequirementLevel
7
- # Should requirement level's class.
8
- class Should < Must
9
- # Evaluate the expectation.
10
- #
11
- # @return [Boolean] Report if the medium expectation pass or fail?
12
- def pass?
13
- super || exam.exception.nil?
14
- end
15
- end
16
- end
17
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative File.join("result", "fail")
4
- require_relative File.join("result", "pass")
5
-
6
- module Spectus
7
- # Namespace for the results.
8
- module Result
9
- # @param is_passed [Boolean] The value of an assertion.
10
- # @return [Class<Spectus::Result::Pass>, Class<Spectus::Result::Fail>] The
11
- # class of the result.
12
- # @example Get the pass class result.
13
- # call(true) # => Pass
14
- def self.call(is_passed)
15
- is_passed ? Pass : Fail
16
- end
17
- end
18
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "expresenter/fail"
4
-
5
- module Spectus
6
- module Result
7
- # The class that is responsible for reporting that the expectation is false.
8
- #
9
- # @see https://github.com/fixrb/expresenter/blob/v1.2.1/lib/expresenter/fail.rb
10
- class Fail < ::Expresenter::Fail
11
- end
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "expresenter/pass"
4
-
5
- module Spectus
6
- module Result
7
- # The class that is responsible for reporting that the expectation is true.
8
- #
9
- # @see https://github.com/fixrb/expresenter/blob/v1.2.1/lib/expresenter/pass.rb
10
- class Pass < ::Expresenter::Pass
11
- end
12
- end
13
- end