r_spec-clone 1.2.2 → 1.4.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: 7ca7e0d020bebba8aec767197a6c765fa4c0ded5bb96fb58723e5de8321ba1bf
4
- data.tar.gz: 3e9fd96ec29c5341bb5b8f8a3fb60c9672a816e3dd22e1d80d7593ef78689f74
3
+ metadata.gz: c388fa8f14bc48ea1cd253f46695e15a1f7e96192cc04143d6bc5d363dfa0669
4
+ data.tar.gz: fae27e21e625015f5e3dfaf9ae4f1fc2454632a13f8ed100e8519b080eb61b9d
5
5
  SHA512:
6
- metadata.gz: 7ae195dc7673cdd06068d376763ca3b67904eb1bea7ec502cdaf74424ffacb2d44c685988e7c22db21e7be2295a9d3de3b93d587e1c0d8696739dfdb8f37216d
7
- data.tar.gz: 2b3522c31de373f4b9dc3a5d88a9a8e2ec7443d11205d6f93eae91f43a136bead79774333d3d8bac04b96cd07f89eb8c9792c379af0eb380b644da0931d639b4
6
+ metadata.gz: 694679d560726f4f0a23c5ee2c5fbbe8fa75744fe8fc480ba907dad64e92036967cfe6ce129a64cb93292025256ba9427cf3723ad7a893dccd430749fd6c0ada
7
+ data.tar.gz: 0aa55bcf1f8aee5ab72adf4cbaef3fa2a6a9228cbf8b7afbf38f80caca54f84285af99d6aeb8dc6e39629cba090c35657988e1c44f3c2c788dabfc444249e0f2
data/README.md CHANGED
@@ -117,6 +117,8 @@ end
117
117
  # Success: expected to eq "foo".
118
118
  ```
119
119
 
120
+ Note: if you are wondering what the Ruby code generated by using the DSL might look like, an article presents the correspondence between each method via simple examples, available in [English](https://dev.to/cyri_/what-ruby-code-to-expect-from-a-testing-dsl-4oe1), [Chinese](https://ruby-china.org/topics/41441) and [Japanese](https://qiita.com/cyril/items/17ee758e162bae144a07).
121
+
120
122
  ### Expectations
121
123
 
122
124
  Expectations define if the value being tested (_actual_) matches a certain value or specific criteria.
@@ -135,6 +137,12 @@ expect(actual).to equal(expected) # passes if expected.equal?(actual)
135
137
  expect(actual).to be(expected) # passes if expected.equal?(actual)
136
138
  ```
137
139
 
140
+ #### Comparisons
141
+
142
+ ```ruby
143
+ expect(actual).to be_within(delta).of(expected) # passes if (expected - actual).abs <= delta
144
+ ```
145
+
138
146
  #### Regular expressions
139
147
 
140
148
  ```ruby
@@ -147,13 +155,13 @@ expect(actual).to match(expected) # passes if expected.match?(actual)
147
155
  expect { actual }.to raise_exception(expected) # passes if expected exception is raised
148
156
  ```
149
157
 
150
- #### Truth
158
+ #### True
151
159
 
152
160
  ```ruby
153
161
  expect(actual).to be_true # passes if true.equal?(actual)
154
162
  ```
155
163
 
156
- #### Untruth
164
+ #### False
157
165
 
158
166
  ```ruby
159
167
  expect(actual).to be_false # passes if false.equal?(actual)
@@ -172,6 +180,21 @@ expect(actual).to be_instance_of(expected) # passes if expected.equal?(actual
172
180
  expect(actual).to be_an_instance_of(expected) # passes if expected.equal?(actual.class)
173
181
  ```
174
182
 
183
+ #### Change
184
+
185
+ ```ruby
186
+ expect { object.action }.to change(object, :value).from(old).to(new)
187
+ expect { object.action }.to change(object, :value).by(delta)
188
+ expect { object.action }.to change(object, :value).by_at_least(minimum_delta)
189
+ expect { object.action }.to change(object, :value).by_at_most(maximum_delta)
190
+ ```
191
+
192
+ #### Satisfy
193
+
194
+ ```ruby
195
+ expect(actual).to(satisfy { |value| value == expected })
196
+ ```
197
+
175
198
  ### Running specs
176
199
 
177
200
  By convention, specs live in the `spec/` directory of a project. Spec files should end with `_spec.rb` to be recognizable as such.
@@ -232,17 +255,23 @@ bundle exec rake
232
255
 
233
256
  ## Performance
234
257
 
258
+ The benchmarks compare the performance of [`r_spec-clone`](https://rubygems.org/gems/r_spec-clone) with the following frameworks (in alphabetical order):
259
+
260
+ * [`fix`](https://rubygems.org/gems/fix)
261
+ * [`minitest`](https://rubygems.org/gems/minitest)
262
+ * [`rspec`](https://rubygems.org/gems/rspec)
263
+
235
264
  ### Boot time
236
265
 
237
266
  Benchmark against [100 executions of a file containing 1 expectation](https://github.com/cyril/r_spec-clone.rb/blob/main/benchmark/boot_time/) (lower is better).
238
267
 
239
- ![Boot time](https://r-spec.dev/benchmark-boot-time.svg)
268
+ ![Boot time benchmark](https://r-spec.dev/benchmark-boot-time.svg)
240
269
 
241
- ### Run time
270
+ ### Runtime
242
271
 
243
272
  Benchmark against [1 execution of a file containing 1,000,000 expectations](https://github.com/cyril/r_spec-clone.rb/blob/main/benchmark/run_time/) (lower is better).
244
273
 
245
- ![Run time](https://r-spec.dev/benchmark-run-time.svg)
274
+ ![Runtime benchmark](https://r-spec.dev/benchmark-run-time.svg)
246
275
 
247
276
  ## Test suite
248
277
 
data/lib/r_spec.rb CHANGED
@@ -37,8 +37,8 @@ require_relative File.join("r_spec", "clone", "dsl")
37
37
  #
38
38
  # # Output to the console
39
39
  # # Success: expected to eq 3.
40
- # # Success: expected true to be true.
41
- # # Success: expected false to be false.
40
+ # # Success: expected to be true.
41
+ # # Success: expected to be false.
42
42
  #
43
43
  # @example An inherited definition of let
44
44
  # require "r_spec"
@@ -12,13 +12,13 @@ module RSpec
12
12
  # @return [nil] Write a pending expectation to STDOUT.
13
13
  def self.result(message)
14
14
  ::Expresenter.call(true).with(
15
- actual: new(message),
16
- error: nil,
17
- expected: self,
18
- got: false,
19
- matcher: :raise_exception,
20
- negate: true,
21
- level: :SHOULD
15
+ actual: new(message),
16
+ definition: "raise exception #{self}",
17
+ error: nil,
18
+ expected: self,
19
+ got: false,
20
+ negate: true,
21
+ level: :SHOULD
22
22
  )
23
23
  end
24
24
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "matchi/rspec"
3
+ require "matchi"
4
4
 
5
5
  module RSpec
6
6
  module Clone
@@ -10,72 +10,208 @@ module RSpec
10
10
  # This module defines a number of methods to create expectations, which
11
11
  # are automatically included into examples.
12
12
  #
13
- # It also includes a collection of expectation matchers 🤹
14
- #
15
- # @example Equivalence matcher
16
- # matcher = eql("foo") # => Matchi::Matcher::Eql.new("foo")
17
- # matcher.matches? { "foo" } # => true
18
- # matcher.matches? { "bar" } # => false
19
- #
20
- # matcher = eq("foo") # => Matchi::Matcher::Eq.new("foo")
21
- # matcher.matches? { "foo" } # => true
22
- # matcher.matches? { "bar" } # => false
23
- #
24
- # @example Identity matcher
25
- # object = "foo"
26
- #
27
- # matcher = equal(object) # => Matchi::Matcher::Equal.new(object)
28
- # matcher.matches? { object } # => true
29
- # matcher.matches? { "foo" } # => false
30
- #
31
- # matcher = be(object) # => Matchi::Matcher::Be.new(object)
32
- # matcher.matches? { object } # => true
33
- # matcher.matches? { "foo" } # => false
34
- #
35
- # @example Regular expressions matcher
36
- # matcher = match(/^foo$/) # => Matchi::Matcher::Match.new(/^foo$/)
37
- # matcher.matches? { "foo" } # => true
38
- # matcher.matches? { "bar" } # => false
39
- #
40
- # @example Expecting errors matcher
41
- # matcher = raise_exception(NameError) # => Matchi::Matcher::RaiseException.new(NameError)
42
- # matcher.matches? { Boom } # => true
43
- # matcher.matches? { true } # => false
44
- #
45
- # @example Truth matcher
46
- # matcher = be_true # => Matchi::Matcher::BeTrue.new
47
- # matcher.matches? { true } # => true
48
- # matcher.matches? { false } # => false
49
- # matcher.matches? { nil } # => false
50
- # matcher.matches? { 4 } # => false
51
- #
52
- # @example Untruth matcher
53
- # matcher = be_false # => Matchi::Matcher::BeFalse.new
54
- # matcher.matches? { false } # => true
55
- # matcher.matches? { true } # => false
56
- # matcher.matches? { nil } # => false
57
- # matcher.matches? { 4 } # => false
58
- #
59
- # @example Nil matcher
60
- # matcher = be_nil # => Matchi::Matcher::BeNil.new
61
- # matcher.matches? { nil } # => true
62
- # matcher.matches? { false } # => false
63
- # matcher.matches? { true } # => false
64
- # matcher.matches? { 4 } # => false
65
- #
66
- # @example Type/class matcher
67
- # matcher = be_instance_of(String) # => Matchi::Matcher::BeInstanceOf.new(String)
68
- # matcher.matches? { "foo" } # => true
69
- # matcher.matches? { 4 } # => false
70
- #
71
- # matcher = be_an_instance_of(String) # => Matchi::Matcher::BeAnInstanceOf.new(String)
72
- # matcher.matches? { "foo" } # => true
73
- # matcher.matches? { 4 } # => false
13
+ # It also includes a collection of expectation matchers.
74
14
  #
75
15
  # @see https://github.com/fixrb/matchi
76
- # @see https://github.com/fixrb/matchi-rspec
77
16
  module Shared
78
- include ::Matchi::Helper
17
+ # Equivalence matcher
18
+ #
19
+ # @example
20
+ # matcher = eq("foo")
21
+ # matcher.matches? { "foo" } # => true
22
+ # matcher.matches? { "bar" } # => false
23
+ #
24
+ # @param expected [#eql?] An expected equivalent object.
25
+ #
26
+ # @return [#matches?] An equivalence matcher.
27
+ #
28
+ # @api public
29
+ def eq(expected)
30
+ ::Matchi::Eq.new(expected)
31
+ end
32
+
33
+ alias eql eq
34
+
35
+ # Identity matcher
36
+ #
37
+ # @example
38
+ # object = "foo"
39
+ # matcher = be(object)
40
+ # matcher.matches? { object } # => true
41
+ # matcher.matches? { "foo" } # => false
42
+ #
43
+ # @param expected [#equal?] The expected identical object.
44
+ #
45
+ # @return [#matches?] An identity matcher.
46
+ #
47
+ # @api public
48
+ def be(expected)
49
+ ::Matchi::Be.new(expected)
50
+ end
51
+
52
+ alias equal be
53
+
54
+ # Comparisons matcher
55
+ #
56
+ # @example
57
+ # matcher = be_within(1).of(41)
58
+ # matcher.matches? { 42 } # => true
59
+ # matcher.matches? { 43 } # => false
60
+ #
61
+ # @param delta [Numeric] A numeric value.
62
+ #
63
+ # @return [#matches?] A comparison matcher.
64
+ #
65
+ # @api public
66
+ def be_within(delta)
67
+ ::Matchi::BeWithin.new(delta)
68
+ end
69
+
70
+ # Regular expressions matcher
71
+ #
72
+ # @example
73
+ # matcher = match(/^foo$/)
74
+ # matcher.matches? { "foo" } # => true
75
+ # matcher.matches? { "bar" } # => false
76
+ #
77
+ # @param expected [#match] A regular expression.
78
+ #
79
+ # @return [#matches?] A regular expression matcher.
80
+ #
81
+ # @api public
82
+ def match(expected)
83
+ ::Matchi::Match.new(expected)
84
+ end
85
+
86
+ # Expecting errors matcher
87
+ #
88
+ # @example
89
+ # matcher = raise_exception(NameError)
90
+ # matcher.matches? { Boom } # => true
91
+ # matcher.matches? { true } # => false
92
+ #
93
+ # @param expected [Exception, #to_s] The expected exception name.
94
+ #
95
+ # @return [#matches?] An error matcher.
96
+ #
97
+ # @api public
98
+ def raise_exception(expected)
99
+ ::Matchi::RaiseException.new(expected)
100
+ end
101
+
102
+ # True matcher
103
+ #
104
+ # @example
105
+ # matcher = be_true
106
+ # matcher.matches? { true } # => true
107
+ # matcher.matches? { false } # => false
108
+ # matcher.matches? { nil } # => false
109
+ # matcher.matches? { 4 } # => false
110
+ #
111
+ # @return [#matches?] A `true` matcher.
112
+ #
113
+ # @api public
114
+ def be_true
115
+ be(true)
116
+ end
117
+
118
+ # False matcher
119
+ #
120
+ # @example
121
+ # matcher = be_false
122
+ # matcher.matches? { false } # => true
123
+ # matcher.matches? { true } # => false
124
+ # matcher.matches? { nil } # => false
125
+ # matcher.matches? { 4 } # => false
126
+ #
127
+ # @return [#matches?] A `false` matcher.
128
+ #
129
+ # @api public
130
+ def be_false
131
+ be(false)
132
+ end
133
+
134
+ # Nil matcher
135
+ #
136
+ # @example
137
+ # matcher = be_nil
138
+ # matcher.matches? { nil } # => true
139
+ # matcher.matches? { false } # => false
140
+ # matcher.matches? { true } # => false
141
+ # matcher.matches? { 4 } # => false
142
+ #
143
+ # @return [#matches?] A `nil` matcher.
144
+ #
145
+ # @api public
146
+ def be_nil
147
+ be(nil)
148
+ end
149
+
150
+ # Type/class matcher
151
+ #
152
+ # @example
153
+ # matcher = be_an_instance_of(String)
154
+ # matcher.matches? { "foo" } # => true
155
+ # matcher.matches? { 4 } # => false
156
+ #
157
+ # @param expected [Class, #to_s] The expected class name.
158
+ #
159
+ # @return [#matches?] A type/class matcher.
160
+ #
161
+ # @api public
162
+ def be_an_instance_of(expected)
163
+ ::Matchi::BeAnInstanceOf.new(expected)
164
+ end
165
+
166
+ # Change matcher
167
+ #
168
+ # @example
169
+ # object = []
170
+ # matcher = change(object, :length).by(1)
171
+ # matcher.matches? { object << 1 } # => true
172
+ #
173
+ # object = []
174
+ # matcher = change(object, :length).by_at_least(1)
175
+ # matcher.matches? { object << 1 } # => true
176
+ #
177
+ # object = []
178
+ # matcher = change(object, :length).by_at_most(1)
179
+ # matcher.matches? { object << 1 } # => true
180
+ #
181
+ # object = "foo"
182
+ # matcher = change(object, :to_s).from("foo").to("FOO")
183
+ # matcher.matches? { object.upcase! } # => true
184
+ #
185
+ # object = "foo"
186
+ # matcher = change(object, :to_s).to("FOO")
187
+ # matcher.matches? { object.upcase! } # => true
188
+ #
189
+ # @param object [#object_id] An object.
190
+ # @param method [Symbol] The name of a method.
191
+ # @param args [Array] A list of arguments.
192
+ # @param kwargs [Hash] A list of keyword arguments.
193
+ #
194
+ # @return [#matches?] A change matcher.
195
+ #
196
+ # @api public
197
+ def change(object, method, *args, **kwargs, &block)
198
+ ::Matchi::Change.new(object, method, *args, **kwargs, &block)
199
+ end
200
+
201
+ # Satisfy matcher
202
+ #
203
+ # @example
204
+ # matcher = satisfy { |value| value == 42 }
205
+ # matcher.matches? { 42 } # => true
206
+ #
207
+ # @param expected [Proc] A block of code.
208
+ #
209
+ # @return [#matches?] A satisfy matcher.
210
+ #
211
+ # @api public
212
+ def satisfy(&expected)
213
+ ::Matchi::Satisfy.new(&expected)
214
+ end
79
215
  end
80
216
  end
81
217
  end
@@ -95,13 +95,13 @@ module RSpec
95
95
  # `Kernel.exit(false)` with a failure message written to STDERR.
96
96
  def result(passed, actual:, error:, got:, matcher:, negate:)
97
97
  Console.passed_spec ::Expresenter.call(passed).with(
98
- actual: actual,
99
- error: error,
100
- expected: matcher.expected,
101
- got: got,
102
- negate: negate,
103
- matcher: matcher.class.to_sym,
104
- level: :MUST
98
+ actual: actual,
99
+ definition: matcher.to_s,
100
+ error: error,
101
+ expected: matcher.expected,
102
+ got: got,
103
+ negate: negate,
104
+ level: :MUST
105
105
  )
106
106
  rescue ::Expresenter::Fail => e
107
107
  Console.failed_spec(e)
@@ -29,7 +29,7 @@ module RSpec
29
29
  # @raise (see Base#absolute_requirement)
30
30
  def absolute_requirement(matcher:, negate:)
31
31
  super(
32
- ::TestTube.invoke(isolation: false, matcher: matcher, negate: negate, &@input),
32
+ ::TestTube.invoke(isolate: false, matcher: matcher, negate: negate, &@input),
33
33
  matcher: matcher,
34
34
  negate: negate
35
35
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r_spec-clone
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.4.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: 2021-07-12 00:00:00.000000000 Z
11
+ date: 2021-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: expresenter
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3.0
19
+ version: 1.4.0
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: 1.3.0
26
+ version: 1.4.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: matchi-rspec
28
+ name: matchi
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.1.2
33
+ version: 3.2.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.1.2
40
+ version: 3.2.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: test_tube
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.0.0
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.0
54
+ version: 2.1.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement