spectus 3.1.0 → 3.2.0
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 +43 -72
- data/lib/spectus.rb +4 -4
- data/lib/spectus/exam.rb +1 -1
- data/lib/spectus/expectation_target.rb +8 -8
- data/lib/spectus/requirement_level/base.rb +10 -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
- metadata +69 -30
- data/lib/spectus/result/common.rb +0 -174
- data/lib/spectus/result/fail.rb +0 -76
- data/lib/spectus/result/pass.rb +0 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7979abd1117a7e7320e221ef8723e818f7e1b3f8f7ac05e8913f65fdb2a7c615
|
4
|
+
data.tar.gz: b163fee339e12eec5712802159f361558f596ffa720cc87ccb26822883c40c36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4970d21d63e784d7257472a9ccee1f3d33f31e61d79030239a620a5a2f8569d039672c35429aa42c8db4c55c184f3bd7512921fb08246ad03ceed9b48b53b71
|
7
|
+
data.tar.gz: a41655c8c03ed03650677d8eae4d1fc4bb412bf4a4a66bc5076950181a6f6c9d123cd74f5a90127299d835f9249d07343463804bdbf276b8ad854c14bf0539c5
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Spectus
|
2
2
|
|
3
|
-
[][travis]
|
4
4
|
[][codeclimate]
|
5
5
|
[][gem]
|
6
|
-
[][inchpages]
|
7
7
|
[][rubydoc]
|
8
8
|
|
9
9
|
> Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)'s requirement levels 🚥
|
@@ -13,7 +13,7 @@
|
|
13
13
|
Add this line to your application's Gemfile:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem
|
16
|
+
gem "spectus"
|
17
17
|
```
|
18
18
|
|
19
19
|
And then execute:
|
@@ -24,57 +24,6 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
$ gem install spectus
|
26
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!"
|
66
|
-
```
|
67
|
-
|
68
|
-
Example of test in isolation:
|
69
|
-
|
70
|
-
```ruby
|
71
|
-
include Spectus
|
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!"
|
76
|
-
```
|
77
|
-
|
78
27
|
## Usage
|
79
28
|
|
80
29
|
To begin with, let's include __Spectus__:
|
@@ -88,8 +37,8 @@ include Spectus
|
|
88
37
|
Given the "`ルビー`" object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
|
89
38
|
|
90
39
|
```ruby
|
91
|
-
it {
|
92
|
-
# =>
|
40
|
+
it { "ルビー".valid_encoding? }.MUST be_true
|
41
|
+
# => Expresenter::Pass(actual: true, error: nil, expected: nil, got: true, matcher: :be_true, negate: false, level: :MUST, valid: true)
|
93
42
|
```
|
94
43
|
|
95
44
|
The result of the test shows that the spec passed.
|
@@ -99,8 +48,8 @@ The result of the test shows that the spec passed.
|
|
99
48
|
Given the "`foo`" object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
|
100
49
|
|
101
50
|
```ruby
|
102
|
-
it {
|
103
|
-
# =>
|
51
|
+
it { "foo".length }.MUST_NOT raise_exception NoMethodError
|
52
|
+
# => Expresenter::Pass(actual: 3, error: nil, expected: NoMethodError, got: true, matcher: :raise_exception, negate: true, level: :MUST, valid: true)
|
104
53
|
```
|
105
54
|
|
106
55
|
The result of the test shows that the spec passed.
|
@@ -111,7 +60,7 @@ Given the `BasicObject` object, when it receives `superclass` method, then it **
|
|
111
60
|
|
112
61
|
```ruby
|
113
62
|
it { BasicObject.superclass }.SHOULD equal NilClass
|
114
|
-
# =>
|
63
|
+
# => Expresenter::Pass(actual: nil, error: nil, expected: NilClass, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
|
115
64
|
```
|
116
65
|
|
117
66
|
Instead of the expected `NilClass` class, its sole instance (which is `nil`) was returned.
|
@@ -122,8 +71,8 @@ However, because there isn't any exception, the result of the test shows that th
|
|
122
71
|
Given the "`1`" object, when it receives `+(1)` method, then it **SHOULD NOT** return the "`11`" value:
|
123
72
|
|
124
73
|
```ruby
|
125
|
-
it {
|
126
|
-
# raise
|
74
|
+
it { "1" + 1 }.SHOULD_NOT eql "11"
|
75
|
+
# raise Expresenter::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
76
|
```
|
128
77
|
|
129
78
|
There was a `TypeError` exception, the result of the test shows that the spec failed.
|
@@ -133,28 +82,50 @@ There was a `TypeError` exception, the result of the test shows that the spec fa
|
|
133
82
|
Given the "`foo`" object, when it receives `blank?` method, then it **MAY** be `false`:
|
134
83
|
|
135
84
|
```ruby
|
136
|
-
it {
|
137
|
-
# =>
|
85
|
+
it { "foo".blank? }.MAY be_false
|
86
|
+
# => Expresenter::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
87
|
```
|
139
88
|
|
140
89
|
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.
|
141
90
|
|
142
91
|
### More Examples
|
143
92
|
|
144
|
-
|
145
|
-
[test.rb](https://github.com/fixrb/spectus/
|
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
|
+
## Code Isolation
|
97
|
+
|
98
|
+
When executing expectations, side-effects may occur.
|
99
|
+
Because they may or may not be desired, each requirement level has 2 versions:
|
100
|
+
|
101
|
+
* if it does not end with `!`, its test is performed without isolation;
|
102
|
+
* if it ends with `!`, its test is performed in isolation.
|
103
|
+
|
104
|
+
Example of test without isolation:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
include Spectus
|
108
|
+
greeting = "Hello, world!"
|
109
|
+
it { greeting.gsub!("world", "Alice") }.MUST eql "Hello, Alice!"
|
110
|
+
# => Expresenter::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
111
|
+
greeting # => "Hello, Alice!"
|
112
|
+
```
|
113
|
+
|
114
|
+
Example of test in isolation:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
include Spectus
|
118
|
+
greeting = "Hello, world!"
|
119
|
+
it { greeting.gsub!("world", "Alice") }.MUST! eql "Hello, Alice!"
|
120
|
+
# => Expresenter::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
|
121
|
+
greeting # => "Hello, world!"
|
122
|
+
```
|
146
123
|
|
147
124
|
## Contact
|
148
125
|
|
149
126
|
* Home page: https://github.com/fixrb/spectus
|
150
127
|
* Bugs/issues: https://github.com/fixrb/spectus/issues
|
151
128
|
|
152
|
-
## Rubies
|
153
|
-
|
154
|
-
* [MRI](https://www.ruby-lang.org/)
|
155
|
-
* [Rubinius](https://rubinius.com/)
|
156
|
-
* [JRuby](https://www.jruby.org/)
|
157
|
-
|
158
129
|
## Versioning
|
159
130
|
|
160
131
|
__Spectus__ follows [Semantic Versioning 2.0](https://semver.org/).
|
@@ -168,7 +139,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
168
139
|
<p>
|
169
140
|
This project is sponsored by:<br />
|
170
141
|
<a href="https://sashite.com/"><img
|
171
|
-
src="https://github.com/fixrb/spectus/raw/
|
142
|
+
src="https://github.com/fixrb/spectus/raw/main/img/sashite.png"
|
172
143
|
alt="Sashite" /></a>
|
173
144
|
</p>
|
174
145
|
|
data/lib/spectus.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
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
|
#
|
7
7
|
# @example It MUST equal 42.
|
8
8
|
# require 'spectus'
|
9
|
-
# it { 42 }.MUST equal 42 # => #<
|
9
|
+
# it { 42 }.MUST equal 42 # => #<Expresenter::Pass...>
|
10
10
|
module Spectus
|
11
11
|
include ::Matchi::Helper
|
12
12
|
|
13
13
|
# Expectations are built with this method.
|
14
14
|
#
|
15
15
|
# @example An _absolute requirement_ definition.
|
16
|
-
# it { 42 }.MUST equal 42 # => #<
|
16
|
+
# it { 42 }.MUST equal 42 # => #<Expresenter::Pass...>
|
17
17
|
#
|
18
18
|
# @param input [Proc] The code to test.
|
19
19
|
#
|
@@ -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
@@ -23,7 +23,7 @@ module Spectus
|
|
23
23
|
#
|
24
24
|
# @param matcher [#matches?] The matcher.
|
25
25
|
#
|
26
|
-
# @return [
|
26
|
+
# @return [Expresenter::Fail, Expresenter::Pass] Report if the spec pass or fail.
|
27
27
|
def MUST(matcher)
|
28
28
|
RequirementLevel::Must.new(
|
29
29
|
callable: callable,
|
@@ -54,7 +54,7 @@ module Spectus
|
|
54
54
|
#
|
55
55
|
# @param matcher [#matches?] The matcher.
|
56
56
|
#
|
57
|
-
# @return [
|
57
|
+
# @return [Expresenter::Fail, Expresenter::Pass] Report if the spec pass or fail.
|
58
58
|
def MUST_NOT(matcher)
|
59
59
|
RequirementLevel::Must.new(
|
60
60
|
callable: callable,
|
@@ -87,7 +87,7 @@ module Spectus
|
|
87
87
|
#
|
88
88
|
# @param matcher [#matches?] The matcher.
|
89
89
|
#
|
90
|
-
# @return [
|
90
|
+
# @return [Expresenter::Fail, Expresenter::Pass] Report if the spec pass or fail.
|
91
91
|
def SHOULD(matcher)
|
92
92
|
RequirementLevel::Should.new(
|
93
93
|
callable: callable,
|
@@ -121,7 +121,7 @@ module Spectus
|
|
121
121
|
#
|
122
122
|
# @param matcher [#matches?] The matcher.
|
123
123
|
#
|
124
|
-
# @return [
|
124
|
+
# @return [Expresenter::Fail, Expresenter::Pass] Report if the spec pass or fail.
|
125
125
|
def SHOULD_NOT(matcher)
|
126
126
|
RequirementLevel::Should.new(
|
127
127
|
callable: callable,
|
@@ -161,7 +161,7 @@ module Spectus
|
|
161
161
|
#
|
162
162
|
# @param matcher [#matches?] The matcher.
|
163
163
|
#
|
164
|
-
# @return [
|
164
|
+
# @return [Expresenter::Fail, Expresenter::Pass] Report if the spec pass or fail.
|
165
165
|
def MAY(matcher)
|
166
166
|
RequirementLevel::May.new(
|
167
167
|
callable: callable,
|
@@ -193,6 +193,6 @@ module Spectus
|
|
193
193
|
end
|
194
194
|
end
|
195
195
|
|
196
|
-
require_relative File.join(
|
197
|
-
require_relative File.join(
|
198
|
-
require_relative File.join(
|
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,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "expresenter"
|
4
|
+
|
3
5
|
module Spectus
|
4
6
|
# Namespace for the requirement levels.
|
5
7
|
module RequirementLevel
|
@@ -32,26 +34,10 @@ module Spectus
|
|
32
34
|
|
33
35
|
# The result of the expectation.
|
34
36
|
#
|
35
|
-
# @
|
37
|
+
# @raise [Expresenter::Fail] The expectation is `false`.
|
38
|
+
# @return [Expresenter::Pass] The expectation is `true`.
|
36
39
|
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
|
-
{
|
40
|
+
::Expresenter.call(pass?).with(
|
55
41
|
actual: exam.actual,
|
56
42
|
error: exam.exception,
|
57
43
|
expected: matcher.expected,
|
@@ -60,12 +46,14 @@ module Spectus
|
|
60
46
|
valid: exam.valid?,
|
61
47
|
matcher: matcher.class.to_sym,
|
62
48
|
level: level
|
63
|
-
|
49
|
+
)
|
64
50
|
end
|
65
51
|
|
52
|
+
protected
|
53
|
+
|
66
54
|
# @return [Symbol] The requirement level.
|
67
55
|
def level
|
68
|
-
self.class.name.split(
|
56
|
+
self.class.name.split("::").fetch(-1).upcase.to_sym
|
69
57
|
end
|
70
58
|
|
71
59
|
# @note The boolean comparison between the actual value and the expected
|
@@ -79,6 +67,4 @@ module Spectus
|
|
79
67
|
end
|
80
68
|
end
|
81
69
|
|
82
|
-
require_relative File.join(
|
83
|
-
require_relative File.join('..', 'result', 'fail')
|
84
|
-
require_relative File.join('..', 'result', 'pass')
|
70
|
+
require_relative File.join("..", "exam")
|
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.2.0
|
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-11 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.0.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.1
|
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,9 +193,6 @@ 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/common.rb
|
155
|
-
- lib/spectus/result/fail.rb
|
156
|
-
- lib/spectus/result/pass.rb
|
157
196
|
homepage: https://github.com/fixrb/spectus
|
158
197
|
licenses:
|
159
198
|
- MIT
|
@@ -166,14 +205,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
166
205
|
requirements:
|
167
206
|
- - ">="
|
168
207
|
- !ruby/object:Gem::Version
|
169
|
-
version:
|
208
|
+
version: 2.7.0
|
170
209
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
210
|
requirements:
|
172
211
|
- - ">="
|
173
212
|
- !ruby/object:Gem::Version
|
174
213
|
version: '0'
|
175
214
|
requirements: []
|
176
|
-
rubygems_version: 3.1.
|
215
|
+
rubygems_version: 3.1.4
|
177
216
|
signing_key:
|
178
217
|
specification_version: 4
|
179
218
|
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
|
data/lib/spectus/result/fail.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'common'
|
4
|
-
|
5
|
-
module Spectus
|
6
|
-
module Result
|
7
|
-
# The class that is responsible for reporting that the expectation is false.
|
8
|
-
class Fail < ::StandardError
|
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
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
data/lib/spectus/result/pass.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'common'
|
4
|
-
|
5
|
-
module Spectus
|
6
|
-
module Result
|
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
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|