spectus 3.1.2 → 3.3.1
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/LICENSE.md +1 -1
- data/README.md +44 -65
- data/lib/spectus.rb +2 -2
- data/lib/spectus/exam.rb +1 -1
- data/lib/spectus/expectation_target.rb +22 -18
- data/lib/spectus/requirement_level/base.rb +9 -24
- data/lib/spectus/requirement_level/may.rb +1 -1
- data/lib/spectus/requirement_level/must.rb +1 -1
- data/lib/spectus/requirement_level/should.rb +1 -1
- data/lib/spectus/result.rb +18 -0
- data/lib/spectus/result/fail.rb +2 -67
- data/lib/spectus/result/pass.rb +2 -76
- metadata +70 -28
- data/lib/spectus/result/common.rb +0 -174
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea568266e54174dc52fd45ac1db0be5b45bd25597324a5979eb3eba3cfe219f9
|
4
|
+
data.tar.gz: fcfc0a8a66bb7a11bbda70d05c153d6707b8667a09c55bef4fb79d7a76db820b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b746d187369c3a87277635e4be4a4810cf66b7e60d7a0e9222b8fb0fff0ab7b83e800479202c7a4685fe282f48295082afbecf288d97281486cd0c8a076b5490
|
7
|
+
data.tar.gz: c731fb2feb89312e33fab1b0890e9881b6d4ff3a66786b10e28fb15e5afe965300ef69966ff428480a56636c35d5e729eae9bbc32eba2c41079b217172d46051
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# Spectus
|
2
2
|
|
3
|
-
[][codeclimate]
|
3
|
+
[][travis]
|
5
4
|
[][gem]
|
6
|
-
[][inchpages]
|
7
6
|
[][rubydoc]
|
8
7
|
|
9
8
|
> Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)'s requirement levels 🚥
|
@@ -13,66 +12,19 @@
|
|
13
12
|
Add this line to your application's Gemfile:
|
14
13
|
|
15
14
|
```ruby
|
16
|
-
gem
|
15
|
+
gem "spectus"
|
17
16
|
```
|
18
17
|
|
19
18
|
And then execute:
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
Or install it yourself as:
|
24
|
-
|
25
|
-
$ gem install spectus
|
26
|
-
|
27
|
-
## Expectation
|
28
|
-
|
29
|
-
An expectation is an assertion that is either `true` or `false`.
|
30
|
-
|
31
|
-
There are several scenarios:
|
32
|
-
|
33
|
-
| Requirement levels | **MUST** | **SHOULD** | **MAY** |
|
34
|
-
| ------------------------- | -------- | ---------- | ------- |
|
35
|
-
| Implemented & Matched | `true` | `true` | `true` |
|
36
|
-
| Implemented & Not matched | `false` | `true` | `false` |
|
37
|
-
| Implemented & Exception | `false` | `false` | `false` |
|
38
|
-
| Not implemented | `false` | `false` | `true` |
|
39
|
-
|
40
|
-
Thus,
|
41
|
-
|
42
|
-
* when an expectation is `true`, a `Spectus::Result::Pass` instance is returned;
|
43
|
-
* when an expectation is `false`, a `Spectus::Result::Fail` exception is raised.
|
44
|
-
|
45
|
-
Both results share a common interface, and can be classified respectively as:
|
46
|
-
|
47
|
-
* ✅ a _success_, ⚠️ a _warning_ or 💡 an _info_;
|
48
|
-
* ❌ a _failure_ or 💥 an _error_.
|
49
|
-
|
50
|
-
## Code Isolation
|
51
|
-
|
52
|
-
When executing expectations, side-effects may occur.
|
53
|
-
Because they may or may not be desired, each requirement level has 2 versions:
|
54
|
-
|
55
|
-
* if it does not end with `!`, its test is performed without isolation;
|
56
|
-
* if it ends with `!`, its test is performed in isolation.
|
57
|
-
|
58
|
-
Example of test without isolation:
|
59
|
-
|
60
|
-
```ruby
|
61
|
-
include Spectus
|
62
|
-
greeting = 'Hello, world!'
|
63
|
-
it { greeting.gsub!('world', 'Alice') }.MUST eql 'Hello, Alice!'
|
64
|
-
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
65
|
-
greeting # => "Hello, Alice!"
|
20
|
+
```sh
|
21
|
+
bundle
|
66
22
|
```
|
67
23
|
|
68
|
-
|
24
|
+
Or install it yourself as:
|
69
25
|
|
70
|
-
```
|
71
|
-
|
72
|
-
greeting = 'Hello, world!'
|
73
|
-
it { greeting.gsub!('world', 'Alice') }.MUST! eql 'Hello, Alice!'
|
74
|
-
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
75
|
-
greeting # => "Hello, world!"
|
26
|
+
```sh
|
27
|
+
gem install spectus
|
76
28
|
```
|
77
29
|
|
78
30
|
## Usage
|
@@ -88,7 +40,7 @@ include Spectus
|
|
88
40
|
Given the "`ルビー`" object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
|
89
41
|
|
90
42
|
```ruby
|
91
|
-
it {
|
43
|
+
it { "ルビー".valid_encoding? }.MUST be_true
|
92
44
|
# => Spectus::Result::Pass(actual: true, error: nil, expected: nil, got: true, matcher: :be_true, negate: false, level: :MUST, valid: true)
|
93
45
|
```
|
94
46
|
|
@@ -99,7 +51,7 @@ The result of the test shows that the spec passed.
|
|
99
51
|
Given the "`foo`" object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
|
100
52
|
|
101
53
|
```ruby
|
102
|
-
it {
|
54
|
+
it { "foo".length }.MUST_NOT raise_exception NoMethodError
|
103
55
|
# => Spectus::Result::Pass(actual: 3, error: nil, expected: NoMethodError, got: true, matcher: :raise_exception, negate: true, level: :MUST, valid: true)
|
104
56
|
```
|
105
57
|
|
@@ -122,7 +74,7 @@ However, because there isn't any exception, the result of the test shows that th
|
|
122
74
|
Given the "`1`" object, when it receives `+(1)` method, then it **SHOULD NOT** return the "`11`" value:
|
123
75
|
|
124
76
|
```ruby
|
125
|
-
it {
|
77
|
+
it { "1" + 1 }.SHOULD_NOT eql "11"
|
126
78
|
# 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)
|
127
79
|
```
|
128
80
|
|
@@ -133,7 +85,7 @@ There was a `TypeError` exception, the result of the test shows that the spec fa
|
|
133
85
|
Given the "`foo`" object, when it receives `blank?` method, then it **MAY** be `false`:
|
134
86
|
|
135
87
|
```ruby
|
136
|
-
it {
|
88
|
+
it { "foo".blank? }.MAY be_false
|
137
89
|
# => 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)
|
138
90
|
```
|
139
91
|
|
@@ -141,8 +93,36 @@ The optional `blank?` method is not implemented (unlike in [Ruby on Rails](https
|
|
141
93
|
|
142
94
|
### More Examples
|
143
95
|
|
144
|
-
A full list of unit tests can be viewed here:
|
145
|
-
[test.rb](https://github.com/fixrb/spectus/blob/
|
96
|
+
A full list of unit tests can be viewed (and executed) here:
|
97
|
+
[./test.rb](https://github.com/fixrb/spectus/blob/main/test.rb)
|
98
|
+
|
99
|
+
## Code Isolation
|
100
|
+
|
101
|
+
When executing expectations, side-effects may occur.
|
102
|
+
Because they may or may not be desired, each requirement level has 2 versions:
|
103
|
+
|
104
|
+
* if it does not end with `!`, its test is performed without isolation;
|
105
|
+
* if it ends with `!`, its test is performed in isolation.
|
106
|
+
|
107
|
+
Example of test without isolation:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
include Spectus
|
111
|
+
greeting = "Hello, world!"
|
112
|
+
it { greeting.gsub!("world", "Alice") }.MUST eql "Hello, Alice!"
|
113
|
+
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
114
|
+
greeting # => "Hello, Alice!"
|
115
|
+
```
|
116
|
+
|
117
|
+
Example of test in isolation:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
include Spectus
|
121
|
+
greeting = "Hello, world!"
|
122
|
+
it { greeting.gsub!("world", "Alice") }.MUST! eql "Hello, Alice!"
|
123
|
+
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
124
|
+
greeting # => "Hello, world!"
|
125
|
+
```
|
146
126
|
|
147
127
|
## Contact
|
148
128
|
|
@@ -155,19 +135,18 @@ __Spectus__ follows [Semantic Versioning 2.0](https://semver.org/).
|
|
155
135
|
|
156
136
|
## License
|
157
137
|
|
158
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
138
|
+
The [gem](https://rubygems.org/gems/spectus) is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
159
139
|
|
160
140
|
***
|
161
141
|
|
162
142
|
<p>
|
163
143
|
This project is sponsored by:<br />
|
164
144
|
<a href="https://sashite.com/"><img
|
165
|
-
src="https://github.com/fixrb/spectus/raw/
|
145
|
+
src="https://github.com/fixrb/spectus/raw/main/img/sashite.png"
|
166
146
|
alt="Sashite" /></a>
|
167
147
|
</p>
|
168
148
|
|
169
149
|
[gem]: https://rubygems.org/gems/spectus
|
170
150
|
[travis]: https://travis-ci.org/fixrb/spectus
|
171
|
-
[codeclimate]: https://codeclimate.com/github/fixrb/spectus
|
172
151
|
[inchpages]: https://inch-ci.org/github/fixrb/spectus
|
173
152
|
[rubydoc]: https://rubydoc.info/gems/spectus/frames
|
data/lib/spectus.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "matchi/helper"
|
4
4
|
|
5
5
|
# Namespace for the Spectus library.
|
6
6
|
#
|
@@ -23,4 +23,4 @@ module Spectus
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
require_relative File.join(
|
26
|
+
require_relative File.join("spectus", "expectation_target")
|
data/lib/spectus/exam.rb
CHANGED
@@ -19,11 +19,12 @@ module Spectus
|
|
19
19
|
# definition is an absolute requirement of the specification.
|
20
20
|
#
|
21
21
|
# @example _Absolute requirement_ definition
|
22
|
-
# it {
|
22
|
+
# it { "foo".upcase }.MUST eql 'FOO'
|
23
23
|
#
|
24
24
|
# @param matcher [#matches?] The matcher.
|
25
25
|
#
|
26
|
-
# @return [Result::Fail, Result::Pass] Report if the spec
|
26
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
27
|
+
# pass or fail.
|
27
28
|
def MUST(matcher)
|
28
29
|
RequirementLevel::Must.new(
|
29
30
|
callable: callable,
|
@@ -34,7 +35,7 @@ module Spectus
|
|
34
35
|
end
|
35
36
|
|
36
37
|
# @example _Absolute requirement_ definition with isolation
|
37
|
-
# it {
|
38
|
+
# it { "foo".upcase }.MUST! eql 'FOO'
|
38
39
|
#
|
39
40
|
# @see MUST
|
40
41
|
def MUST!(matcher)
|
@@ -50,11 +51,12 @@ module Spectus
|
|
50
51
|
# definition is an absolute prohibition of the specification.
|
51
52
|
#
|
52
53
|
# @example _Absolute prohibition_ definition
|
53
|
-
# it {
|
54
|
+
# it { "foo".size }.MUST_NOT equal 42
|
54
55
|
#
|
55
56
|
# @param matcher [#matches?] The matcher.
|
56
57
|
#
|
57
|
-
# @return [Result::Fail, Result::Pass] Report if the spec
|
58
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
59
|
+
# pass or fail.
|
58
60
|
def MUST_NOT(matcher)
|
59
61
|
RequirementLevel::Must.new(
|
60
62
|
callable: callable,
|
@@ -65,7 +67,7 @@ module Spectus
|
|
65
67
|
end
|
66
68
|
|
67
69
|
# @example _Absolute prohibition_ definition with isolation
|
68
|
-
# it {
|
70
|
+
# it { "foo".size }.MUST_NOT! equal 42
|
69
71
|
#
|
70
72
|
# @see MUST_NOT
|
71
73
|
def MUST_NOT!(matcher)
|
@@ -83,11 +85,12 @@ module Spectus
|
|
83
85
|
# carefully weighed before choosing a different course.
|
84
86
|
#
|
85
87
|
# @example _Recommended_ definition
|
86
|
-
# it {
|
88
|
+
# it { "foo".valid_encoding? }.SHOULD equal true
|
87
89
|
#
|
88
90
|
# @param matcher [#matches?] The matcher.
|
89
91
|
#
|
90
|
-
# @return [Result::Fail, Result::Pass] Report if the spec
|
92
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
93
|
+
# pass or fail.
|
91
94
|
def SHOULD(matcher)
|
92
95
|
RequirementLevel::Should.new(
|
93
96
|
callable: callable,
|
@@ -98,7 +101,7 @@ module Spectus
|
|
98
101
|
end
|
99
102
|
|
100
103
|
# @example _Recommended_ definition with isolation
|
101
|
-
# it {
|
104
|
+
# it { "foo".valid_encoding? }.SHOULD! equal true
|
102
105
|
#
|
103
106
|
# @see SHOULD
|
104
107
|
def SHOULD!(matcher)
|
@@ -117,11 +120,12 @@ module Spectus
|
|
117
120
|
# before implementing any behavior described with this label.
|
118
121
|
#
|
119
122
|
# @example _Not recommended_ definition
|
120
|
-
# it {
|
123
|
+
# it { "".blank? }.SHOULD_NOT raise_exception NoMethodError
|
121
124
|
#
|
122
125
|
# @param matcher [#matches?] The matcher.
|
123
126
|
#
|
124
|
-
# @return [Result::Fail, Result::Pass] Report if the spec
|
127
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec
|
128
|
+
# pass or fail.
|
125
129
|
def SHOULD_NOT(matcher)
|
126
130
|
RequirementLevel::Should.new(
|
127
131
|
callable: callable,
|
@@ -132,7 +136,7 @@ module Spectus
|
|
132
136
|
end
|
133
137
|
|
134
138
|
# @example _Not recommended_ definition with isolation
|
135
|
-
# it {
|
139
|
+
# it { "".blank? }.SHOULD_NOT! raise_exception NoMethodError
|
136
140
|
#
|
137
141
|
# @see SHOULD_NOT
|
138
142
|
def SHOULD_NOT!(matcher)
|
@@ -157,11 +161,11 @@ module Spectus
|
|
157
161
|
# option provides.)
|
158
162
|
#
|
159
163
|
# @example _Optional_ definition
|
160
|
-
# it {
|
164
|
+
# it { "foo".bar }.MAY match /^foo$/
|
161
165
|
#
|
162
166
|
# @param matcher [#matches?] The matcher.
|
163
167
|
#
|
164
|
-
# @return [Result::Fail, Result::Pass] Report if the spec pass or fail.
|
168
|
+
# @return [Spectus::Result::Fail, Spectus::Result::Pass] Report if the spec pass or fail.
|
165
169
|
def MAY(matcher)
|
166
170
|
RequirementLevel::May.new(
|
167
171
|
callable: callable,
|
@@ -172,7 +176,7 @@ module Spectus
|
|
172
176
|
end
|
173
177
|
|
174
178
|
# @example _Optional_ definition with isolation
|
175
|
-
# it {
|
179
|
+
# it { "foo".bar }.MAY! match /^foo$/
|
176
180
|
#
|
177
181
|
# @see MAY
|
178
182
|
def MAY!(matcher)
|
@@ -193,6 +197,6 @@ module Spectus
|
|
193
197
|
end
|
194
198
|
end
|
195
199
|
|
196
|
-
require_relative File.join(
|
197
|
-
require_relative File.join(
|
198
|
-
require_relative File.join(
|
200
|
+
require_relative File.join("requirement_level", "must")
|
201
|
+
require_relative File.join("requirement_level", "should")
|
202
|
+
require_relative File.join("requirement_level", "may")
|
@@ -32,26 +32,10 @@ module Spectus
|
|
32
32
|
|
33
33
|
# The result of the expectation.
|
34
34
|
#
|
35
|
-
# @
|
35
|
+
# @raise [Spectus::Result::Fail] The expectation is `false`.
|
36
|
+
# @return [Spectus::Result::Pass] The expectation is `true`.
|
36
37
|
def call
|
37
|
-
pass?
|
38
|
-
end
|
39
|
-
|
40
|
-
protected
|
41
|
-
|
42
|
-
# @return [Result::Pass] A passed spec result.
|
43
|
-
def pass!
|
44
|
-
Result::Pass.new(**details)
|
45
|
-
end
|
46
|
-
|
47
|
-
# @raise [Result::Fail] A failed spec result.
|
48
|
-
def fail!
|
49
|
-
raise Result::Fail.new(**details)
|
50
|
-
end
|
51
|
-
|
52
|
-
# @return [Hash] List of parameters.
|
53
|
-
def details
|
54
|
-
{
|
38
|
+
Result.call(pass?).with(
|
55
39
|
actual: exam.actual,
|
56
40
|
error: exam.exception,
|
57
41
|
expected: matcher.expected,
|
@@ -60,12 +44,14 @@ module Spectus
|
|
60
44
|
valid: exam.valid?,
|
61
45
|
matcher: matcher.class.to_sym,
|
62
46
|
level: level
|
63
|
-
|
47
|
+
)
|
64
48
|
end
|
65
49
|
|
50
|
+
protected
|
51
|
+
|
66
52
|
# @return [Symbol] The requirement level.
|
67
53
|
def level
|
68
|
-
self.class.name.split(
|
54
|
+
self.class.name.split("::").fetch(-1).upcase.to_sym
|
69
55
|
end
|
70
56
|
|
71
57
|
# @note The boolean comparison between the actual value and the expected
|
@@ -79,6 +65,5 @@ module Spectus
|
|
79
65
|
end
|
80
66
|
end
|
81
67
|
|
82
|
-
require_relative File.join(
|
83
|
-
require_relative File.join(
|
84
|
-
require_relative File.join('..', 'result', 'pass')
|
68
|
+
require_relative File.join("..", "exam")
|
69
|
+
require_relative File.join("..", "result")
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spectus
|
4
|
+
# Namespace for the results.
|
5
|
+
module Result
|
6
|
+
# @param is_passed [Boolean] The value of an assertion.
|
7
|
+
# @return [Class<Spectus::Result::Pass>, Class<Spectus::Result::Fail>] The
|
8
|
+
# class of the result.
|
9
|
+
# @example Get the pass class result.
|
10
|
+
# call(true) # => Pass
|
11
|
+
def self.call(is_passed)
|
12
|
+
is_passed ? Pass : Fail
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require_relative File.join("result", "fail")
|
18
|
+
require_relative File.join("result", "pass")
|
data/lib/spectus/result/fail.rb
CHANGED
@@ -1,76 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "expresenter/fail"
|
4
4
|
|
5
5
|
module Spectus
|
6
6
|
module Result
|
7
7
|
# The class that is responsible for reporting that the expectation is false.
|
8
|
-
class Fail < ::
|
9
|
-
include Common
|
10
|
-
|
11
|
-
# Did the test fail?
|
12
|
-
#
|
13
|
-
# @return [Boolean] The spec passed or failed?
|
14
|
-
def failed?
|
15
|
-
true
|
16
|
-
end
|
17
|
-
|
18
|
-
# Did the test pass?
|
19
|
-
#
|
20
|
-
# @return [Boolean] The spec passed or failed?
|
21
|
-
def passed?
|
22
|
-
!failed?
|
23
|
-
end
|
24
|
-
|
25
|
-
# The state of failure.
|
26
|
-
#
|
27
|
-
# @return [Boolean] The test was a failure?
|
28
|
-
def failure?
|
29
|
-
!error?
|
30
|
-
end
|
31
|
-
|
32
|
-
# The state of info.
|
33
|
-
#
|
34
|
-
# @return [Boolean] The test was an info?
|
35
|
-
def info?
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
|
-
# The state of warning.
|
40
|
-
#
|
41
|
-
# @return [Boolean] The test was a warning?
|
42
|
-
def warning?
|
43
|
-
false
|
44
|
-
end
|
45
|
-
|
46
|
-
# Identify the state of the result.
|
47
|
-
#
|
48
|
-
# @return [Symbol] The identifier of the state.
|
49
|
-
def to_sym
|
50
|
-
failure? ? :failure : :error
|
51
|
-
end
|
52
|
-
|
53
|
-
# Express the result with one char.
|
54
|
-
#
|
55
|
-
# @return [String] The char that identify the result.
|
56
|
-
def char
|
57
|
-
if failure?
|
58
|
-
'F'
|
59
|
-
else
|
60
|
-
'E'
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Express the result with one emoji.
|
65
|
-
#
|
66
|
-
# @return [String] The emoji that identify the result.
|
67
|
-
def emoji
|
68
|
-
if failure?
|
69
|
-
'❌'
|
70
|
-
else
|
71
|
-
'💥'
|
72
|
-
end
|
73
|
-
end
|
8
|
+
class Fail < ::Expresenter::Fail
|
74
9
|
end
|
75
10
|
end
|
76
11
|
end
|
data/lib/spectus/result/pass.rb
CHANGED
@@ -1,85 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "expresenter/pass"
|
4
4
|
|
5
5
|
module Spectus
|
6
6
|
module Result
|
7
7
|
# The class that is responsible for reporting that the expectation is true.
|
8
|
-
class Pass
|
9
|
-
include Common
|
10
|
-
|
11
|
-
alias message to_s
|
12
|
-
|
13
|
-
# Did the test fail?
|
14
|
-
#
|
15
|
-
# @return [Boolean] The spec passed or failed?
|
16
|
-
def failed?
|
17
|
-
false
|
18
|
-
end
|
19
|
-
|
20
|
-
# Did the test pass?
|
21
|
-
#
|
22
|
-
# @return [Boolean] The spec passed or failed?
|
23
|
-
def passed?
|
24
|
-
!failed?
|
25
|
-
end
|
26
|
-
|
27
|
-
# The state of failure.
|
28
|
-
#
|
29
|
-
# @return [Boolean] The test was a failure?
|
30
|
-
def failure?
|
31
|
-
false
|
32
|
-
end
|
33
|
-
|
34
|
-
# The state of info.
|
35
|
-
#
|
36
|
-
# @return [Boolean] The test was an info?
|
37
|
-
def info?
|
38
|
-
!error.nil?
|
39
|
-
end
|
40
|
-
|
41
|
-
# The state of warning.
|
42
|
-
#
|
43
|
-
# @return [Boolean] The test was a warning?
|
44
|
-
def warning?
|
45
|
-
got.equal?(false)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Identify the state of the result.
|
49
|
-
#
|
50
|
-
# @return [Symbol] The identifier of the state.
|
51
|
-
def to_sym
|
52
|
-
return :success if success?
|
53
|
-
return :warning if warning?
|
54
|
-
|
55
|
-
:info
|
56
|
-
end
|
57
|
-
|
58
|
-
# Express the result with one char.
|
59
|
-
#
|
60
|
-
# @return [String] The char that identify the result.
|
61
|
-
def char
|
62
|
-
if success?
|
63
|
-
'.'
|
64
|
-
elsif warning?
|
65
|
-
'W'
|
66
|
-
else
|
67
|
-
'I'
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Express the result with one emoji.
|
72
|
-
#
|
73
|
-
# @return [String] The emoji that identify the result.
|
74
|
-
def emoji
|
75
|
-
if success?
|
76
|
-
'✅'
|
77
|
-
elsif warning?
|
78
|
-
'⚠️'
|
79
|
-
else
|
80
|
-
'💡'
|
81
|
-
end
|
82
|
-
end
|
8
|
+
class Pass < ::Expresenter::Pass
|
83
9
|
end
|
84
10
|
end
|
85
11
|
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.1
|
4
|
+
version: 3.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: defi
|
@@ -16,14 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.0.
|
19
|
+
version: 2.0.4
|
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.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: expresenter
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.2.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: matchi
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -42,46 +56,46 @@ dependencies:
|
|
42
56
|
name: brutal
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- - "
|
59
|
+
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
61
|
+
version: '0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- - "
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- - "
|
73
|
+
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
75
|
+
version: '0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- - "
|
80
|
+
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rake
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- - "
|
87
|
+
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
89
|
+
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- - "
|
94
|
+
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop
|
98
|
+
name: rubocop-md
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
@@ -108,34 +122,62 @@ dependencies:
|
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rake
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop-thread_safety
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
111
153
|
- !ruby/object:Gem::Dependency
|
112
154
|
name: simplecov
|
113
155
|
requirement: !ruby/object:Gem::Requirement
|
114
156
|
requirements:
|
115
|
-
- - "
|
157
|
+
- - ">="
|
116
158
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0
|
159
|
+
version: '0'
|
118
160
|
type: :development
|
119
161
|
prerelease: false
|
120
162
|
version_requirements: !ruby/object:Gem::Requirement
|
121
163
|
requirements:
|
122
|
-
- - "
|
164
|
+
- - ">="
|
123
165
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0
|
166
|
+
version: '0'
|
125
167
|
- !ruby/object:Gem::Dependency
|
126
168
|
name: yard
|
127
169
|
requirement: !ruby/object:Gem::Requirement
|
128
170
|
requirements:
|
129
|
-
- - "
|
171
|
+
- - ">="
|
130
172
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0
|
173
|
+
version: '0'
|
132
174
|
type: :development
|
133
175
|
prerelease: false
|
134
176
|
version_requirements: !ruby/object:Gem::Requirement
|
135
177
|
requirements:
|
136
|
-
- - "
|
178
|
+
- - ">="
|
137
179
|
- !ruby/object:Gem::Version
|
138
|
-
version: '0
|
180
|
+
version: '0'
|
139
181
|
description: "Expectation library with RFC 2119's requirement levels \U0001F6A5"
|
140
182
|
email: contact@cyril.email
|
141
183
|
executables: []
|
@@ -151,7 +193,7 @@ files:
|
|
151
193
|
- lib/spectus/requirement_level/may.rb
|
152
194
|
- lib/spectus/requirement_level/must.rb
|
153
195
|
- lib/spectus/requirement_level/should.rb
|
154
|
-
- lib/spectus/result
|
196
|
+
- lib/spectus/result.rb
|
155
197
|
- lib/spectus/result/fail.rb
|
156
198
|
- lib/spectus/result/pass.rb
|
157
199
|
homepage: https://github.com/fixrb/spectus
|
@@ -166,14 +208,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
166
208
|
requirements:
|
167
209
|
- - ">="
|
168
210
|
- !ruby/object:Gem::Version
|
169
|
-
version: 2.
|
211
|
+
version: 2.7.0
|
170
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
213
|
requirements:
|
172
214
|
- - ">="
|
173
215
|
- !ruby/object:Gem::Version
|
174
216
|
version: '0'
|
175
217
|
requirements: []
|
176
|
-
rubygems_version: 3.1.
|
218
|
+
rubygems_version: 3.1.6
|
177
219
|
signing_key:
|
178
220
|
specification_version: 4
|
179
221
|
summary: "Expectation library with RFC 2119's requirement levels \U0001F6A5"
|
@@ -1,174 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spectus
|
4
|
-
# Namespace for the results.
|
5
|
-
module Result
|
6
|
-
# Common collection of methods for Result's classes.
|
7
|
-
module Common
|
8
|
-
# @return [#object_id] Returned value by the challenged subject.
|
9
|
-
attr_reader :actual
|
10
|
-
|
11
|
-
# @return [Exception, nil] Any possible raised exception.
|
12
|
-
attr_reader :error
|
13
|
-
|
14
|
-
# @return [#object_id] The expected value.
|
15
|
-
attr_reader :expected
|
16
|
-
|
17
|
-
# @return [#object_id] The result of the boolean comparison between the
|
18
|
-
# actual value and the expected value through the matcher.
|
19
|
-
attr_reader :got
|
20
|
-
|
21
|
-
# @return [#object_id] The matcher.
|
22
|
-
attr_reader :matcher
|
23
|
-
|
24
|
-
# @return [:MUST, :SHOULD, :MAY] The requirement level of the expectation.
|
25
|
-
attr_reader :level
|
26
|
-
|
27
|
-
# Common initialize method.
|
28
|
-
#
|
29
|
-
# @param actual [#object_id] Returned value by the challenged subject.
|
30
|
-
# @param error [Exception, nil] Any possible raised exception.
|
31
|
-
# @param expected [#object_id] The expected value.
|
32
|
-
# @param got [Boolean, nil] The result of the boolean comparison
|
33
|
-
# between the actual value and the expected value through the matcher.
|
34
|
-
# @param negate [Boolean] Evaluated to a negative assertion?
|
35
|
-
# @param valid [Boolean] Report if the test was true or false?
|
36
|
-
# @param matcher [Symbol] The matcher.
|
37
|
-
# @param level [:MUST, :SHOULD, :MAY] The requirement level.
|
38
|
-
def initialize(actual:, error:, expected:, got:, negate:, valid:,
|
39
|
-
matcher:, level:)
|
40
|
-
|
41
|
-
@actual = actual
|
42
|
-
@error = error
|
43
|
-
@expected = expected
|
44
|
-
@got = got
|
45
|
-
@negate = negate
|
46
|
-
@valid = valid
|
47
|
-
@matcher = matcher
|
48
|
-
@level = level
|
49
|
-
|
50
|
-
super(to_s) if failed?
|
51
|
-
end
|
52
|
-
|
53
|
-
# The value of the negate instance variable.
|
54
|
-
#
|
55
|
-
# @return [Boolean] Evaluated to a negative assertion?
|
56
|
-
def negate?
|
57
|
-
@negate
|
58
|
-
end
|
59
|
-
|
60
|
-
# The state of error.
|
61
|
-
#
|
62
|
-
# @return [Boolean] The test raised an error?
|
63
|
-
def error?
|
64
|
-
!error.nil?
|
65
|
-
end
|
66
|
-
|
67
|
-
# The state of success.
|
68
|
-
#
|
69
|
-
# @return [Boolean] The test was a success?
|
70
|
-
def success?
|
71
|
-
got.equal?(true)
|
72
|
-
end
|
73
|
-
|
74
|
-
# The value of the boolean comparison between the actual value and the
|
75
|
-
# expected value.
|
76
|
-
#
|
77
|
-
# @return [Boolean] The test was true or false?
|
78
|
-
def valid?
|
79
|
-
@valid
|
80
|
-
end
|
81
|
-
|
82
|
-
# A string containing a human-readable representation of the result.
|
83
|
-
#
|
84
|
-
# @return [String] The human-readable representation of the result.
|
85
|
-
def inspect
|
86
|
-
"#{self.class}(actual: #{actual.inspect}, " \
|
87
|
-
"error: #{error.inspect}, " \
|
88
|
-
"expected: #{expected.inspect}, " \
|
89
|
-
"got: #{got.inspect}, " \
|
90
|
-
"matcher: #{matcher.inspect}, " \
|
91
|
-
"negate: #{negate?.inspect}, " \
|
92
|
-
"level: #{level.inspect}, " \
|
93
|
-
"valid: #{valid?.inspect})" \
|
94
|
-
end
|
95
|
-
|
96
|
-
# The readable definition.
|
97
|
-
#
|
98
|
-
# @return [String] A readable string of the definition.
|
99
|
-
def definition
|
100
|
-
[matcher, expected&.inspect].compact.join(' ')
|
101
|
-
end
|
102
|
-
|
103
|
-
# The negation, if any.
|
104
|
-
#
|
105
|
-
# @return [String] The negation, or an empty string.
|
106
|
-
def maybe_negate
|
107
|
-
negate? ? ' not' : ''
|
108
|
-
end
|
109
|
-
|
110
|
-
# The summary of the result.
|
111
|
-
#
|
112
|
-
# @return [String] A string representing the summary of the result.
|
113
|
-
def summary
|
114
|
-
if error?
|
115
|
-
error.message
|
116
|
-
elsif actual.is_a?(::Exception)
|
117
|
-
actual.message
|
118
|
-
elsif actual == expected
|
119
|
-
"expected#{maybe_negate} to #{definition}"
|
120
|
-
else
|
121
|
-
"expected #{actual.inspect}#{maybe_negate} to #{definition}"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Express the result with one colored char.
|
126
|
-
#
|
127
|
-
# @return [String] The colored char that identify the result.
|
128
|
-
def colored_char
|
129
|
-
color(char)
|
130
|
-
end
|
131
|
-
|
132
|
-
# The colored string representation of the result.
|
133
|
-
#
|
134
|
-
# @return [String] A string representing the result.
|
135
|
-
def colored_string
|
136
|
-
color(to_s)
|
137
|
-
end
|
138
|
-
|
139
|
-
# The representation of the result.
|
140
|
-
#
|
141
|
-
# @return [String] A string representing the result.
|
142
|
-
def to_s
|
143
|
-
"#{titre}: #{summary}."
|
144
|
-
end
|
145
|
-
|
146
|
-
# Titre for the result.
|
147
|
-
#
|
148
|
-
# @return [String] A string representing the titre.
|
149
|
-
def titre
|
150
|
-
if error?
|
151
|
-
error.class.name
|
152
|
-
else
|
153
|
-
to_sym.to_s.capitalize
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
protected
|
158
|
-
|
159
|
-
def color(str)
|
160
|
-
if success?
|
161
|
-
"\e[32m#{str}\e[0m"
|
162
|
-
elsif info?
|
163
|
-
"\e[36m#{str}\e[0m"
|
164
|
-
elsif warning?
|
165
|
-
"\e[33m#{str}\e[0m"
|
166
|
-
elsif failure?
|
167
|
-
"\e[35m#{str}\e[0m"
|
168
|
-
else
|
169
|
-
"\e[31m#{str}\e[0m"
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|