spectus 3.0.9 → 3.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +67 -84
- data/lib/spectus.rb +3 -5
- data/lib/spectus/exam.rb +56 -0
- data/lib/spectus/expectation_target.rb +87 -70
- data/lib/spectus/requirement_level/base.rb +50 -75
- data/lib/spectus/requirement_level/may.rb +17 -0
- data/lib/spectus/requirement_level/must.rb +17 -0
- data/lib/spectus/requirement_level/should.rb +17 -0
- data/lib/spectus/result/common.rb +174 -0
- data/lib/spectus/result/fail.rb +40 -17
- data/lib/spectus/result/pass.rb +48 -21
- metadata +87 -91
- data/.gitignore +0 -11
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +0 -56
- data/.travis.yml +0 -28
- data/.yardopts +0 -1
- data/CODE_OF_CONDUCT.md +0 -13
- data/Gemfile +0 -5
- data/Rakefile +0 -23
- data/VERSION.semver +0 -1
- data/bin/console +0 -8
- data/bin/setup +0 -6
- data/checksum/spectus-2.0.0.gem.sha512 +0 -1
- data/checksum/spectus-2.0.1.gem.sha512 +0 -1
- data/checksum/spectus-2.0.2.gem.sha512 +0 -1
- data/checksum/spectus-2.0.3.gem.sha512 +0 -1
- data/checksum/spectus-2.0.4.gem.sha512 +0 -1
- data/checksum/spectus-2.1.0.gem.sha512 +0 -1
- data/checksum/spectus-2.1.1.gem.sha512 +0 -1
- data/checksum/spectus-2.1.2.gem.sha512 +0 -1
- data/checksum/spectus-2.1.3.gem.sha512 +0 -1
- data/checksum/spectus-2.10.0.gem.sha512 +0 -1
- data/checksum/spectus-2.2.0.gem.sha512 +0 -1
- data/checksum/spectus-2.3.0.gem.sha512 +0 -1
- data/checksum/spectus-2.3.1.gem.sha512 +0 -1
- data/checksum/spectus-2.4.0.gem.sha512 +0 -1
- data/checksum/spectus-2.5.0.gem.sha512 +0 -1
- data/checksum/spectus-2.6.0.gem.sha512 +0 -1
- data/checksum/spectus-2.7.0.gem.sha512 +0 -1
- data/checksum/spectus-2.7.1.gem.sha512 +0 -1
- data/checksum/spectus-2.8.0.gem.sha512 +0 -1
- data/checksum/spectus-2.9.0.gem.sha512 +0 -1
- data/checksum/spectus-2.9.1.gem.sha512 +0 -1
- data/checksum/spectus-2.9.2.gem.sha512 +0 -1
- data/checksum/spectus-3.0.0.gem.sha512 +0 -1
- data/checksum/spectus-3.0.1.gem.sha512 +0 -1
- data/checksum/spectus-3.0.2.gem.sha512 +0 -1
- data/checksum/spectus-3.0.3.gem.sha512 +0 -1
- data/checksum/spectus-3.0.5.gem.sha512 +0 -1
- data/checksum/spectus-3.0.6.gem.sha512 +0 -1
- data/checksum/spectus-3.0.7.gem.sha512 +0 -1
- data/checksum/spectus-3.0.8.gem.sha512 +0 -1
- data/lib/spectus/matchers.rb +0 -33
- data/lib/spectus/report.rb +0 -92
- data/lib/spectus/requirement_level/high.rb +0 -27
- data/lib/spectus/requirement_level/low.rb +0 -27
- data/lib/spectus/requirement_level/medium.rb +0 -27
- data/lib/spectus/result/base.rb +0 -112
- data/lib/spectus/sandbox.rb +0 -61
- data/pkg_checksum +0 -12
- data/spectus.gemspec +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee7d9fda32871f2db5571569f0b85a63edb9cdd4abb7149059bca0e218383a07
|
4
|
+
data.tar.gz: 530aefebbfedcea834fec61c14e79b79a4e71930a059c51de314c85c8264a299
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42d8f625fd2f0057416a41e3c46decefee155a24679443851882c36513fc8765c1ca437800ee94a031a11edf30ff81758f36e87e08959dbbefd64cc8d94ffbd9
|
7
|
+
data.tar.gz: b6607f0a2309f8dae7ceac5e8dc82bd2733b6289610a5b67ae258889395c15e496de38a13978726670a371bb9668eaf3a4f83e576d94e102f5b3b603d2ae558a
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,31 +1,19 @@
|
|
1
1
|
# Spectus
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/fixrb/spectus.svg?branch=master)][travis]
|
3
|
+
[![Build Status](https://api.travis-ci.org/fixrb/spectus.svg?branch=master)][travis]
|
4
4
|
[![Code Climate](https://codeclimate.com/github/fixrb/spectus/badges/gpa.svg)][codeclimate]
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/spectus.svg)][gem]
|
6
|
-
[![Inline docs](
|
7
|
-
[![Documentation](
|
6
|
+
[![Inline docs](https://inch-ci.org/github/fixrb/spectus.svg?branch=master)][inchpages]
|
7
|
+
[![Documentation](https://img.shields.io/:yard-docs-38c800.svg)][rubydoc]
|
8
8
|
|
9
|
-
> Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)'s requirement levels
|
10
|
-
|
11
|
-
## Contact
|
12
|
-
|
13
|
-
* Home page: https://github.com/fixrb/spectus
|
14
|
-
* Bugs/issues: https://github.com/fixrb/spectus/issues
|
15
|
-
* Support: https://stackoverflow.com/questions/tagged/spectus
|
16
|
-
|
17
|
-
## Rubies
|
18
|
-
|
19
|
-
* [MRI](https://www.ruby-lang.org/)
|
20
|
-
* [Rubinius](http://rubini.us/)
|
21
|
-
* [JRuby](http://jruby.org/)
|
9
|
+
> Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)'s requirement levels 🚥
|
22
10
|
|
23
11
|
## Installation
|
24
12
|
|
25
13
|
Add this line to your application's Gemfile:
|
26
14
|
|
27
15
|
```ruby
|
28
|
-
gem
|
16
|
+
gem "spectus"
|
29
17
|
```
|
30
18
|
|
31
19
|
And then execute:
|
@@ -40,6 +28,8 @@ Or install it yourself as:
|
|
40
28
|
|
41
29
|
An expectation is an assertion that is either `true` or `false`.
|
42
30
|
|
31
|
+
There are several scenarios:
|
32
|
+
|
43
33
|
| Requirement levels | **MUST** | **SHOULD** | **MAY** |
|
44
34
|
| ------------------------- | -------- | ---------- | ------- |
|
45
35
|
| Implemented & Matched | `true` | `true` | `true` |
|
@@ -47,39 +37,43 @@ An expectation is an assertion that is either `true` or `false`.
|
|
47
37
|
| Implemented & Exception | `false` | `false` | `false` |
|
48
38
|
| Not implemented | `false` | `false` | `true` |
|
49
39
|
|
50
|
-
|
40
|
+
Thus,
|
51
41
|
|
52
|
-
|
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.
|
53
44
|
|
54
|
-
|
55
|
-
* when the requirement level of an expectation does not end with `!`, the test is performed without isolation.
|
45
|
+
Both results share a common interface, and can be classified respectively as:
|
56
46
|
|
57
|
-
|
47
|
+
* ✅ a _success_, ⚠️ a _warning_ or 💡 an _info_;
|
48
|
+
* ❌ a _failure_ or 💥 an _error_.
|
58
49
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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.
|
65
57
|
|
66
58
|
Example of test without isolation:
|
67
59
|
|
68
60
|
```ruby
|
69
|
-
|
70
|
-
|
71
|
-
|
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)
|
72
65
|
greeting # => "Hello, Alice!"
|
73
66
|
```
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
There are two cases:
|
78
|
-
|
79
|
-
* when an expectation is `true`, an instance of `Spectus::Result::Pass` is returned;
|
80
|
-
* when an expectation is `false`, an instance of `Spectus::Result::Fail` is raised.
|
68
|
+
Example of test in isolation:
|
81
69
|
|
82
|
-
|
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
|
+
```
|
83
77
|
|
84
78
|
## Usage
|
85
79
|
|
@@ -89,24 +83,24 @@ To begin with, let's include __Spectus__:
|
|
89
83
|
include Spectus
|
90
84
|
```
|
91
85
|
|
92
|
-
### Absolute
|
86
|
+
### Absolute Requirement
|
93
87
|
|
94
|
-
Given the
|
88
|
+
Given the "`ルビー`" object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
|
95
89
|
|
96
90
|
```ruby
|
97
|
-
it {
|
98
|
-
# =>
|
91
|
+
it { "ルビー".valid_encoding? }.MUST be_true
|
92
|
+
# => Spectus::Result::Pass(actual: true, error: nil, expected: nil, got: true, matcher: :be_true, negate: false, level: :MUST, valid: true)
|
99
93
|
```
|
100
94
|
|
101
95
|
The result of the test shows that the spec passed.
|
102
96
|
|
103
|
-
### Absolute
|
97
|
+
### Absolute Prohibition
|
104
98
|
|
105
|
-
Given the `
|
99
|
+
Given the "`foo`" object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
|
106
100
|
|
107
101
|
```ruby
|
108
|
-
it {
|
109
|
-
# =>
|
102
|
+
it { "foo".length }.MUST_NOT raise_exception NoMethodError
|
103
|
+
# => Spectus::Result::Pass(actual: 3, error: nil, expected: NoMethodError, got: true, matcher: :raise_exception, negate: true, level: :MUST, valid: true)
|
110
104
|
```
|
111
105
|
|
112
106
|
The result of the test shows that the spec passed.
|
@@ -117,74 +111,63 @@ Given the `BasicObject` object, when it receives `superclass` method, then it **
|
|
117
111
|
|
118
112
|
```ruby
|
119
113
|
it { BasicObject.superclass }.SHOULD equal NilClass
|
120
|
-
# =>
|
114
|
+
# => Spectus::Result::Pass(actual: nil, error: nil, expected: NilClass, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
|
121
115
|
```
|
122
116
|
|
123
117
|
Instead of the expected `NilClass` class, its sole instance (which is `nil`) was returned.
|
124
118
|
However, because there isn't any exception, the result of the test shows that the spec passed.
|
125
119
|
|
126
|
-
### Not
|
120
|
+
### Not Recommended
|
127
121
|
|
128
|
-
Given the `
|
122
|
+
Given the "`1`" object, when it receives `+(1)` method, then it **SHOULD NOT** return the "`11`" value:
|
129
123
|
|
130
124
|
```ruby
|
131
|
-
it {
|
132
|
-
# Spectus::Result::Fail:
|
133
|
-
# from (irb):5
|
134
|
-
# from ./bin/console:7:in `<main>'
|
125
|
+
it { "1" + 1 }.SHOULD_NOT eql "11"
|
126
|
+
# 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)
|
135
127
|
```
|
136
128
|
|
137
129
|
There was a `TypeError` exception, the result of the test shows that the spec failed.
|
138
130
|
|
139
131
|
### Optional
|
140
132
|
|
141
|
-
Given the `
|
133
|
+
Given the "`foo`" object, when it receives `blank?` method, then it **MAY** be `false`:
|
142
134
|
|
143
135
|
```ruby
|
144
|
-
it {
|
145
|
-
# =>
|
136
|
+
it { "foo".blank? }.MAY be_false
|
137
|
+
# => 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)
|
146
138
|
```
|
147
139
|
|
148
|
-
The optional `blank?` method is not implemented (unlike in [Ruby on Rails](
|
140
|
+
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.
|
149
141
|
|
150
|
-
|
142
|
+
### More Examples
|
151
143
|
|
152
|
-
|
153
|
-
|
154
|
-
Although these checksums do not prevent malicious users from tampering with a
|
155
|
-
built Gem they can be used for basic integrity verification purposes.
|
144
|
+
A full list of unit tests can be viewed here:
|
145
|
+
[test.rb](https://github.com/fixrb/spectus/blob/master/test.rb)
|
156
146
|
|
157
|
-
|
158
|
-
example:
|
147
|
+
## Contact
|
159
148
|
|
160
|
-
|
161
|
-
|
149
|
+
* Home page: https://github.com/fixrb/spectus
|
150
|
+
* Bugs/issues: https://github.com/fixrb/spectus/issues
|
162
151
|
|
163
152
|
## Versioning
|
164
153
|
|
165
|
-
__Spectus__ follows [Semantic Versioning 2.0](
|
154
|
+
__Spectus__ follows [Semantic Versioning 2.0](https://semver.org/).
|
166
155
|
|
167
|
-
##
|
156
|
+
## License
|
168
157
|
|
169
|
-
|
170
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
171
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
172
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
173
|
-
5. Create a new Pull Request
|
158
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
174
159
|
|
175
|
-
|
160
|
+
***
|
176
161
|
|
177
|
-
|
162
|
+
<p>
|
163
|
+
This project is sponsored by:<br />
|
164
|
+
<a href="https://sashite.com/"><img
|
165
|
+
src="https://github.com/fixrb/spectus/raw/master/img/sashite.png"
|
166
|
+
alt="Sashite" /></a>
|
167
|
+
</p>
|
178
168
|
|
179
169
|
[gem]: https://rubygems.org/gems/spectus
|
180
170
|
[travis]: https://travis-ci.org/fixrb/spectus
|
181
171
|
[codeclimate]: https://codeclimate.com/github/fixrb/spectus
|
182
|
-
[
|
183
|
-
[
|
184
|
-
[rubydoc]: http://rubydoc.info/gems/spectus/frames
|
185
|
-
|
186
|
-
***
|
187
|
-
|
188
|
-
This project is sponsored by:
|
189
|
-
|
190
|
-
[![Sashite](https://pbs.twimg.com/profile_images/618485028322975744/PZ9qPuI__400x400.png)](https://sashite.com/)
|
172
|
+
[inchpages]: https://inch-ci.org/github/fixrb/spectus
|
173
|
+
[rubydoc]: https://rubydoc.info/gems/spectus/frames
|
data/lib/spectus.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "matchi/helper"
|
4
4
|
|
5
5
|
# Namespace for the Spectus library.
|
6
6
|
#
|
7
|
-
# @api public
|
8
|
-
#
|
9
7
|
# @example It MUST equal 42.
|
10
8
|
# require 'spectus'
|
11
9
|
# it { 42 }.MUST equal 42 # => #<Spectus::Result::Pass...>
|
12
10
|
module Spectus
|
13
|
-
include
|
11
|
+
include ::Matchi::Helper
|
14
12
|
|
15
13
|
# Expectations are built with this method.
|
16
14
|
#
|
@@ -25,4 +23,4 @@ module Spectus
|
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
28
|
-
require_relative File.join(
|
26
|
+
require_relative File.join("spectus", "expectation_target")
|
data/lib/spectus/exam.rb
ADDED
@@ -0,0 +1,56 @@
|
|
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,49 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'defi'
|
4
|
-
|
5
3
|
module Spectus
|
6
4
|
# Wraps the target of an expectation.
|
7
5
|
#
|
8
|
-
# @api public
|
9
|
-
#
|
10
6
|
# @example
|
11
7
|
# it { actual value } # => ExpectationTarget wrapping the block
|
12
8
|
class ExpectationTarget
|
13
|
-
# Create a new
|
9
|
+
# Create a new expectation target
|
14
10
|
#
|
15
|
-
# @
|
16
|
-
|
17
|
-
|
18
|
-
def initialize(&subject)
|
19
|
-
@subject = subject
|
20
|
-
@challenges = [block_challenge]
|
11
|
+
# @param callable [Proc] The object to test.
|
12
|
+
def initialize(&callable)
|
13
|
+
@callable = callable
|
21
14
|
end
|
22
15
|
|
23
|
-
# rubocop:disable
|
24
|
-
# rubocop:disable Naming/UncommunicativeMethodParamName
|
16
|
+
# rubocop:disable Naming/MethodName
|
25
17
|
|
26
|
-
# @api public
|
27
|
-
#
|
28
18
|
# This word, or the terms "REQUIRED" or "SHALL", mean that the
|
29
19
|
# definition is an absolute requirement of the specification.
|
30
20
|
#
|
31
21
|
# @example _Absolute requirement_ definition
|
32
22
|
# it { 'foo'.upcase }.MUST eql 'FOO'
|
33
23
|
#
|
34
|
-
# @param
|
24
|
+
# @param matcher [#matches?] The matcher.
|
35
25
|
#
|
36
26
|
# @return [Result::Fail, Result::Pass] Report if the spec pass or fail.
|
37
|
-
def MUST(
|
38
|
-
RequirementLevel::
|
27
|
+
def MUST(matcher)
|
28
|
+
RequirementLevel::Must.new(
|
29
|
+
callable: callable,
|
30
|
+
isolation: false,
|
31
|
+
negate: false,
|
32
|
+
matcher: matcher
|
33
|
+
).call
|
39
34
|
end
|
40
35
|
|
41
36
|
# @example _Absolute requirement_ definition with isolation
|
42
37
|
# it { 'foo'.upcase }.MUST! eql 'FOO'
|
43
38
|
#
|
44
39
|
# @see MUST
|
45
|
-
def MUST!(
|
46
|
-
RequirementLevel::
|
40
|
+
def MUST!(matcher)
|
41
|
+
RequirementLevel::Must.new(
|
42
|
+
callable: callable,
|
43
|
+
isolation: true,
|
44
|
+
negate: false,
|
45
|
+
matcher: matcher
|
46
|
+
).call
|
47
47
|
end
|
48
48
|
|
49
49
|
# This phrase, or the phrase "SHALL NOT", mean that the
|
@@ -52,19 +52,29 @@ module Spectus
|
|
52
52
|
# @example _Absolute prohibition_ definition
|
53
53
|
# it { 'foo'.size }.MUST_NOT equal 42
|
54
54
|
#
|
55
|
-
# @param
|
55
|
+
# @param matcher [#matches?] The matcher.
|
56
56
|
#
|
57
57
|
# @return [Result::Fail, Result::Pass] Report if the spec pass or fail.
|
58
|
-
def MUST_NOT(
|
59
|
-
RequirementLevel::
|
58
|
+
def MUST_NOT(matcher)
|
59
|
+
RequirementLevel::Must.new(
|
60
|
+
callable: callable,
|
61
|
+
isolation: false,
|
62
|
+
negate: true,
|
63
|
+
matcher: matcher
|
64
|
+
).call
|
60
65
|
end
|
61
66
|
|
62
67
|
# @example _Absolute prohibition_ definition with isolation
|
63
68
|
# it { 'foo'.size }.MUST_NOT! equal 42
|
64
69
|
#
|
65
70
|
# @see MUST_NOT
|
66
|
-
def MUST_NOT!(
|
67
|
-
RequirementLevel::
|
71
|
+
def MUST_NOT!(matcher)
|
72
|
+
RequirementLevel::Must.new(
|
73
|
+
callable: callable,
|
74
|
+
isolation: true,
|
75
|
+
negate: true,
|
76
|
+
matcher: matcher
|
77
|
+
).call
|
68
78
|
end
|
69
79
|
|
70
80
|
# This word, or the adjective "RECOMMENDED", mean that there
|
@@ -75,19 +85,29 @@ module Spectus
|
|
75
85
|
# @example _Recommended_ definition
|
76
86
|
# it { 'foo'.valid_encoding? }.SHOULD equal true
|
77
87
|
#
|
78
|
-
# @param
|
88
|
+
# @param matcher [#matches?] The matcher.
|
79
89
|
#
|
80
90
|
# @return [Result::Fail, Result::Pass] Report if the spec pass or fail.
|
81
|
-
def SHOULD(
|
82
|
-
RequirementLevel::
|
91
|
+
def SHOULD(matcher)
|
92
|
+
RequirementLevel::Should.new(
|
93
|
+
callable: callable,
|
94
|
+
isolation: false,
|
95
|
+
negate: false,
|
96
|
+
matcher: matcher
|
97
|
+
).call
|
83
98
|
end
|
84
99
|
|
85
100
|
# @example _Recommended_ definition with isolation
|
86
101
|
# it { 'foo'.valid_encoding? }.SHOULD! equal true
|
87
102
|
#
|
88
103
|
# @see SHOULD
|
89
|
-
def SHOULD!(
|
90
|
-
RequirementLevel::
|
104
|
+
def SHOULD!(matcher)
|
105
|
+
RequirementLevel::Should.new(
|
106
|
+
callable: callable,
|
107
|
+
isolation: true,
|
108
|
+
negate: false,
|
109
|
+
matcher: matcher
|
110
|
+
).call
|
91
111
|
end
|
92
112
|
|
93
113
|
# This phrase, or the phrase "NOT RECOMMENDED" mean that
|
@@ -99,19 +119,29 @@ module Spectus
|
|
99
119
|
# @example _Not recommended_ definition
|
100
120
|
# it { ''.blank? }.SHOULD_NOT raise_exception NoMethodError
|
101
121
|
#
|
102
|
-
# @param
|
122
|
+
# @param matcher [#matches?] The matcher.
|
103
123
|
#
|
104
124
|
# @return [Result::Fail, Result::Pass] Report if the spec pass or fail.
|
105
|
-
def SHOULD_NOT(
|
106
|
-
RequirementLevel::
|
125
|
+
def SHOULD_NOT(matcher)
|
126
|
+
RequirementLevel::Should.new(
|
127
|
+
callable: callable,
|
128
|
+
isolation: false,
|
129
|
+
negate: true,
|
130
|
+
matcher: matcher
|
131
|
+
).call
|
107
132
|
end
|
108
133
|
|
109
134
|
# @example _Not recommended_ definition with isolation
|
110
135
|
# it { ''.blank? }.SHOULD_NOT! raise_exception NoMethodError
|
111
136
|
#
|
112
137
|
# @see SHOULD_NOT
|
113
|
-
def SHOULD_NOT!(
|
114
|
-
RequirementLevel::
|
138
|
+
def SHOULD_NOT!(matcher)
|
139
|
+
RequirementLevel::Should.new(
|
140
|
+
callable: callable,
|
141
|
+
isolation: true,
|
142
|
+
negate: true,
|
143
|
+
matcher: matcher
|
144
|
+
).call
|
115
145
|
end
|
116
146
|
|
117
147
|
# This word, or the adjective "OPTIONAL", mean that an item is
|
@@ -129,53 +159,40 @@ module Spectus
|
|
129
159
|
# @example _Optional_ definition
|
130
160
|
# it { 'foo'.bar }.MAY match /^foo$/
|
131
161
|
#
|
132
|
-
# @param
|
162
|
+
# @param matcher [#matches?] The matcher.
|
133
163
|
#
|
134
164
|
# @return [Result::Fail, Result::Pass] Report if the spec pass or fail.
|
135
|
-
def MAY(
|
136
|
-
RequirementLevel::
|
165
|
+
def MAY(matcher)
|
166
|
+
RequirementLevel::May.new(
|
167
|
+
callable: callable,
|
168
|
+
isolation: false,
|
169
|
+
negate: false,
|
170
|
+
matcher: matcher
|
171
|
+
).call
|
137
172
|
end
|
138
173
|
|
139
174
|
# @example _Optional_ definition with isolation
|
140
175
|
# it { 'foo'.bar }.MAY! match /^foo$/
|
141
176
|
#
|
142
177
|
# @see MAY
|
143
|
-
def MAY!(
|
144
|
-
RequirementLevel::
|
178
|
+
def MAY!(matcher)
|
179
|
+
RequirementLevel::May.new(
|
180
|
+
callable: callable,
|
181
|
+
isolation: true,
|
182
|
+
negate: false,
|
183
|
+
matcher: matcher
|
184
|
+
).call
|
145
185
|
end
|
146
186
|
|
147
|
-
# rubocop:enable
|
148
|
-
# rubocop:enable Naming/UncommunicativeMethodParamName
|
187
|
+
# rubocop:enable Naming/MethodName
|
149
188
|
|
150
|
-
|
189
|
+
protected
|
151
190
|
|
152
|
-
#
|
153
|
-
|
154
|
-
# @return [BasicObject] The front object to be tested.
|
155
|
-
attr_reader :subject
|
156
|
-
private :subject
|
157
|
-
|
158
|
-
# @!attribute [r] challenges
|
159
|
-
#
|
160
|
-
# @return [Array] The challenges to call on the subject.
|
161
|
-
attr_reader :challenges
|
162
|
-
private :challenges
|
163
|
-
|
164
|
-
# rubocop:enable Style/AccessModifierDeclarations
|
165
|
-
|
166
|
-
private
|
167
|
-
|
168
|
-
# The first default challenge for blocks.
|
169
|
-
#
|
170
|
-
# @since 2.10.0
|
171
|
-
#
|
172
|
-
# @return [Defi] The challenge for blocks.
|
173
|
-
def block_challenge
|
174
|
-
::Defi.send(:call)
|
175
|
-
end
|
191
|
+
# @return [#call] The callable object to test.
|
192
|
+
attr_reader :callable
|
176
193
|
end
|
177
194
|
end
|
178
195
|
|
179
|
-
require_relative File.join(
|
180
|
-
require_relative File.join(
|
181
|
-
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")
|