spectus 3.3.3 → 3.3.4

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: 99e857c2dbe2b02d961770b40bd9119fa115665105c99f0a6eb813266e9b72be
4
- data.tar.gz: 6f54bf36215f3f662257cffd68e420051f83f6de13d15d9dca60ffb7e89b9c0f
3
+ metadata.gz: 8767313f403c0f015d1316eabbf06f124ef4ecb136f8edf3529d533602622a8c
4
+ data.tar.gz: 419a5c0e93edac33135d305e9e384fea7d6ca305d68f9bd268f89d4ead020d3c
5
5
  SHA512:
6
- metadata.gz: 5d6b1e7a99bc5d6b52760a8f5fa37f58d485bda7fbf08d9790f78944375d46807366cc9c0232f5f0bb25940b668f89b8a153b78940204ee8e0c54cdc371dacd4
7
- data.tar.gz: 658aaa685fe75ea3fd06c92b0ddca3066efb841cf3c0aa4b252f7d2a9f797ea9f44791ff441bc72bfc76f95fd3f3c532a8b4a1b74e40ea832f6c72ffcbff9b3d
6
+ metadata.gz: 368fb8f488627e6c5b225bd66416ce4a3c8f61aaab0ce0a68ec6d2f354978393299399ccc4f9ea2c8e719b336764b9b7cededa4f6f237a7e5ad9a1495deb47ef
7
+ data.tar.gz: a5e56d1e3c6058f6df75bea0b5d564b0eb2cb6eea620ac9d445bea29a0a45e17302cdddf7cb9b5f7d18609c0b1334527f2495eef264bfb5d9041da453ec1055e
data/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Spectus
2
2
 
3
- [![Build Status](https://api.travis-ci.org/fixrb/spectus.svg?branch=main)][travis]
4
- [![Gem Version](https://badge.fury.io/rb/spectus.svg)][gem]
5
- [![Inline docs](https://inch-ci.org/github/fixrb/spectus.svg?branch=main)][inchpages]
6
- [![Documentation](https://img.shields.io/:yard-docs-38c800.svg)][rubydoc]
3
+ [![Build Status](https://api.travis-ci.org/fixrb/spectus.svg?branch=main)](https://travis-ci.org/fixrb/spectus)
4
+ [![Gem Version](https://badge.fury.io/rb/spectus.svg)](https://rubygems.org/gems/spectus)
5
+ [![Documentation](https://img.shields.io/:yard-docs-38c800.svg)](https://rubydoc.info/gems/spectus/frames)
7
6
 
8
- > Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)'s requirement levels 🚥
7
+ > Expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) requirement levels 🚥
9
8
 
10
9
  ## Installation
11
10
 
@@ -27,19 +26,102 @@ Or install it yourself as:
27
26
  gem install spectus
28
27
  ```
29
28
 
29
+ ## Overview
30
+
31
+ Assuming that an expectation is an assertion that is either `true` or `false`,
32
+ qualifying it with `MUST`, `SHOULD` and `MAY`, we can draw up several scenarios:
33
+
34
+ | Requirement levels | **MUST** | **SHOULD** | **MAY** |
35
+ | ------------------------- | -------- | ---------- | ------- |
36
+ | Implemented & Matched | `true` | `true` | `true` |
37
+ | Implemented & Not matched | `false` | `true` | `false` |
38
+ | Implemented & Exception | `false` | `false` | `false` |
39
+ | Not implemented | `false` | `false` | `true` |
40
+
41
+ When an expectation is evaluated by Spectus,
42
+
43
+ * in case of a _passed_ expectation, a `Spectus::Result::Pass` instance is _returned_;
44
+ * in case of a _failed_ expectation, a `Spectus::Result::Fail` exception is _raised_.
45
+
30
46
  ## Usage
31
47
 
32
- To begin with, let's include __Spectus__:
48
+ The __Spectus__ library is basically a module containing an `it` instance method that accept a block representing the actual value to be evaluated through an expectation.
49
+
50
+ The `Spectus` module can be included inside a class and used as follows:
33
51
 
34
52
  ```ruby
35
- include Spectus
53
+ require "spectus"
54
+
55
+ class Spec
56
+ include ::Spectus
57
+
58
+ attr_reader :subject
59
+
60
+ def initialize(subject)
61
+ @subject = subject
62
+ end
63
+
64
+ def test_a
65
+ it { subject.upcase }.MUST eql "FOO"
66
+ end
67
+
68
+ def test_b
69
+ it { subject.blank? }.MAY be_true
70
+ end
71
+
72
+ def test_c
73
+ it { subject.length }.SHOULD equal 42
74
+ end
75
+ end
36
76
  ```
37
77
 
78
+ ```ruby
79
+ t = Spec.new("foo")
80
+
81
+ t.test_a # => Spectus::Result::Pass(actual: "FOO", error: nil, expected: "FOO", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
82
+
83
+ t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for "foo":String>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY, valid: false)
84
+
85
+ t.test_c # => Spectus::Result::Pass(actual: 3, error: nil, expected: 42, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
86
+ ```
87
+
88
+ ```ruby
89
+ t = Spec.new(4)
90
+
91
+ t.test_a # => raises an exception:
92
+ # Traceback (most recent call last):
93
+ # 6: from ./bin/console:8:in `<main>'
94
+ # 5: from (irb):23
95
+ # 4: from (irb):11:in `test_a'
96
+ # 3: from /Users/cyril/github/fixrb/spectus/lib/spectus/expectation_target.rb:34:in `MUST'
97
+ # 2: from /Users/cyril/github/fixrb/spectus/lib/spectus/requirement_level/base.rb:38:in `call'
98
+ # 1: from /Users/cyril/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/expresenter-1.2.1/lib/expresenter/fail.rb:19:in `with'
99
+ # Spectus::Result::Fail (NoMethodError: undefined method `upcase' for 4:Integer)
100
+
101
+ t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for 4:Integer>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY, valid: false)
102
+
103
+ t.test_c # => raises an exception:
104
+ # Traceback (most recent call last):
105
+ # 6: from ./bin/console:8:in `<main>'
106
+ # 5: from (irb):25
107
+ # 4: from (irb):19:in `test_c'
108
+ # 3: from /Users/cyril/github/fixrb/spectus/lib/spectus/expectation_target.rb:100:in `SHOULD'
109
+ # 2: from /Users/cyril/github/fixrb/spectus/lib/spectus/requirement_level/base.rb:38:in `call'
110
+ # 1: from /Users/cyril/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/expresenter-1.2.1/lib/expresenter/fail.rb:19:in `with'
111
+ # Spectus::Result::Fail (NoMethodError: undefined method `length' for 4:Integer.)
112
+ ```
113
+
114
+ ## More examples
115
+
38
116
  ### Absolute Requirement
39
117
 
40
118
  Given the "`ルビー`" object, when it receives `valid_encoding?` method, then it **MUST** be `true`:
41
119
 
42
120
  ```ruby
121
+ require "spectus"
122
+
123
+ include Spectus
124
+
43
125
  it { "ルビー".valid_encoding? }.MUST be_true
44
126
  # => Spectus::Result::Pass(actual: true, error: nil, expected: nil, got: true, matcher: :be_true, negate: false, level: :MUST, valid: true)
45
127
  ```
@@ -51,6 +133,10 @@ The result of the test shows that the spec passed.
51
133
  Given the "`foo`" object, when it receives `length` method, then it **MUST NOT** raise the `NoMethodError` exception:
52
134
 
53
135
  ```ruby
136
+ require "spectus"
137
+
138
+ include Spectus
139
+
54
140
  it { "foo".length }.MUST_NOT raise_exception NoMethodError
55
141
  # => Spectus::Result::Pass(actual: 3, error: nil, expected: NoMethodError, got: true, matcher: :raise_exception, negate: true, level: :MUST, valid: true)
56
142
  ```
@@ -62,6 +148,10 @@ The result of the test shows that the spec passed.
62
148
  Given the `BasicObject` object, when it receives `superclass` method, then it **SHOULD** return the explicit blank class `NilClass`:
63
149
 
64
150
  ```ruby
151
+ require "spectus"
152
+
153
+ include Spectus
154
+
65
155
  it { BasicObject.superclass }.SHOULD equal NilClass
66
156
  # => Spectus::Result::Pass(actual: nil, error: nil, expected: NilClass, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
67
157
  ```
@@ -74,6 +164,10 @@ However, because there isn't any exception, the result of the test shows that th
74
164
  Given the "`1`" object, when it receives `+(1)` method, then it **SHOULD NOT** return the "`11`" value:
75
165
 
76
166
  ```ruby
167
+ require "spectus"
168
+
169
+ include Spectus
170
+
77
171
  it { "1" + 1 }.SHOULD_NOT eql "11"
78
172
  # 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)
79
173
  ```
@@ -85,17 +179,16 @@ There was a `TypeError` exception, the result of the test shows that the spec fa
85
179
  Given the "`foo`" object, when it receives `blank?` method, then it **MAY** be `false`:
86
180
 
87
181
  ```ruby
182
+ require "spectus"
183
+
184
+ include Spectus
185
+
88
186
  it { "foo".blank? }.MAY be_false
89
187
  # => 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)
90
188
  ```
91
189
 
92
190
  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.
93
191
 
94
- ### More Examples
95
-
96
- A full list of unit tests can be viewed (and executed) here:
97
- [./test.rb](https://github.com/fixrb/spectus/blob/main/test.rb)
98
-
99
192
  ## Code Isolation
100
193
 
101
194
  When executing expectations, side-effects may occur.
@@ -107,7 +200,10 @@ Because they may or may not be desired, each requirement level has 2 versions:
107
200
  Example of test without isolation:
108
201
 
109
202
  ```ruby
203
+ require "spectus"
204
+
110
205
  include Spectus
206
+
111
207
  greeting = "Hello, world!"
112
208
  it { greeting.gsub!("world", "Alice") }.MUST eql "Hello, Alice!"
113
209
  # => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
@@ -117,7 +213,10 @@ greeting # => "Hello, Alice!"
117
213
  Example of test in isolation:
118
214
 
119
215
  ```ruby
216
+ require "spectus"
217
+
120
218
  include Spectus
219
+
121
220
  greeting = "Hello, world!"
122
221
  it { greeting.gsub!("world", "Alice") }.MUST! eql "Hello, Alice!"
123
222
  # => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
@@ -145,8 +244,3 @@ The [gem](https://rubygems.org/gems/spectus) is available as open source under t
145
244
  src="https://github.com/fixrb/spectus/raw/main/img/sashite.png"
146
245
  alt="Sashite" /></a>
147
246
  </p>
148
-
149
- [gem]: https://rubygems.org/gems/spectus
150
- [travis]: https://travis-ci.org/fixrb/spectus
151
- [inchpages]: https://inch-ci.org/github/fixrb/spectus
152
- [rubydoc]: https://rubydoc.info/gems/spectus/frames
data/lib/spectus.rb CHANGED
@@ -2,11 +2,101 @@
2
2
 
3
3
  require "matchi/helper"
4
4
 
5
+ require_relative File.join("spectus", "expectation_target")
6
+
5
7
  # Namespace for the Spectus library.
6
8
  #
7
- # @example It MUST equal 42.
9
+ # This module defines the {#it} method to create expectations, which can be
10
+ # automatically included into classes.
11
+ #
12
+ # @example
13
+ # class Spec
14
+ # include ::Spectus
15
+ #
16
+ # attr_reader :subject
17
+ #
18
+ # def initialize(subject)
19
+ # @subject = subject
20
+ # end
21
+ #
22
+ # def test_a
23
+ # it { subject.upcase }.MUST eql "FOO"
24
+ # end
25
+ #
26
+ # def test_b
27
+ # it { subject.blank? }.MAY be_true
28
+ # end
29
+ #
30
+ # def test_c
31
+ # it { subject.length }.SHOULD equal 42
32
+ # end
33
+ # end
34
+ #
35
+ # t = Spec.new("foo")
36
+ # t.test_a # => Spectus::Result::Pass(actual: "FOO", error: nil, expected: "FOO", got: true, matcher: :eql, negate: false, level: :MUST, valid: true)
37
+ # t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for "foo":String>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY, valid: false)
38
+ # t.test_c # => Spectus::Result::Pass(actual: 3, error: nil, expected: 42, got: false, matcher: :equal, negate: false, level: :SHOULD, valid: false)
39
+ #
40
+ # Or even directly used like this.
41
+ #
42
+ # @example
8
43
  # require 'spectus'
44
+ #
45
+ # include Spectus
46
+ #
9
47
  # it { 42 }.MUST equal 42 # => #<Spectus::Result::Pass...>
48
+ #
49
+ # It also includes a collection of expectation matchers 🤹
50
+ #
51
+ # @example Equivalence matcher
52
+ # matcher = eql("foo") # => Matchi::Matcher::Eql.new("foo")
53
+ # matcher.matches? { "foo" } # => true
54
+ # matcher.matches? { "bar" } # => false
55
+ #
56
+ # @example Identity matcher
57
+ # object = "foo"
58
+ #
59
+ # matcher = equal(object) # => Matchi::Matcher::Equal.new(object)
60
+ # matcher.matches? { object } # => true
61
+ # matcher.matches? { "foo" } # => false
62
+ #
63
+ # @example Regular expressions matcher
64
+ # matcher = match(/^foo$/) # => Matchi::Matcher::Match.new(/^foo$/)
65
+ # matcher.matches? { "foo" } # => true
66
+ # matcher.matches? { "bar" } # => false
67
+ #
68
+ # @example Expecting errors matcher
69
+ # matcher = raise_exception(NameError) # => Matchi::Matcher::RaiseException.new(NameError)
70
+ # matcher.matches? { Boom } # => true
71
+ # matcher.matches? { true } # => false
72
+ #
73
+ # @example Truth matcher
74
+ # matcher = be_true # => Matchi::Matcher::BeTrue.new
75
+ # matcher.matches? { true } # => true
76
+ # matcher.matches? { false } # => false
77
+ # matcher.matches? { nil } # => false
78
+ # matcher.matches? { 4 } # => false
79
+ #
80
+ # @example Untruth matcher
81
+ # matcher = be_false # => Matchi::Matcher::BeFalse.new
82
+ # matcher.matches? { false } # => true
83
+ # matcher.matches? { true } # => false
84
+ # matcher.matches? { nil } # => false
85
+ # matcher.matches? { 4 } # => false
86
+ #
87
+ # @example Nil matcher
88
+ # matcher = be_nil # => Matchi::Matcher::BeNil.new
89
+ # matcher.matches? { nil } # => true
90
+ # matcher.matches? { false } # => false
91
+ # matcher.matches? { true } # => false
92
+ # matcher.matches? { 4 } # => false
93
+ #
94
+ # @example Type/class matcher
95
+ # matcher = be_an_instance_of(String) # => Matchi::Matcher::BeAnInstanceOf.new(String)
96
+ # matcher.matches? { "foo" } # => true
97
+ # matcher.matches? { 4 } # => false
98
+ #
99
+ # @see https://github.com/fixrb/matchi
10
100
  module Spectus
11
101
  include ::Matchi::Helper
12
102
 
@@ -22,5 +112,3 @@ module Spectus
22
112
  ExpectationTarget.new(&input)
23
113
  end
24
114
  end
25
-
26
- require_relative File.join("spectus", "expectation_target")
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative File.join("requirement_level", "must")
4
+ require_relative File.join("requirement_level", "should")
5
+ require_relative File.join("requirement_level", "may")
6
+
3
7
  module Spectus
4
8
  # Wraps the target of an expectation.
5
9
  #
@@ -196,7 +200,3 @@ module Spectus
196
200
  attr_reader :callable
197
201
  end
198
202
  end
199
-
200
- require_relative File.join("requirement_level", "must")
201
- require_relative File.join("requirement_level", "should")
202
- require_relative File.join("requirement_level", "may")
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative File.join("..", "exam")
4
+ require_relative File.join("..", "result")
5
+
3
6
  module Spectus
4
7
  # Namespace for the requirement levels.
5
8
  module RequirementLevel
@@ -32,8 +35,8 @@ module Spectus
32
35
 
33
36
  # The result of the expectation.
34
37
  #
35
- # @raise [Spectus::Result::Fail] The expectation is `false`.
36
- # @return [Spectus::Result::Pass] The expectation is `true`.
38
+ # @raise [Spectus::Result::Fail] The expectation failed.
39
+ # @return [Spectus::Result::Pass] The expectation passed.
37
40
  def call
38
41
  Result.call(pass?).with(
39
42
  actual: exam.actual,
@@ -64,6 +67,3 @@ module Spectus
64
67
  end
65
68
  end
66
69
  end
67
-
68
- require_relative File.join("..", "exam")
69
- require_relative File.join("..", "result")
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative File.join("result", "fail")
4
+ require_relative File.join("result", "pass")
5
+
3
6
  module Spectus
4
7
  # Namespace for the results.
5
8
  module Result
@@ -13,6 +16,3 @@ module Spectus
13
16
  end
14
17
  end
15
18
  end
16
-
17
- require_relative File.join("result", "fail")
18
- require_relative File.join("result", "pass")
@@ -5,6 +5,8 @@ require "expresenter/fail"
5
5
  module Spectus
6
6
  module Result
7
7
  # The class that is responsible for reporting that the expectation is false.
8
+ #
9
+ # @see https://github.com/fixrb/expresenter/blob/v1.2.1/lib/expresenter/fail.rb
8
10
  class Fail < ::Expresenter::Fail
9
11
  end
10
12
  end
@@ -5,6 +5,8 @@ require "expresenter/pass"
5
5
  module Spectus
6
6
  module Result
7
7
  # The class that is responsible for reporting that the expectation is true.
8
+ #
9
+ # @see https://github.com/fixrb/expresenter/blob/v1.2.1/lib/expresenter/pass.rb
8
10
  class Pass < ::Expresenter::Pass
9
11
  end
10
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectus
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.3
4
+ version: 3.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-10 00:00:00.000000000 Z
11
+ date: 2021-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: defi
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.0.2
47
+ version: 2.1.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.0.2
54
+ version: 2.1.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: brutal
57
57
  requirement: !ruby/object:Gem::Requirement