spectus 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +0 -5
- data/.travis.yml +12 -3
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +3 -0
- data/LICENSE.md +17 -18
- data/README.md +18 -199
- data/VERSION.semver +1 -1
- data/bin/console +7 -0
- data/bin/setup +5 -0
- data/lib/spectus.rb +12 -2
- data/lib/spectus/expectation_target.rb +86 -12
- data/lib/spectus/requirement_level/high.rb +36 -0
- data/lib/spectus/requirement_level/low.rb +22 -0
- data/lib/spectus/requirement_level/medium.rb +22 -0
- data/lib/spectus/sandbox.rb +31 -0
- data/{spectus.pem → spectus-gem-public_cert.pem} +0 -0
- data/spectus.gemspec +14 -10
- metadata +50 -72
- metadata.gz.sig +0 -0
- data/.coveralls.yml +0 -1
- data/example/duck/README.md +0 -6
- data/example/duck/app.rb +0 -3
- data/example/duck/lib.rb +0 -13
- data/example/duck/test.rb +0 -43
- data/lib/spectus/dsl.rb +0 -20
- data/lib/spectus/matcher.rb +0 -34
- data/lib/spectus/matcher/eql.rb +0 -16
- data/lib/spectus/matcher/equal.rb +0 -16
- data/lib/spectus/matcher/match.rb +0 -16
- data/lib/spectus/matcher/raise_exception.rb +0 -22
- data/lib/spectus/version.rb +0 -9
- data/test/helper_test.rb +0 -4
- data/test/spectus/helper_test.rb +0 -1
- data/test/spectus/matcher/built_in/helper_test.rb +0 -1
- data/test/spectus/matcher/built_in/test_eql.rb +0 -21
- data/test/spectus/matcher/built_in/test_equal.rb +0 -21
- data/test/spectus/matcher/built_in/test_match.rb +0 -21
- data/test/spectus/matcher/built_in/test_raise_exception.rb +0 -21
- data/test/spectus/matcher/custom/be_prime/helper_test.rb +0 -13
- data/test/spectus/matcher/custom/be_prime/test_be_prime.rb +0 -21
- data/test/spectus/matcher/custom/be_the_answer/helper_test.rb +0 -11
- data/test/spectus/matcher/custom/be_the_answer/test_be_the_answer.rb +0 -21
- data/test/spectus/matcher/custom/helper_test.rb +0 -1
- data/test/spectus/matcher/custom/start_with/helper_test.rb +0 -15
- data/test/spectus/matcher/custom/start_with/test_start_with.rb +0 -21
- data/test/spectus/matcher/helper_test.rb +0 -1
- data/test/spectus/test_dsl.rb +0 -9
- data/test/spectus/test_matcher.rb +0 -38
- data/test/spectus/test_version.rb +0 -11
- data/test/support.rb +0 -3
- data/test/support/coverage.rb +0 -11
- data/test/support/env.rb +0 -1
- data/test/support/immutable.rb +0 -12
- data/test/support/presenter.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 867183006b16f6ab6f0d641efbfd37380a4612b8
|
4
|
+
data.tar.gz: a478b86f508003282d7544cfd660a6b811b71cb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 252c54bd2591df3ff5eb38b27ae5482855d08346c9679901bea0d6fba059134a678d9d79235a621c94de6d970eaf195f96144d52034f42379ce903ce46de92f7
|
7
|
+
data.tar.gz: 9576c89c47fa07424278f9bcff57e5fd26cf9075a239fc2e3db2e367eedb696e656296a6a07a4ced7ea923a1fc156f493f62410211970ae10262b69d943ad90c
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
2
|
+
sudo: false
|
3
|
+
cache: bundler
|
4
|
+
script: 'bundle exec rake test:coverage --trace'
|
5
|
+
before_install:
|
6
|
+
- gem install bundler
|
3
7
|
rvm:
|
4
|
-
-
|
5
|
-
- 2.
|
8
|
+
- 1.9.3
|
9
|
+
- 2.0
|
10
|
+
- 2.1
|
11
|
+
- 2.2
|
6
12
|
- ruby-head
|
13
|
+
- jruby
|
14
|
+
- jruby-head
|
15
|
+
- rbx-2
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
CHANGED
data/LICENSE.md
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
3
|
+
Copyright (c) 2014 Cyril Wack
|
4
4
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
the following conditions:
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
12
11
|
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
15
14
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
OF
|
22
|
-
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
# Spectus
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/fixrb/spectus.svg?branch=master)](https://travis-ci.org/fixrb/spectus)
|
4
|
-
[![Coverage Status](http://img.shields.io/coveralls/fixrb/spectus.svg?branch=master)](https://coveralls.io/r/fixrb/spectus)
|
5
4
|
[![Dependency Status](https://gemnasium.com/fixrb/spectus.svg)](https://gemnasium.com/fixrb/spectus)
|
6
5
|
[![Gem Version](http://img.shields.io/gem/v/spectus.svg)](https://rubygems.org/gems/spectus)
|
7
6
|
[![Inline docs](http://inch-ci.org/github/fixrb/spectus.svg?branch=master)](http://inch-ci.org/github/fixrb/spectus)
|
8
7
|
[![Documentation](http://img.shields.io/:yard-docs-38c800.svg)](http://rubydoc.info/gems/spectus/frames)
|
9
8
|
|
10
|
-
> Expectation library with some
|
9
|
+
> Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)'s requirement levels, and some matchers for Ruby.
|
11
10
|
|
12
11
|
## Contact
|
13
12
|
|
@@ -17,7 +16,9 @@
|
|
17
16
|
|
18
17
|
## Rubies
|
19
18
|
|
20
|
-
|
19
|
+
* [MRI](https://www.ruby-lang.org/)
|
20
|
+
* [Rubinius](http://rubini.us/)
|
21
|
+
* [JRuby](http://jruby.org/)
|
21
22
|
|
22
23
|
## Installation
|
23
24
|
|
@@ -29,221 +30,47 @@ gem 'spectus'
|
|
29
30
|
|
30
31
|
And then execute:
|
31
32
|
|
32
|
-
|
33
|
-
$ bundle
|
34
|
-
```
|
33
|
+
$ bundle
|
35
34
|
|
36
35
|
Or install it yourself as:
|
37
36
|
|
38
|
-
|
39
|
-
$ gem install spectus
|
40
|
-
```
|
41
|
-
|
42
|
-
## Why would I want this library?
|
43
|
-
|
44
|
-
* It's 143 lines of fast and KISS code.
|
45
|
-
* Atomic state transitions, unmutated objects, thread-safe.
|
46
|
-
* Provides a generic and consistent DSL for assertions.
|
47
|
-
|
48
|
-
## API
|
49
|
-
|
50
|
-
The [Spectus DSL](lib/spectus/dsl.rb) provides the `expect` method.
|
51
|
-
It takes a block parameter and responds to:
|
52
|
-
|
53
|
-
* `to(definition)`
|
54
|
-
* `not_to(definition)`
|
55
|
-
|
56
|
-
Then, it returns `true` or `false`; or it raises an exception.
|
37
|
+
$ gem install spectus
|
57
38
|
|
58
39
|
## Usage
|
59
40
|
|
60
|
-
|
61
|
-
class Duck
|
62
|
-
def walks
|
63
|
-
"Klop klop!"
|
64
|
-
end
|
65
|
-
|
66
|
-
def swims
|
67
|
-
"Swoosh..."
|
68
|
-
end
|
69
|
-
|
70
|
-
def quacks
|
71
|
-
puts "Quaaaaaack!"
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
@bird = Duck.new
|
76
|
-
```
|
77
|
-
|
78
|
-
> When I see a `#<Duck:0x007f96b285d6d0>` that ...
|
41
|
+
**Absolute requirement** definition:
|
79
42
|
|
80
43
|
```ruby
|
81
|
-
|
82
|
-
extend Spectus::DSL
|
83
|
-
|
84
|
-
# Let's define the custom matcher `capture_stdout`.
|
85
|
-
require 'stringio'
|
86
|
-
module Spectus
|
87
|
-
module Matcher
|
88
|
-
class CaptureStdout
|
89
|
-
def initialize expected
|
90
|
-
@expected = expected
|
91
|
-
end
|
92
|
-
|
93
|
-
def matches?
|
94
|
-
begin
|
95
|
-
orig_std = $stdout
|
96
|
-
$stdout = StringIO.new
|
97
|
-
yield
|
98
|
-
$stdout.string.eql? @expected
|
99
|
-
ensure
|
100
|
-
$stdout = orig_std
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
expectation_1 = expect { @bird.walks }.to eql: "Klop klop!"
|
108
|
-
expectation_2 = expect { @bird.swims }.to eql: "Swoosh..."
|
109
|
-
expectation_3 = expect { @bird.quacks }.to capture_stdout: "Quaaaaaack!\n"
|
110
|
-
expectation_4 = expect { @bird.speaks }.to raise_exception: NoMethodError
|
111
|
-
|
112
|
-
case (expectation_1 == true &&
|
113
|
-
expectation_2 == true &&
|
114
|
-
expectation_3 == true &&
|
115
|
-
expectation_4 == true)
|
116
|
-
when true then puts "I call that #{@bird} a duck."
|
117
|
-
else abort 'WAT?'
|
118
|
-
end
|
44
|
+
Spectus.this { 'foo'.upcase }.MUST eql: 'FOO' # => true
|
119
45
|
```
|
120
46
|
|
121
|
-
|
122
|
-
|
123
|
-
## Built-in matchers
|
124
|
-
|
125
|
-
### Equivalence
|
47
|
+
**Absolute prohibition** definition:
|
126
48
|
|
127
49
|
```ruby
|
128
|
-
|
50
|
+
Spectus.this { 'foo'.length }.MUST_NOT equal: 42 # => true
|
129
51
|
```
|
130
52
|
|
131
|
-
|
53
|
+
**Recommended** definition:
|
132
54
|
|
133
55
|
```ruby
|
134
|
-
|
56
|
+
Spectus.this { 'foo'.valid_encoding? }.SHOULD equal: true # => true
|
135
57
|
```
|
136
58
|
|
137
|
-
|
59
|
+
**Not recommended** definition:
|
138
60
|
|
139
61
|
```ruby
|
140
|
-
|
62
|
+
Spectus.this { ''.blank? }.SHOULD_NOT raise_exception: NoMethodError # => false
|
141
63
|
```
|
142
64
|
|
143
|
-
|
144
|
-
|
145
|
-
```ruby
|
146
|
-
expect { Foo }.to raise_exception: NameError # => true
|
147
|
-
```
|
148
|
-
|
149
|
-
## Custom matchers
|
150
|
-
|
151
|
-
Custom matchers can also be defined for expressing expectations.
|
152
|
-
|
153
|
-
### Be prime
|
154
|
-
|
155
|
-
The following expression...
|
65
|
+
**Optional** definition:
|
156
66
|
|
157
67
|
```ruby
|
158
|
-
|
159
|
-
expect { Prime.prime? 42 }.to equal: false # => true
|
68
|
+
Spectus.this { 'foo'.bar }.MAY match: /^foo$/ # => true
|
160
69
|
```
|
161
70
|
|
162
|
-
|
163
|
-
|
164
|
-
```ruby
|
165
|
-
expect { 42 }.not_to :be_prime # => true
|
166
|
-
```
|
167
|
-
|
168
|
-
It can be done with this custom matcher:
|
169
|
-
|
170
|
-
```ruby
|
171
|
-
require 'prime'
|
172
|
-
|
173
|
-
module Spectus
|
174
|
-
module Matcher
|
175
|
-
class BePrime
|
176
|
-
def matches?
|
177
|
-
Prime.prime? yield
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
```
|
183
|
-
|
184
|
-
### Be the answer
|
185
|
-
|
186
|
-
The following expression...
|
187
|
-
|
188
|
-
```ruby
|
189
|
-
expect { 42 }.to equal: 42 # => true
|
190
|
-
```
|
191
|
-
|
192
|
-
...could be refactored into:
|
193
|
-
|
194
|
-
```ruby
|
195
|
-
expect { 42 }.to :be_the_answer # => true
|
196
|
-
```
|
197
|
-
|
198
|
-
It can be done with this custom matcher:
|
199
|
-
|
200
|
-
```ruby
|
201
|
-
module Spectus
|
202
|
-
module Matcher
|
203
|
-
class BeTheAnswer
|
204
|
-
def matches?
|
205
|
-
42.equal? yield
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
```
|
211
|
-
|
212
|
-
### Start with
|
213
|
-
|
214
|
-
The following expression...
|
215
|
-
|
216
|
-
```ruby
|
217
|
-
expect { 'foobar' }.to match: /^foo/ # => true
|
218
|
-
```
|
219
|
-
|
220
|
-
...could be refactored into:
|
221
|
-
|
222
|
-
```ruby
|
223
|
-
expect { 'foobar' }.to start_with: 'foo' # => true
|
224
|
-
```
|
225
|
-
|
226
|
-
It can be done with this custom matcher:
|
227
|
-
|
228
|
-
```ruby
|
229
|
-
module Spectus
|
230
|
-
module Matcher
|
231
|
-
class StartWith
|
232
|
-
def initialize expected
|
233
|
-
@expected = expected
|
234
|
-
end
|
235
|
-
|
236
|
-
def matches?
|
237
|
-
!Regexp.new("^#{@expected}").match(yield).nil?
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
```
|
243
|
-
|
244
|
-
## Presentations
|
71
|
+
## Versioning
|
245
72
|
|
246
|
-
|
73
|
+
__Spectus__ follows [Semantic Versioning 2.0](http://semver.org/).
|
247
74
|
|
248
75
|
## Contributing
|
249
76
|
|
@@ -252,11 +79,3 @@ end
|
|
252
79
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
253
80
|
4. Push to the branch (`git push origin my-new-feature`)
|
254
81
|
5. Create a new Pull Request
|
255
|
-
|
256
|
-
## Versioning
|
257
|
-
|
258
|
-
__Spectus__ follows [Semantic Versioning 2.0](http://semver.org/)
|
259
|
-
|
260
|
-
## Copyright
|
261
|
-
|
262
|
-
© 2014 [Cyril Wack](https://plus.google.com/+CyrilWack?rel=author)
|
data/VERSION.semver
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/bin/console
ADDED
data/bin/setup
ADDED
data/lib/spectus.rb
CHANGED
@@ -1,8 +1,18 @@
|
|
1
|
-
require_relative File.join 'spectus', '
|
2
|
-
require_relative File.join 'spectus', 'version'
|
1
|
+
require_relative File.join 'spectus', 'expectation_target'
|
3
2
|
|
4
3
|
# Namespace for the Spectus library.
|
5
4
|
#
|
6
5
|
# @api private
|
7
6
|
module Spectus
|
7
|
+
# Expectations are built with this method.
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
#
|
11
|
+
# @example Absolute requirement definition
|
12
|
+
# this { 42 }.MUST equal: 42 # => true
|
13
|
+
#
|
14
|
+
# @return [ExpectationTarget] the expectation target.
|
15
|
+
def self.this(&input)
|
16
|
+
ExpectationTarget.new(&input)
|
17
|
+
end
|
8
18
|
end
|
@@ -1,32 +1,106 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative File.join 'requirement_level', 'high'
|
2
|
+
require_relative File.join 'requirement_level', 'medium'
|
3
|
+
require_relative File.join 'requirement_level', 'low'
|
2
4
|
|
3
5
|
module Spectus
|
4
|
-
|
5
6
|
# Wraps the target of an expectation.
|
6
7
|
#
|
7
8
|
# @example
|
8
|
-
#
|
9
|
+
# this { stuff } # => ExpectationTarget wrapping the block
|
9
10
|
class ExpectationTarget < BasicObject
|
10
|
-
|
11
|
+
# Create a new expection target
|
12
|
+
#
|
13
|
+
def initialize(&actual)
|
11
14
|
@actual = actual
|
12
15
|
end
|
13
16
|
|
14
|
-
#
|
17
|
+
# This word, or the terms "REQUIRED" or "SHALL", mean that the
|
18
|
+
# definition is an absolute requirement of the specification.
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
#
|
22
|
+
# @example _Absolute requirement_ definition
|
23
|
+
# this { 'foo'.upcase }.MUST eql: 'FOO' # => true
|
24
|
+
#
|
25
|
+
# @param [Hash] definition
|
26
|
+
#
|
27
|
+
# @return [Boolean] report if the expectation is true or false.
|
28
|
+
def MUST(definition)
|
29
|
+
RequirementLevel::High.new(definition).pass?(&@actual)
|
30
|
+
end
|
31
|
+
|
32
|
+
# This phrase, or the phrase "SHALL NOT", mean that the
|
33
|
+
# definition is an absolute prohibition of the specification.
|
15
34
|
#
|
16
35
|
# @api public
|
17
36
|
#
|
18
|
-
# @
|
19
|
-
|
20
|
-
|
37
|
+
# @example _Absolute prohibition_ definition
|
38
|
+
# this { 'foo'.length }.MUST_NOT equal: 42 # => true
|
39
|
+
#
|
40
|
+
# @param [Hash] definition
|
41
|
+
#
|
42
|
+
# @return [Boolean] report if the expectation is true or false.
|
43
|
+
def MUST_NOT(definition)
|
44
|
+
RequirementLevel::High.new(definition, true).pass?(&@actual)
|
21
45
|
end
|
22
46
|
|
23
|
-
#
|
47
|
+
# This word, or the adjective "RECOMMENDED", mean that there
|
48
|
+
# may exist valid reasons in particular circumstances to ignore a
|
49
|
+
# particular item, but the full implications must be understood and
|
50
|
+
# carefully weighed before choosing a different course.
|
24
51
|
#
|
25
52
|
# @api public
|
26
53
|
#
|
27
|
-
# @
|
28
|
-
|
29
|
-
|
54
|
+
# @example _Recommended_ definition
|
55
|
+
# this { 'foo'.valid_encoding? }.SHOULD equal: true # => true
|
56
|
+
#
|
57
|
+
# @param [Hash] definition
|
58
|
+
#
|
59
|
+
# @return [Boolean] report if the expectation is true or false.
|
60
|
+
def SHOULD(definition)
|
61
|
+
RequirementLevel::Medium.new(definition).pass?(&@actual)
|
62
|
+
end
|
63
|
+
|
64
|
+
# This phrase, or the phrase "NOT RECOMMENDED" mean that
|
65
|
+
# there may exist valid reasons in particular circumstances when the
|
66
|
+
# particular behavior is acceptable or even useful, but the full
|
67
|
+
# implications should be understood and the case carefully weighed
|
68
|
+
# before implementing any behavior described with this label.
|
69
|
+
#
|
70
|
+
# @api public
|
71
|
+
#
|
72
|
+
# @example _Not recommended_ definition
|
73
|
+
# this { ''.blank? }.SHOULD_NOT raise_exception: NoMethodError # => false
|
74
|
+
#
|
75
|
+
# @param [Hash] definition
|
76
|
+
#
|
77
|
+
# @return [Boolean] report if the expectation is true or false.
|
78
|
+
def SHOULD_NOT(definition)
|
79
|
+
RequirementLevel::Medium.new(definition, true).pass?(&@actual)
|
80
|
+
end
|
81
|
+
|
82
|
+
# This word, or the adjective "OPTIONAL", mean that an item is
|
83
|
+
# truly optional. One vendor may choose to include the item because a
|
84
|
+
# particular marketplace requires it or because the vendor feels that
|
85
|
+
# it enhances the product while another vendor may omit the same item.
|
86
|
+
# An implementation which does not include a particular option MUST be
|
87
|
+
# prepared to interoperate with another implementation which does
|
88
|
+
# include the option, though perhaps with reduced functionality. In the
|
89
|
+
# same vein an implementation which does include a particular option
|
90
|
+
# MUST be prepared to interoperate with another implementation which
|
91
|
+
# does not include the option (except, of course, for the feature the
|
92
|
+
# option provides.)
|
93
|
+
#
|
94
|
+
# @api public
|
95
|
+
#
|
96
|
+
# @example _Optional_ definition
|
97
|
+
# this { 'foo'.bar }.MAY match: /^foo$/ # => true
|
98
|
+
#
|
99
|
+
# @param [Hash] definition
|
100
|
+
#
|
101
|
+
# @return [Boolean] report if the expectation is true or false.
|
102
|
+
def MAY(definition)
|
103
|
+
RequirementLevel::Low.new(definition).pass?(&@actual)
|
30
104
|
end
|
31
105
|
end
|
32
106
|
end
|