spectus 3.0.10 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13481b61d71af90cd7460d98c76eb3e13914e2720f7364433a746571d78e63d6
4
- data.tar.gz: 71843f9b4ad356df5a992494978a2275dcccafb207eebcc5067e21d04a1438c4
3
+ metadata.gz: 61974cb7f8cc0f5e3feaab04f902099123a2f71fa815af3d5d5230b49a8dc573
4
+ data.tar.gz: bd85d771520589ee1a10ff672f610e04ad00bdb254343241f7aacc32a1af8f5a
5
5
  SHA512:
6
- metadata.gz: 538622c03f5c9e52cda46b1c76b7c7d80ffad22e18abb6bc56a52ad371bdacb4ed292b9b6a44c29894ac1ca2ea319e22c053a448baa32aedf28ec143fa8cba11
7
- data.tar.gz: 638c15fc458db6ee8cc4381b16235df22ed8c6020f56b9d79f8330f28f32af34d9a50684b8b87e43ed83bac10c7c2822a8ef98cb03407ed2edae5d584312ebbd
6
+ metadata.gz: baf4571bbc6b585b87b6d98752bf4ba1880c99fb05bfbb1d66d0587aadc8ec9fb3481cacb5bd8f193a53eca5269002a92d1a9900ee7e9ad8874e5950a7b5dd8a
7
+ data.tar.gz: b0819b033292607bc53ba1c690f09dad9c95566e70e102f02cde1a9b0c6e42d6b58db1dd16d5ece1423e8bef94841c3d9b37775d2f08e205e2a054df079ad97e
data/README.md CHANGED
@@ -1,24 +1,12 @@
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](http://inch-ci.org/github/fixrb/spectus.svg?branch=master)][inchpages]
7
- [![Documentation](http://img.shields.io/:yard-docs-38c800.svg)][rubydoc]
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, and some matchers for Ruby.
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
 
@@ -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
- ## Isolation
40
+ Thus,
51
41
 
52
- There are two cases:
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
- * when the requirement level of an expectation ends with `!`, the test is performed in isolation;
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
- Example of test in isolation:
47
+ * a _success_, a ⚠️ _warning_ or an 💡 _info_;
48
+ * a ❌ _failure_ or an 💥 _error_.
58
49
 
59
- ```ruby
60
- greeting = 'Hello, world!'
61
- it { greeting.gsub!('world', 'Alice') }.MUST! eql 'Hello, Alice!'
62
- # => #<Spectus::Result::Pass:0x007fa5022d8760 @message="Pass: Expected \"Hello, Alice!\" to eql \"Hello, Alice!\".", @subject=#<Proc:0x007fa5022d8e18@(irb):3>, @challenge=#<Defi::Challenge:0x007fa5022d8a08 @method=:call, @args=[]>, @actual="Hello, Alice!", @expected=#<Matchi::Eql:0x007fa5022d8cb0 @expected="Hello, Alice!">, @got=true, @error=nil, @level=:High, @negate=false, @valid=true>
63
- greeting # => "Hello, world!"
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
61
+ include Spectus
69
62
  greeting = 'Hello, world!'
70
63
  it { greeting.gsub!('world', 'Alice') }.MUST eql 'Hello, Alice!'
71
- # => #<Spectus::Result::Pass:0x007f982304d310 @message="Pass: Expected \"Hello, Alice!\" to eql \"Hello, Alice!\".", @subject=#<Proc:0x007f982304fbb0@(irb):3>, @challenge=#<Defi::Challenge:0x007f982304f890 @method=:call, @args=[]>, @actual="Hello, Alice!", @expected=#<Matchi::Eql:0x007f982304f200 @expected="Hello, Alice!">, @got=true, @error=nil, @level=:High, @negate=false, @valid=true>
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
- ## Results
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
- Both instances share the same interface.
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 requirement
86
+ ### Absolute Requirement
93
87
 
94
- Given the `"ルビー"` object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
88
+ Given the "`ルビー`" object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
95
89
 
96
90
  ```ruby
97
91
  it { 'ルビー'.valid_encoding? }.MUST be_true
98
- # => #<Spectus::Result::Pass:0x007ffd7d00af50 @message="Pass: Expected true to be_true.", @subject=#<Proc:0x007ffd7d010130@(irb):2>, @challenge=#<Defi::Challenge:0x007ffd7d0116e8 @method=:call, @args=[]>, @actual=true, @expected=#<Matchi::BeTrue:0x007ffd7d012188>, @got=true, @error=nil, @level=:High, @negate=false, @valid=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 prohibition
97
+ ### Absolute Prohibition
104
98
 
105
- Given the `"foo"` object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
99
+ Given the "`foo`" object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
106
100
 
107
101
  ```ruby
108
102
  it { 'foo'.length }.MUST_NOT raise_exception NoMethodError
109
- # => #<Spectus::Result::Pass:0x007ffd7b890af0 @message="Pass: Expected 3 not to raise_exception NoMethodError.", @subject=#<Proc:0x007ffd7b8913b0@(irb):3>, @challenge=#<Defi::Challenge:0x007ffd7b891248 @method=:call, @args=[]>, @actual=3, @expected=#<Matchi::RaiseException:0x007ffd7b891130 @expected=NoMethodError>, @got=true, @error=nil, @level=:High, @negate=true, @valid=true>
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,69 @@ 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
- # => #<Spectus::Result::Pass:0x007ffd7b871a38 @message="Info: Expected nil to equal NilClass.", @subject=#<Proc:0x007ffd7b872460@(irb):4>, @challenge=#<Defi::Challenge:0x007ffd7b872370 @method=:call, @args=[]>, @actual=nil, @expected=#<Matchi::Equal:0x007ffd7b872140 @expected=NilClass>, @got=false, @error=nil, @level=:Medium, @negate=false, @valid=false>
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 recommended
120
+ ### Not Recommended
127
121
 
128
- Given the `"1"` object, when it receives `+(1)` method, then it **SHOULD NOT** return the `"11"` value:
122
+ Given the "`1`" object, when it receives `+(1)` method, then it **SHOULD NOT** return the "`11`" value:
129
123
 
130
124
  ```ruby
131
125
  it { '1' + 1 }.SHOULD_NOT eql '11'
132
- # Spectus::Result::Fail: Error: no implicit conversion of Fixnum into String (TypeError).
133
- # from (irb):5
134
- # from ./bin/console:7:in `<main>'
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 `"foo"` object, when it receives `blank?` method, then it **MAY** be `false`:
133
+ Given the "`foo`" object, when it receives `blank?` method, then it **MAY** be `false`:
142
134
 
143
135
  ```ruby
144
136
  it { 'foo'.blank? }.MAY be_false
145
- # => #<Spectus::Result::Pass:0x007ffd7bbc3cb8 @message="Info: undefined method `blank?' for \"foo\":String (NoMethodError).", @subject=#<Proc:0x007ffd7b8285b8@(irb):6>, @challenge=#<Defi::Challenge:0x007ffd7b8284f0 @method=:call, @args=[]>, @actual=nil, @expected=#<Matchi::BeFalse:0x007ffd7b828310>, @got=nil, @error=#<NoMethodError: undefined method `blank?' for "foo":String>, @level=:Low, @negate=false, @valid=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](http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F), for instance), so the result of the test shows that the spec passed.
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
- ## Security
142
+ ### More Examples
151
143
 
152
- As a basic form of security __Spectus__ provides a set of SHA512 checksums for
153
- every Gem release. These checksums can be found in the `checksum/` directory.
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
+ An exhaustive list of examples can also be viewed here:
145
+ [test.rb](https://github.com/fixrb/spectus/raw/master/test.rb)
156
146
 
157
- The checksum of a file can be checked using the `sha512sum` command. For
158
- example:
147
+ ## Contact
159
148
 
160
- $ sha512sum pkg/spectus-2.3.0.gem
161
- e9e35e1953104e2d428b0f217e418db3c1baecd9e011b2545f9fcba4ff7e3bba674c6b928b3d8db842a139cd7cc9806d77ebdc7f710ece4f2aecb343703e2451 pkg/spectus-2.3.0.gem
149
+ * Home page: https://github.com/fixrb/spectus
150
+ * Bugs/issues: https://github.com/fixrb/spectus/issues
162
151
 
163
- ## Versioning
152
+ ## Rubies
164
153
 
165
- __Spectus__ follows [Semantic Versioning 2.0](http://semver.org/).
154
+ * [MRI](https://www.ruby-lang.org/)
155
+ * [Rubinius](https://rubinius.com/)
156
+ * [JRuby](https://www.jruby.org/)
166
157
 
167
- ## Contributing
158
+ ## Versioning
168
159
 
169
- 1. [Fork it](https://github.com/fixrb/spectus/fork)
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
160
+ __Spectus__ follows [Semantic Versioning 2.0](https://semver.org/).
174
161
 
175
162
  ## License
176
163
 
177
- See `LICENSE.md` file.
178
-
179
- [gem]: https://rubygems.org/gems/spectus
180
- [travis]: https://travis-ci.org/fixrb/spectus
181
- [codeclimate]: https://codeclimate.com/github/fixrb/spectus
182
- [gemnasium]: https://gemnasium.com/fixrb/spectus
183
- [inchpages]: http://inch-ci.org/github/fixrb/spectus
184
- [rubydoc]: http://rubydoc.info/gems/spectus/frames
164
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
185
165
 
186
166
  ***
187
167
 
188
- This project is sponsored by:
168
+ <p>
169
+ This project is sponsored by:<br />
170
+ <a href="https://sashite.com/"><img
171
+ src="https://github.com/fixrb/spectus/raw/master/img/sashite.png"
172
+ alt="Sashite" /></a>
173
+ </p>
189
174
 
190
- [![Sashite](https://pbs.twimg.com/profile_images/618485028322975744/PZ9qPuI__400x400.png)](https://sashite.com/)
175
+ [gem]: https://rubygems.org/gems/spectus
176
+ [travis]: https://travis-ci.org/fixrb/spectus
177
+ [codeclimate]: https://codeclimate.com/github/fixrb/spectus
178
+ [inchpages]: https://inch-ci.org/github/fixrb/spectus
179
+ [rubydoc]: https://rubydoc.info/gems/spectus/frames
@@ -1,16 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative File.join('spectus', 'matchers')
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 Matchers
11
+ include ::Matchi::Helper
14
12
 
15
13
  # Expectations are built with this method.
16
14
  #
@@ -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 expection target
9
+ # Create a new expectation target
14
10
  #
15
- # @api private
16
- #
17
- # @param subject [Proc] The value which is compared with the expected value.
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 Style/MethodName
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 m [#matches?] The matcher.
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(m)
38
- RequirementLevel::High.new(m, false, subject, *challenges).result
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!(m)
46
- RequirementLevel::High.new(m, false, subject, *challenges).result(true)
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 m [#matches?] The matcher.
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(m)
59
- RequirementLevel::High.new(m, true, subject, *challenges).result
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!(m)
67
- RequirementLevel::High.new(m, true, subject, *challenges).result(true)
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 m [#matches?] The matcher.
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(m)
82
- RequirementLevel::Medium.new(m, false, subject, *challenges).result
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!(m)
90
- RequirementLevel::Medium.new(m, false, subject, *challenges).result(true)
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 m [#matches?] The matcher.
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(m)
106
- RequirementLevel::Medium.new(m, true, subject, *challenges).result
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!(m)
114
- RequirementLevel::Medium.new(m, true, subject, *challenges).result(true)
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 m [#matches?] The matcher.
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(m)
136
- RequirementLevel::Low.new(m, false, subject, *challenges).result
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!(m)
144
- RequirementLevel::Low.new(m, false, subject, *challenges).result(true)
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 Style/MethodName
148
- # rubocop:enable Naming/UncommunicativeMethodParamName
187
+ # rubocop:enable Naming/MethodName
149
188
 
150
- # rubocop:disable Style/AccessModifierDeclarations
189
+ protected
151
190
 
152
- # @!attribute [r] subject
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('requirement_level', 'high')
180
- require_relative File.join('requirement_level', 'medium')
181
- require_relative File.join('requirement_level', 'low')
196
+ require_relative File.join('requirement_level', 'must')
197
+ require_relative File.join('requirement_level', 'should')
198
+ require_relative File.join('requirement_level', 'may')