spectus 3.2.0 → 3.3.4
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 +4 -4
- data/README.md +125 -29
- data/lib/spectus.rb +93 -5
- data/lib/spectus/expectation_target.rb +23 -19
- data/lib/spectus/requirement_level/base.rb +5 -6
- data/lib/spectus/result.rb +18 -0
- data/lib/spectus/result/fail.rb +13 -0
- data/lib/spectus/result/pass.rb +13 -0
- metadata +12 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8767313f403c0f015d1316eabbf06f124ef4ecb136f8edf3529d533602622a8c
|
4
|
+
data.tar.gz: 419a5c0e93edac33135d305e9e384fea7d6ca305d68f9bd268f89d4ead020d3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 368fb8f488627e6c5b225bd66416ce4a3c8f61aaab0ce0a68ec6d2f354978393299399ccc4f9ea2c8e719b336764b9b7cededa4f6f237a7e5ad9a1495deb47ef
|
7
|
+
data.tar.gz: a5e56d1e3c6058f6df75bea0b5d564b0eb2cb6eea620ac9d445bea29a0a45e17302cdddf7cb9b5f7d18609c0b1334527f2495eef264bfb5d9041da453ec1055e
|
data/README.md
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# Spectus
|
2
2
|
|
3
|
-
[]
|
4
|
-
[][inchpages]
|
7
|
-
[][rubydoc]
|
3
|
+
[](https://travis-ci.org/fixrb/spectus)
|
4
|
+
[](https://rubygems.org/gems/spectus)
|
5
|
+
[](https://rubydoc.info/gems/spectus/frames)
|
8
6
|
|
9
|
-
> Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)
|
7
|
+
> Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) requirement levels 🚥
|
10
8
|
|
11
9
|
## Installation
|
12
10
|
|
@@ -18,27 +16,114 @@ gem "spectus"
|
|
18
16
|
|
19
17
|
And then execute:
|
20
18
|
|
21
|
-
|
19
|
+
```sh
|
20
|
+
bundle
|
21
|
+
```
|
22
22
|
|
23
23
|
Or install it yourself as:
|
24
24
|
|
25
|
-
|
25
|
+
```sh
|
26
|
+
gem install spectus
|
27
|
+
```
|
28
|
+
|
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_.
|
26
45
|
|
27
46
|
## Usage
|
28
47
|
|
29
|
-
|
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.
|
49
|
+
|
50
|
+
The `Spectus` module can be included inside a class and used as follows:
|
30
51
|
|
31
52
|
```ruby
|
32
|
-
|
53
|
+
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
|
+
```
|
77
|
+
|
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)
|
84
|
+
|
85
|
+
t.test_c # => Spectus::Result::Pass(actual: 3, error: nil, expected: 42, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
|
86
|
+
```
|
87
|
+
|
88
|
+
```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.)
|
33
112
|
```
|
34
113
|
|
114
|
+
## More examples
|
115
|
+
|
35
116
|
### Absolute Requirement
|
36
117
|
|
37
118
|
Given the "`ルビー`" object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
|
38
119
|
|
39
120
|
```ruby
|
121
|
+
require "spectus"
|
122
|
+
|
123
|
+
include Spectus
|
124
|
+
|
40
125
|
it { "ルビー".valid_encoding? }.MUST be_true
|
41
|
-
# =>
|
126
|
+
# => Spectus::Result::Pass(actual: true, error: nil, expected: nil, got: true, matcher: :be_true, negate: false, level: :MUST, valid: true)
|
42
127
|
```
|
43
128
|
|
44
129
|
The result of the test shows that the spec passed.
|
@@ -48,8 +133,12 @@ The result of the test shows that the spec passed.
|
|
48
133
|
Given the "`foo`" object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
|
49
134
|
|
50
135
|
```ruby
|
136
|
+
require "spectus"
|
137
|
+
|
138
|
+
include Spectus
|
139
|
+
|
51
140
|
it { "foo".length }.MUST_NOT raise_exception NoMethodError
|
52
|
-
# =>
|
141
|
+
# => Spectus::Result::Pass(actual: 3, error: nil, expected: NoMethodError, got: true, matcher: :raise_exception, negate: true, level: :MUST, valid: true)
|
53
142
|
```
|
54
143
|
|
55
144
|
The result of the test shows that the spec passed.
|
@@ -59,8 +148,12 @@ The result of the test shows that the spec passed.
|
|
59
148
|
Given the `BasicObject` object, when it receives `superclass` method, then it **SHOULD** return the explicit blank class `NilClass`:
|
60
149
|
|
61
150
|
```ruby
|
151
|
+
require "spectus"
|
152
|
+
|
153
|
+
include Spectus
|
154
|
+
|
62
155
|
it { BasicObject.superclass }.SHOULD equal NilClass
|
63
|
-
# =>
|
156
|
+
# => Spectus::Result::Pass(actual: nil, error: nil, expected: NilClass, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
|
64
157
|
```
|
65
158
|
|
66
159
|
Instead of the expected `NilClass` class, its sole instance (which is `nil`) was returned.
|
@@ -71,8 +164,12 @@ However, because there isn't any exception, the result of the test shows that th
|
|
71
164
|
Given the "`1`" object, when it receives `+(1)` method, then it **SHOULD NOT** return the "`11`" value:
|
72
165
|
|
73
166
|
```ruby
|
167
|
+
require "spectus"
|
168
|
+
|
169
|
+
include Spectus
|
170
|
+
|
74
171
|
it { "1" + 1 }.SHOULD_NOT eql "11"
|
75
|
-
# raise
|
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)
|
76
173
|
```
|
77
174
|
|
78
175
|
There was a `TypeError` exception, the result of the test shows that the spec failed.
|
@@ -82,17 +179,16 @@ There was a `TypeError` exception, the result of the test shows that the spec fa
|
|
82
179
|
Given the "`foo`" object, when it receives `blank?` method, then it **MAY** be `false`:
|
83
180
|
|
84
181
|
```ruby
|
182
|
+
require "spectus"
|
183
|
+
|
184
|
+
include Spectus
|
185
|
+
|
85
186
|
it { "foo".blank? }.MAY be_false
|
86
|
-
# =>
|
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)
|
87
188
|
```
|
88
189
|
|
89
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.
|
90
191
|
|
91
|
-
### More Examples
|
92
|
-
|
93
|
-
A full list of unit tests can be viewed (and executed) here:
|
94
|
-
[./test.rb](https://github.com/fixrb/spectus/blob/main/test.rb)
|
95
|
-
|
96
192
|
## Code Isolation
|
97
193
|
|
98
194
|
When executing expectations, side-effects may occur.
|
@@ -104,20 +200,26 @@ Because they may or may not be desired, each requirement level has 2 versions:
|
|
104
200
|
Example of test without isolation:
|
105
201
|
|
106
202
|
```ruby
|
203
|
+
require "spectus"
|
204
|
+
|
107
205
|
include Spectus
|
206
|
+
|
108
207
|
greeting = "Hello, world!"
|
109
208
|
it { greeting.gsub!("world", "Alice") }.MUST eql "Hello, Alice!"
|
110
|
-
# =>
|
209
|
+
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
111
210
|
greeting # => "Hello, Alice!"
|
112
211
|
```
|
113
212
|
|
114
213
|
Example of test in isolation:
|
115
214
|
|
116
215
|
```ruby
|
216
|
+
require "spectus"
|
217
|
+
|
117
218
|
include Spectus
|
219
|
+
|
118
220
|
greeting = "Hello, world!"
|
119
221
|
it { greeting.gsub!("world", "Alice") }.MUST! eql "Hello, Alice!"
|
120
|
-
# =>
|
222
|
+
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
121
223
|
greeting # => "Hello, world!"
|
122
224
|
```
|
123
225
|
|
@@ -132,7 +234,7 @@ __Spectus__ follows [Semantic Versioning 2.0](https://semver.org/).
|
|
132
234
|
|
133
235
|
## License
|
134
236
|
|
135
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
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).
|
136
238
|
|
137
239
|
***
|
138
240
|
|
@@ -142,9 +244,3 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
142
244
|
src="https://github.com/fixrb/spectus/raw/main/img/sashite.png"
|
143
245
|
alt="Sashite" /></a>
|
144
246
|
</p>
|
145
|
-
|
146
|
-
[gem]: https://rubygems.org/gems/spectus
|
147
|
-
[travis]: https://travis-ci.org/fixrb/spectus
|
148
|
-
[codeclimate]: https://codeclimate.com/github/fixrb/spectus
|
149
|
-
[inchpages]: https://inch-ci.org/github/fixrb/spectus
|
150
|
-
[rubydoc]: https://rubydoc.info/gems/spectus/frames
|
data/lib/spectus.rb
CHANGED
@@ -2,18 +2,108 @@
|
|
2
2
|
|
3
3
|
require "matchi/helper"
|
4
4
|
|
5
|
+
require_relative File.join("spectus", "expectation_target")
|
6
|
+
|
5
7
|
# Namespace for the Spectus library.
|
6
8
|
#
|
7
|
-
#
|
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
|
8
43
|
# require 'spectus'
|
9
|
-
#
|
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
|
10
100
|
module Spectus
|
11
101
|
include ::Matchi::Helper
|
12
102
|
|
13
103
|
# Expectations are built with this method.
|
14
104
|
#
|
15
105
|
# @example An _absolute requirement_ definition.
|
16
|
-
# it { 42 }.MUST equal 42 # => #<
|
106
|
+
# it { 42 }.MUST equal 42 # => #<Spectus::Result::Pass...>
|
17
107
|
#
|
18
108
|
# @param input [Proc] The code to test.
|
19
109
|
#
|
@@ -22,5 +112,3 @@ module Spectus
|
|
22
112
|
ExpectationTarget.new(&input)
|
23
113
|
end
|
24
114
|
end
|
25
|
-
|
26
|
-
require_relative File.join("spectus", "expectation_target")
|
@@ -1,5 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
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
|
+
|
3
7
|
module Spectus
|
4
8
|
# Wraps the target of an expectation.
|
5
9
|
#
|
@@ -19,11 +23,12 @@ module Spectus
|
|
19
23
|
# definition is an absolute requirement of the specification.
|
20
24
|
#
|
21
25
|
# @example _Absolute requirement_ definition
|
22
|
-
# it {
|
26
|
+
# it { "foo".upcase }.MUST eql 'FOO'
|
23
27
|
#
|
24
28
|
# @param matcher [#matches?] The matcher.
|
25
29
|
#
|
26
|
-
# @return [
|
30
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
31
|
+
# pass or fail.
|
27
32
|
def MUST(matcher)
|
28
33
|
RequirementLevel::Must.new(
|
29
34
|
callable: callable,
|
@@ -34,7 +39,7 @@ module Spectus
|
|
34
39
|
end
|
35
40
|
|
36
41
|
# @example _Absolute requirement_ definition with isolation
|
37
|
-
# it {
|
42
|
+
# it { "foo".upcase }.MUST! eql 'FOO'
|
38
43
|
#
|
39
44
|
# @see MUST
|
40
45
|
def MUST!(matcher)
|
@@ -50,11 +55,12 @@ module Spectus
|
|
50
55
|
# definition is an absolute prohibition of the specification.
|
51
56
|
#
|
52
57
|
# @example _Absolute prohibition_ definition
|
53
|
-
# it {
|
58
|
+
# it { "foo".size }.MUST_NOT equal 42
|
54
59
|
#
|
55
60
|
# @param matcher [#matches?] The matcher.
|
56
61
|
#
|
57
|
-
# @return [
|
62
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
63
|
+
# pass or fail.
|
58
64
|
def MUST_NOT(matcher)
|
59
65
|
RequirementLevel::Must.new(
|
60
66
|
callable: callable,
|
@@ -65,7 +71,7 @@ module Spectus
|
|
65
71
|
end
|
66
72
|
|
67
73
|
# @example _Absolute prohibition_ definition with isolation
|
68
|
-
# it {
|
74
|
+
# it { "foo".size }.MUST_NOT! equal 42
|
69
75
|
#
|
70
76
|
# @see MUST_NOT
|
71
77
|
def MUST_NOT!(matcher)
|
@@ -83,11 +89,12 @@ module Spectus
|
|
83
89
|
# carefully weighed before choosing a different course.
|
84
90
|
#
|
85
91
|
# @example _Recommended_ definition
|
86
|
-
# it {
|
92
|
+
# it { "foo".valid_encoding? }.SHOULD equal true
|
87
93
|
#
|
88
94
|
# @param matcher [#matches?] The matcher.
|
89
95
|
#
|
90
|
-
# @return [
|
96
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
97
|
+
# pass or fail.
|
91
98
|
def SHOULD(matcher)
|
92
99
|
RequirementLevel::Should.new(
|
93
100
|
callable: callable,
|
@@ -98,7 +105,7 @@ module Spectus
|
|
98
105
|
end
|
99
106
|
|
100
107
|
# @example _Recommended_ definition with isolation
|
101
|
-
# it {
|
108
|
+
# it { "foo".valid_encoding? }.SHOULD! equal true
|
102
109
|
#
|
103
110
|
# @see SHOULD
|
104
111
|
def SHOULD!(matcher)
|
@@ -117,11 +124,12 @@ module Spectus
|
|
117
124
|
# before implementing any behavior described with this label.
|
118
125
|
#
|
119
126
|
# @example _Not recommended_ definition
|
120
|
-
# it {
|
127
|
+
# it { "".blank? }.SHOULD_NOT raise_exception NoMethodError
|
121
128
|
#
|
122
129
|
# @param matcher [#matches?] The matcher.
|
123
130
|
#
|
124
|
-
# @return [
|
131
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
132
|
+
# pass or fail.
|
125
133
|
def SHOULD_NOT(matcher)
|
126
134
|
RequirementLevel::Should.new(
|
127
135
|
callable: callable,
|
@@ -132,7 +140,7 @@ module Spectus
|
|
132
140
|
end
|
133
141
|
|
134
142
|
# @example _Not recommended_ definition with isolation
|
135
|
-
# it {
|
143
|
+
# it { "".blank? }.SHOULD_NOT! raise_exception NoMethodError
|
136
144
|
#
|
137
145
|
# @see SHOULD_NOT
|
138
146
|
def SHOULD_NOT!(matcher)
|
@@ -157,11 +165,11 @@ module Spectus
|
|
157
165
|
# option provides.)
|
158
166
|
#
|
159
167
|
# @example _Optional_ definition
|
160
|
-
# it {
|
168
|
+
# it { "foo".bar }.MAY match /^foo$/
|
161
169
|
#
|
162
170
|
# @param matcher [#matches?] The matcher.
|
163
171
|
#
|
164
|
-
# @return [
|
172
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec pass or fail.
|
165
173
|
def MAY(matcher)
|
166
174
|
RequirementLevel::May.new(
|
167
175
|
callable: callable,
|
@@ -172,7 +180,7 @@ module Spectus
|
|
172
180
|
end
|
173
181
|
|
174
182
|
# @example _Optional_ definition with isolation
|
175
|
-
# it {
|
183
|
+
# it { "foo".bar }.MAY! match /^foo$/
|
176
184
|
#
|
177
185
|
# @see MAY
|
178
186
|
def MAY!(matcher)
|
@@ -192,7 +200,3 @@ module Spectus
|
|
192
200
|
attr_reader :callable
|
193
201
|
end
|
194
202
|
end
|
195
|
-
|
196
|
-
require_relative File.join("requirement_level", "must")
|
197
|
-
require_relative File.join("requirement_level", "should")
|
198
|
-
require_relative File.join("requirement_level", "may")
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative File.join("..", "exam")
|
4
|
+
require_relative File.join("..", "result")
|
4
5
|
|
5
6
|
module Spectus
|
6
7
|
# Namespace for the requirement levels.
|
@@ -34,10 +35,10 @@ module Spectus
|
|
34
35
|
|
35
36
|
# The result of the expectation.
|
36
37
|
#
|
37
|
-
# @raise [
|
38
|
-
# @return [
|
38
|
+
# @raise [Spectus::Result::Fail] The expectation failed.
|
39
|
+
# @return [Spectus::Result::Pass] The expectation passed.
|
39
40
|
def call
|
40
|
-
|
41
|
+
Result.call(pass?).with(
|
41
42
|
actual: exam.actual,
|
42
43
|
error: exam.exception,
|
43
44
|
expected: matcher.expected,
|
@@ -66,5 +67,3 @@ module Spectus
|
|
66
67
|
end
|
67
68
|
end
|
68
69
|
end
|
69
|
-
|
70
|
-
require_relative File.join("..", "exam")
|
@@ -0,0 +1,18 @@
|
|
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
|
@@ -0,0 +1,13 @@
|
|
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
|
@@ -0,0 +1,13 @@
|
|
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
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spectus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.4
|
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-
|
11
|
+
date: 2021-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: defi
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.0.
|
19
|
+
version: 2.0.5
|
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.
|
26
|
+
version: 2.0.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: expresenter
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.2.1
|
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.
|
40
|
+
version: 1.2.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: matchi
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.
|
47
|
+
version: 2.1.0
|
48
48
|
type: :runtime
|
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.
|
54
|
+
version: 2.1.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: brutal
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,6 +193,9 @@ files:
|
|
193
193
|
- lib/spectus/requirement_level/may.rb
|
194
194
|
- lib/spectus/requirement_level/must.rb
|
195
195
|
- lib/spectus/requirement_level/should.rb
|
196
|
+
- lib/spectus/result.rb
|
197
|
+
- lib/spectus/result/fail.rb
|
198
|
+
- lib/spectus/result/pass.rb
|
196
199
|
homepage: https://github.com/fixrb/spectus
|
197
200
|
licenses:
|
198
201
|
- MIT
|
@@ -212,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
212
215
|
- !ruby/object:Gem::Version
|
213
216
|
version: '0'
|
214
217
|
requirements: []
|
215
|
-
rubygems_version: 3.1.
|
218
|
+
rubygems_version: 3.1.6
|
216
219
|
signing_key:
|
217
220
|
specification_version: 4
|
218
221
|
summary: "Expectation library with RFC 2119's requirement levels \U0001F6A5"
|