spectus 3.3.4 → 4.0.2

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