rspec-benchmark 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -3
- data/README.md +48 -4
- data/Rakefile +1 -1
- data/lib/rspec/benchmark/comparison_matcher.rb +237 -0
- data/lib/rspec/benchmark/iteration_matcher.rb +5 -3
- data/lib/rspec/benchmark/matchers.rb +29 -2
- data/lib/rspec/benchmark/timing_matcher.rb +4 -3
- data/lib/rspec/benchmark/version.rb +1 -1
- data/spec/unit/comparison_matcher_spec.rb +183 -0
- data/spec/unit/perform_at_least_spec.rb +11 -0
- data/spec/unit/perform_under_spec.rb +8 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e2f1ed591f703a89dbf9a01070a9ba4cf893e82
|
4
|
+
data.tar.gz: f837f60f9864f23ff94e88a0d48adafff16fcd13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63d13b9d25a62d5ad5e3afacb0e538b0d7b5c5bdc0f35488a375401a5e6ad86cc840dddb87b711bdf7f6a303c910d6786271fbe5e56a65ee4cbaa56947c04d56
|
7
|
+
data.tar.gz: df7988107e1e39c7dbfdd2c560ddfba738d9972786671245f5273cd089c50070fabbac8cd2fa9a7f186d0990cd2f18b9a29f681224f27c7bc0ab4ee00024abb9
|
data/.travis.yml
CHANGED
@@ -6,18 +6,19 @@ script: "bundle exec rake ci"
|
|
6
6
|
rvm:
|
7
7
|
- 2.0.0
|
8
8
|
- 2.1.10
|
9
|
-
- 2.2.
|
10
|
-
- 2.3.
|
9
|
+
- 2.2.6
|
10
|
+
- 2.3.3
|
11
|
+
- 2.4.0
|
11
12
|
- ruby-head
|
12
13
|
- jruby-9000
|
13
14
|
- jruby-head
|
14
|
-
- rbx
|
15
|
+
- rbx-3
|
15
16
|
env:
|
16
17
|
global:
|
17
18
|
- JRUBY_OPTS="-Xcli.debug=true --debug"
|
18
19
|
matrix:
|
19
20
|
allow_failures:
|
20
|
-
- rvm: rbx
|
21
|
+
- rvm: rbx-3
|
21
22
|
- rvm: ruby-head
|
22
23
|
- rvm: jruby-head
|
23
24
|
fast_finish: true
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.3.0] - 2017-02-05
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add ComparisonMatcher with #perform_faster_than and #perform_slower_than expectations by Dmitri(@WildDima)
|
7
|
+
* Add ability to configure timing options for all Matchers such as :warmup & :time
|
8
|
+
|
3
9
|
## [v0.2.0] - 2016-11-01
|
4
10
|
|
5
11
|
### Changed
|
@@ -9,5 +15,6 @@
|
|
9
15
|
|
10
16
|
Initial release
|
11
17
|
|
18
|
+
[v0.3.0]: https://github.com/peter-murach/rspec-benchmark/compare/v0.2.0...v0.3.0
|
12
19
|
[v0.2.0]: https://github.com/peter-murach/rspec-benchmark/compare/v0.1.0...v0.2.0
|
13
20
|
[v0.1.0]: https://github.com/peter-murach/rspec-benchmark/compare/v0.1.0
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/rspec-benchmark.svg)][gem]
|
3
3
|
[![Build Status](https://secure.travis-ci.org/piotrmurach/rspec-benchmark.svg?branch=master)][travis]
|
4
4
|
[![Code Climate](https://codeclimate.com/github/piotrmurach/rspec-benchmark/badges/gpa.svg)][codeclimate]
|
5
|
-
[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/rspec-benchmark/badge.svg
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/rspec-benchmark/badge.svg)][coverage]
|
6
6
|
[![Inline docs](http://inch-ci.org/github/piotrmurach/rspec-benchmark.svg?branch=master)][inchpages]
|
7
7
|
|
8
8
|
[gem]: http://badge.fury.io/rb/rspec-benchmark
|
9
9
|
[travis]: http://travis-ci.org/piotrmurach/rspec-benchmark
|
10
10
|
[codeclimate]: https://codeclimate.com/github/piotrmurach/rspec-benchmark
|
11
|
-
[coverage]: https://coveralls.io/github/piotrmurach/rspec-benchmark
|
11
|
+
[coverage]: https://coveralls.io/github/piotrmurach/rspec-benchmark
|
12
12
|
[inchpages]: http://inch-ci.org/github/piotrmurach/rspec-benchmark
|
13
13
|
|
14
14
|
> Performance testing matchers for RSpec
|
@@ -26,6 +26,7 @@ If you are new to performance testing you may find [Caveats](#3-caveats) section
|
|
26
26
|
* [1. Usage](#1-usage)
|
27
27
|
* [1.1 Execution Time](#11-execution-time)
|
28
28
|
* [1.2 Iterations ](#12-iterations)
|
29
|
+
* [1.3 Comparison ](#13-comparison)
|
29
30
|
* [2. Filtering](#2-filtering)
|
30
31
|
* [3. Caveats](#3-caveats)
|
31
32
|
|
@@ -57,7 +58,7 @@ RSpec.configure do |config|
|
|
57
58
|
end
|
58
59
|
```
|
59
60
|
|
60
|
-
This will add the `perform_under` and `
|
61
|
+
This will add the `perform_under`, `perform_at_least`, `perform_faster_than` and `perform_slower_than` matchers to express expected performance benchmark for code executed inside the expectation.
|
61
62
|
|
62
63
|
Alternatively, you can add matchers for particular example:
|
63
64
|
|
@@ -97,6 +98,49 @@ expect { ... }.to perform_at_least(10000).ips
|
|
97
98
|
|
98
99
|
The `ips` part is optional but its usage clarifies the intent.
|
99
100
|
|
101
|
+
The performance timining of this matcher can be tweaked using the `:time` and `:warmup` parameters. These are expressed as seconds. By default `:time` is set to `0.2` and `:warmup` to `0.1` respectively. To change parameters do:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
expect { ... }.to perform_faster_than(time: 0.4, warmup: 0.2) { ... }
|
105
|
+
```
|
106
|
+
|
107
|
+
The higher values for `:time` and `:warmup` the more accurate average readings and hence more stable tests at the cost of longer test suite overall time.
|
108
|
+
|
109
|
+
### 1.3 Comparison
|
110
|
+
|
111
|
+
The `perform_faster_than` and `perform_slower_than` matchers allow you to test performance of your code compared with other. For example:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
expect { ... }.to perform_faster_than { ... }
|
115
|
+
expect { ... }.to perform_slower_than { ... }
|
116
|
+
```
|
117
|
+
|
118
|
+
And if you want to compare how much faster or slower your code is do:
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
expect { ... }.to perform_faster_than { ... }.once
|
122
|
+
expect { ... }.to perform_faster_than { ... }.twice
|
123
|
+
expect { ... }.to perform_faster_than { ... }.exactly(5).times
|
124
|
+
expect { ... }.to perform_faster_than { ... }.at_least(5).times
|
125
|
+
expect { ... }.to perform_faster_than { ... }.at_most(5).times
|
126
|
+
|
127
|
+
expect { ... }.to perform_slower_than { ... }.once
|
128
|
+
expect { ... }.to perform_slower_than { ... }.twice
|
129
|
+
expect { ... }.to perform_slower_than { ... }.at_least(5).times
|
130
|
+
expect { ... }.to perform_slower_than { ... }.at_most(5).times
|
131
|
+
expect { ... }.to perform_slower_than { ... }.exactly(5).times
|
132
|
+
```
|
133
|
+
|
134
|
+
The `times` part is also optional.
|
135
|
+
|
136
|
+
The performance timining of each matcher can be tweaked using the `:time` and `:warmup` parameters. These are expressed as seconds. By default `:time` is set to `0.2` and `:warmup` to `0.1` respectively. To change parameters do:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
expect { ... }.to perform_faster_than(time: 0.4, warmup: 0.2) { ... }
|
140
|
+
```
|
141
|
+
|
142
|
+
The higher values for `:time` and `:warmup` the more accurate average readings and hence more stable tests at the cost of longer test suite overall time.
|
143
|
+
|
100
144
|
## 2 Filtering
|
101
145
|
|
102
146
|
Usually performance tests are best left for CI or occasional runs that do not affect TDD/BDD cycle. To achieve isolation you can use RSpec filters. For instance, in `spec_helper`:
|
@@ -136,4 +180,4 @@ If you have any other observations please share them!
|
|
136
180
|
|
137
181
|
## Copyright
|
138
182
|
|
139
|
-
Copyright (c) 2016 Piotr Murach. See LICENSE for further details.
|
183
|
+
Copyright (c) 2016-2017 Piotr Murach. See LICENSE for further details.
|
data/Rakefile
CHANGED
@@ -0,0 +1,237 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Benchmark
|
5
|
+
module ComparisonMatcher
|
6
|
+
# Implements the `perform_faster_than` and `perform_slower_than` matchers
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Matcher
|
10
|
+
def initialize(expected, comparison_type, **options)
|
11
|
+
check_comparison(comparison_type)
|
12
|
+
@expected = expected
|
13
|
+
@comparison_type = comparison_type
|
14
|
+
@count = 1
|
15
|
+
@count_type = :at_least
|
16
|
+
time = options.fetch(:time) { 0.2 }
|
17
|
+
warmup = options.fetch(:warmup) { 0.1 }
|
18
|
+
@bench = ::Benchmark::Perf::Iteration.new(time: time, warmup: warmup)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Indicates this matcher matches against a block
|
22
|
+
#
|
23
|
+
# @return [True]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
def supports_block_expectations?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def matcher_name
|
31
|
+
"perform_#{@comparison_type}_than"
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Boolean]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
def matches?(block)
|
38
|
+
@actual = block
|
39
|
+
return false unless @actual.is_a?(Proc)
|
40
|
+
|
41
|
+
@expected_ips, @expected_stdev, = @bench.run(&@expected)
|
42
|
+
@actual_ips, @actual_stdev, = @bench.run(&@actual)
|
43
|
+
|
44
|
+
@ratio = @actual_ips / @expected_ips.to_f
|
45
|
+
|
46
|
+
case @count_type
|
47
|
+
when :at_most
|
48
|
+
at_most_comparison
|
49
|
+
when :exactly
|
50
|
+
exact_comparison
|
51
|
+
else
|
52
|
+
default_comparison
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Specify the minimum number of times a block
|
57
|
+
# is faster/slower than other.
|
58
|
+
# @api public
|
59
|
+
def at_least(n)
|
60
|
+
set_expected_times_count(:at_least, n)
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
# Specify the maximum number of times a block
|
65
|
+
# is faster/slower than another.
|
66
|
+
# @api public
|
67
|
+
def at_most(n)
|
68
|
+
set_expected_times_count(:at_most, n)
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
# Specify exact number of times a block
|
73
|
+
# is faster/slower than another.
|
74
|
+
# @api public
|
75
|
+
def exactly(n)
|
76
|
+
set_expected_times_count(:exactly, n)
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
# Specify that the code runs faster/slower exactly once.
|
81
|
+
# @api public
|
82
|
+
def once
|
83
|
+
exactly(1)
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
# Specify that the code runs faster/slower exactly twice.
|
88
|
+
def twice
|
89
|
+
exactly(2)
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
# Specify that the code runs faster/slower exactly thrice.
|
94
|
+
# @api public
|
95
|
+
def thrice
|
96
|
+
exactly(3)
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
# No-op, syntactic sugar.
|
101
|
+
# @api public
|
102
|
+
def times
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
# @api private
|
107
|
+
def failure_message
|
108
|
+
"expected given block to #{description}, but #{failure_reason}"
|
109
|
+
end
|
110
|
+
|
111
|
+
# @api private
|
112
|
+
def failure_message_when_negated
|
113
|
+
"expected given block not to #{description}, but #{failure_reason}"
|
114
|
+
end
|
115
|
+
|
116
|
+
# @api private
|
117
|
+
def description
|
118
|
+
if @count == 1
|
119
|
+
"perform #{@comparison_type} than comparison block"
|
120
|
+
else
|
121
|
+
"perform #{@comparison_type} than comparison block " \
|
122
|
+
"by #{@count_type} #{@count} times"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# @api private
|
127
|
+
def failure_reason
|
128
|
+
return "was not a block" unless @actual.is_a?(Proc)
|
129
|
+
|
130
|
+
if @ratio < 1
|
131
|
+
"performed slower by #{format('%.2f', (@ratio**-1))} times"
|
132
|
+
elsif @ratio > 1
|
133
|
+
"performed faster by #{format('%.2f', @ratio)} times"
|
134
|
+
else
|
135
|
+
"performed by the same time"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def convert_count(n)
|
142
|
+
case n
|
143
|
+
when Numeric then n
|
144
|
+
when :once then 1
|
145
|
+
when :twice then 2
|
146
|
+
when :thrice then 3
|
147
|
+
else
|
148
|
+
raise "The #{matcher_name} matcher is not designed to be used " \
|
149
|
+
"with #{n} count type."
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def set_expected_times_count(type, n)
|
154
|
+
@count_type = type
|
155
|
+
@count = convert_count(n)
|
156
|
+
end
|
157
|
+
|
158
|
+
# @return [Boolean]
|
159
|
+
# @example
|
160
|
+
# @actual = 40
|
161
|
+
# @count = 41
|
162
|
+
# perform_faster_than { ... }.at_most(@count).times # => true
|
163
|
+
#
|
164
|
+
# @actual = 40
|
165
|
+
# @count = 41
|
166
|
+
# perform_faster_than { ... }.at_most(@count).times # => false
|
167
|
+
#
|
168
|
+
# @actual = 1/40
|
169
|
+
# @count = 41
|
170
|
+
# perform_slower_than { ... }.at_most(@count).times # => true
|
171
|
+
#
|
172
|
+
# @actual = 1/40
|
173
|
+
# @count = 41
|
174
|
+
# perform_slower_than { ... }.at_most(@count).times # => false
|
175
|
+
# @api private
|
176
|
+
def at_most_comparison
|
177
|
+
if @comparison_type == :faster
|
178
|
+
1 < @ratio && @ratio < @count
|
179
|
+
else
|
180
|
+
@count**-1 < @ratio && @ratio < 1
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Check if expected ips is faster/slower than actual ips
|
185
|
+
# exactly number of counts.
|
186
|
+
#
|
187
|
+
# @example
|
188
|
+
# @actual = 40.1
|
189
|
+
# @count = 40
|
190
|
+
# perform_faster_than { ... }.exact(@count).times # => true
|
191
|
+
#
|
192
|
+
# @actual = 40.1
|
193
|
+
# @count = 41
|
194
|
+
# perform_faster_than { ... }.exact(@count).times # => true
|
195
|
+
#
|
196
|
+
# @return [Boolean]
|
197
|
+
#
|
198
|
+
# @api private
|
199
|
+
def exact_comparison
|
200
|
+
@count == @ratio.round
|
201
|
+
end
|
202
|
+
|
203
|
+
# @return [Boolean]
|
204
|
+
# @example
|
205
|
+
# @actual = 41
|
206
|
+
# @count = 40
|
207
|
+
# perform_faster_than { ... } # => true
|
208
|
+
#
|
209
|
+
# @actual = 41
|
210
|
+
# @count = 40
|
211
|
+
# perform_faster_than { ... }.at_least(@count).times # => true
|
212
|
+
#
|
213
|
+
# @actual = 1/40
|
214
|
+
# @count = 41
|
215
|
+
# perform_slower_than { ... }.at_least(@count).times # => false
|
216
|
+
#
|
217
|
+
# @actual = 1/41
|
218
|
+
# @count = 40
|
219
|
+
# perform_slower_than { ... }.at_least(@count).times # => true
|
220
|
+
# @api private
|
221
|
+
def default_comparison
|
222
|
+
if @comparison_type == :faster
|
223
|
+
@ratio / @count > 1
|
224
|
+
else
|
225
|
+
@ratio / @count < 1 / @count.to_f
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def check_comparison(type)
|
230
|
+
[:slower, :faster].include?(type) ||
|
231
|
+
(raise ArgumentError, 'comparison_type must be ' \
|
232
|
+
":faster or :slower, not `:#{type}`")
|
233
|
+
end
|
234
|
+
end # Matcher
|
235
|
+
end # ComparisonMatcher
|
236
|
+
end # Benchmark
|
237
|
+
end # RSpec
|
@@ -7,8 +7,11 @@ module RSpec
|
|
7
7
|
#
|
8
8
|
# @api private
|
9
9
|
class Matcher
|
10
|
-
def initialize(iterations, options
|
10
|
+
def initialize(iterations, **options)
|
11
11
|
@iterations = iterations
|
12
|
+
time = options.fetch(:time) { 0.2 }
|
13
|
+
warmup = options.fetch(:warmup) { 0.1 }
|
14
|
+
@bench = ::Benchmark::Perf::Iteration.new(time: time, warmup: warmup)
|
12
15
|
end
|
13
16
|
|
14
17
|
# Indicates this matcher matches against a block
|
@@ -24,8 +27,7 @@ module RSpec
|
|
24
27
|
#
|
25
28
|
# @api private
|
26
29
|
def matches?(block)
|
27
|
-
@
|
28
|
-
@average, @stddev, _ = @bench.run(&block)
|
30
|
+
@average, @stddev, = @bench.run(&block)
|
29
31
|
@iterations <= (@average + 3 * @stddev)
|
30
32
|
end
|
31
33
|
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rspec/benchmark/timing_matcher'
|
4
4
|
require 'rspec/benchmark/iteration_matcher'
|
5
|
+
require 'rspec/benchmark/comparison_matcher'
|
5
6
|
|
6
7
|
module RSpec
|
7
8
|
module Benchmark
|
@@ -31,7 +32,7 @@ module RSpec
|
|
31
32
|
# expect { ... }.to perform_at_least(10000).ips
|
32
33
|
#
|
33
34
|
# @api public
|
34
|
-
def perform_at_least(iterations, options
|
35
|
+
def perform_at_least(iterations, **options)
|
35
36
|
IterationMatcher::Matcher.new(iterations, options)
|
36
37
|
end
|
37
38
|
|
@@ -45,9 +46,35 @@ module RSpec
|
|
45
46
|
# expect { ... }.to peform_under(10).ms
|
46
47
|
#
|
47
48
|
# @api public
|
48
|
-
def perform_under(threshold, options
|
49
|
+
def perform_under(threshold, **options)
|
49
50
|
TimingMatcher::Matcher.new(threshold, options)
|
50
51
|
end
|
52
|
+
|
53
|
+
# Passes if code block performs faster than sample block
|
54
|
+
#
|
55
|
+
# @param [Proc] sample
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# expect { ... }.to peform_faster_than { ... }
|
59
|
+
# expect { ... }.to peform_faster_than { ... }.at_least(5).times
|
60
|
+
#
|
61
|
+
# @api public
|
62
|
+
def perform_faster_than(**options, &sample)
|
63
|
+
ComparisonMatcher::Matcher.new(sample, :faster, options)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Passes if code block performs slower than sample block
|
67
|
+
#
|
68
|
+
# @param [Proc] sample
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# expect { ... }.to peform_slower_than { ... }
|
72
|
+
# expect { ... }.to peform_slower_than { ... }.at_most(5).times
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
def perform_slower_than(**options, &sample)
|
76
|
+
ComparisonMatcher::Matcher.new(sample, :slower, options)
|
77
|
+
end
|
51
78
|
end # Matchers
|
52
79
|
end # Benchmark
|
53
80
|
end # RSpec
|
@@ -11,12 +11,14 @@ module RSpec
|
|
11
11
|
|
12
12
|
attr_reader :threshold
|
13
13
|
|
14
|
-
def initialize(threshold, options
|
14
|
+
def initialize(threshold, **options)
|
15
15
|
@threshold = threshold
|
16
16
|
@samples = options.fetch(:samples) { 30 }
|
17
17
|
@scale = threshold.to_s.split(/\./).last.size
|
18
18
|
@block = nil
|
19
19
|
@confidence_interval = nil
|
20
|
+
warmup = options.fetch(:warmup) { 1 }
|
21
|
+
@bench = ::Benchmark::Perf::ExecutionTime.new(warmup: warmup)
|
20
22
|
end
|
21
23
|
|
22
24
|
# Indicates this matcher matches against a block
|
@@ -34,7 +36,6 @@ module RSpec
|
|
34
36
|
def matches?(block)
|
35
37
|
@block = block
|
36
38
|
return false unless block.is_a?(Proc)
|
37
|
-
@bench = ::Benchmark::Perf::ExecutionTime.new
|
38
39
|
@average, @stddev = @bench.run(@samples, &block)
|
39
40
|
@average <= @threshold
|
40
41
|
end
|
@@ -51,7 +52,7 @@ module RSpec
|
|
51
52
|
def secs
|
52
53
|
self
|
53
54
|
end
|
54
|
-
|
55
|
+
alias sec secs
|
55
56
|
|
56
57
|
# Tell this matcher to convert threshold to ms
|
57
58
|
# @api public
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe RSpec::Benchmark::ComparisonMatcher::Matcher do
|
4
|
+
|
5
|
+
it "validates comparison type" do
|
6
|
+
expect {
|
7
|
+
described_class.new(-> { 1 + 2 }, :unknown)
|
8
|
+
}.to raise_error(ArgumentError, /comparison_type must be :faster or :slower, not `:unknown`/)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "raises expectation error when not given a block" do
|
12
|
+
expect {
|
13
|
+
expect(1 + 1).to perform_faster_than { 'x' * 10 * 1024 }
|
14
|
+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError,
|
15
|
+
"expected given block to perform faster than comparison block, but was not a block")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "allows to configure matcher timings" do
|
19
|
+
bench = double(run: 100)
|
20
|
+
allow(::Benchmark::Perf::Iteration).to receive(:new).and_return(bench)
|
21
|
+
sample = -> { 'x' * 10 * 1024 }
|
22
|
+
expect { 1 << 1 }.to perform_faster_than(warmup: 0.2, time: 0.3, &sample).exactly(1).times
|
23
|
+
|
24
|
+
expect(::Benchmark::Perf::Iteration).to have_received(:new).
|
25
|
+
with(time: 0.3, warmup: 0.2)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "expect { ... }.to perform_faster_than(...)" do
|
29
|
+
it "passes if the block performs faster than sample" do
|
30
|
+
expect { 1 << 1 }.to perform_faster_than { 'x' * 10 * 1024 }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "fails if the block performs slower than sample" do
|
34
|
+
expect {
|
35
|
+
expect { 'x' * 10 * 1024 }.to perform_faster_than { 1 << 1 }
|
36
|
+
}.to raise_error(/expected given block to perform faster than comparison block, but performed slower by \d+.\d+ times/)
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with exact count' do
|
40
|
+
it "passes if the block performs faster than sample" do
|
41
|
+
expect { 1 << 1 }.to perform_faster_than { 1 << 1 }.exactly(1).times
|
42
|
+
end
|
43
|
+
|
44
|
+
it "passes if the block performs specified number of times" do
|
45
|
+
expect { 1 << 1 }.to perform_faster_than { 1 << 1 }.once
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "with at_least count" do
|
50
|
+
it "passes if the block performs faster by count times" do
|
51
|
+
expect { 1 << 1 }.to perform_faster_than { 'x' * 10 * 1024 }.at_least(2)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "fails if the block doesn't perform faster by count times" do
|
55
|
+
expect {
|
56
|
+
expect {
|
57
|
+
'x' * 10 * 1024
|
58
|
+
}.to perform_faster_than { 1 << 1 }.at_least(2).times
|
59
|
+
}.to raise_error(/expected given block to perform faster than comparison block by at_least \d+ times, but performed slower by \d+.\d+ times/)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with at_most count" do
|
64
|
+
it "passes if the block performs faster than sample" do
|
65
|
+
expect { 1 << 1 }.to perform_faster_than { 'x' * 10 * 1024 }.at_most(125)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "fails if the block performs faster than sample more than in 20 times" do
|
69
|
+
expect {
|
70
|
+
expect {
|
71
|
+
1 << 1
|
72
|
+
}.to perform_faster_than { 'x' * 10 * 1024 }.at_most(2).times
|
73
|
+
}.to raise_error(/expected given block to perform faster than comparison block by at_most \d+ times, but performed faster by \d+.\d+ times/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "expect { ... }.not_to perform_faster_than(...)" do
|
79
|
+
it "passes if the block performs slower than sample" do
|
80
|
+
expect { 'x' * 10 * 1024 }.not_to perform_faster_than { 1 << 1 }
|
81
|
+
end
|
82
|
+
|
83
|
+
it "fails if the block performs faster than sample" do
|
84
|
+
expect {
|
85
|
+
expect { 1 << 1 }.not_to perform_faster_than { 'x' * 10 * 1024 }
|
86
|
+
}.to raise_error(/expected given block not to perform faster than comparison block, but performed faster by \d+.\d+ times/)
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with at_least count' do
|
90
|
+
it "passes if the block performs slower than sample" do
|
91
|
+
expect {
|
92
|
+
'x' * 10 * 1024
|
93
|
+
}.not_to perform_faster_than { 1 << 1 }.at_least(20).times
|
94
|
+
end
|
95
|
+
|
96
|
+
it "fails if the block performs faster than sample" do
|
97
|
+
expect {
|
98
|
+
expect {
|
99
|
+
1 << 1
|
100
|
+
}.not_to perform_faster_than { 'x' * 10 * 1024 }.at_least(2).times
|
101
|
+
}.to raise_error(/expected given block not to perform faster than comparison block by at_least \d+ times, but performed faster by \d+.\d+ times/)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "expect { ... }.not_to perform_slower_than(...)" do
|
107
|
+
it "passes if the block performs faster than sample" do
|
108
|
+
expect { 1 << 1 }.not_to perform_slower_than { 'x' * 10 * 1024 }
|
109
|
+
end
|
110
|
+
|
111
|
+
it "fails if the block performs slower than sample" do
|
112
|
+
expect {
|
113
|
+
expect { 'x' * 10 * 1024 }.not_to perform_slower_than { 1 << 1 }
|
114
|
+
}.to raise_error(/expected given block not to perform slower than comparison block, but performed slower by \d+.\d+ times/)
|
115
|
+
end
|
116
|
+
|
117
|
+
context "with at_least count" do
|
118
|
+
it "passes if the block performs faster than sample" do
|
119
|
+
expect {
|
120
|
+
1 << 1
|
121
|
+
}.not_to perform_slower_than { 'x' * 10 * 1024 }.at_least(2).times
|
122
|
+
end
|
123
|
+
|
124
|
+
it "fails if the block performs slower than sample" do
|
125
|
+
expect {
|
126
|
+
expect {
|
127
|
+
'x' * 10 * 1024
|
128
|
+
}.not_to perform_slower_than { 1 << 1 }.at_least(5).times
|
129
|
+
}.to raise_error(/expected given block not to perform slower than comparison block by at_least \d+ times, but performed slower by \d+.\d+ times/)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "expect { ... }.to perform_slower_than(...)" do
|
135
|
+
it "passes if the block performs slower than sample" do
|
136
|
+
expect { 'x' * 10 * 1024 }.to perform_slower_than { 1 << 1 }
|
137
|
+
end
|
138
|
+
|
139
|
+
it "fails if the block performs faster than sample" do
|
140
|
+
expect {
|
141
|
+
expect { 1 << 1 }.to perform_slower_than { 'x' * 10 * 1024 }
|
142
|
+
}.to raise_error(/expected given block to perform slower than comparison block, but performed faster by \d+.\d+ times/)
|
143
|
+
end
|
144
|
+
|
145
|
+
context "with at_least count" do
|
146
|
+
it "passes if the block does performs slower than sample" do
|
147
|
+
expect {
|
148
|
+
'x' * 10 * 1024
|
149
|
+
}.to perform_slower_than { 1 << 1 }.at_least(20).times
|
150
|
+
end
|
151
|
+
|
152
|
+
it "fails if the block does performs faster than sample" do
|
153
|
+
expect {
|
154
|
+
expect {
|
155
|
+
1 << 1
|
156
|
+
}.to perform_slower_than { 'x' * 10 * 1024 }.at_least(2).times
|
157
|
+
}.to raise_error(/expected given block to perform slower than comparison block by at_least \d+ times, but performed faster by \d+.\d+ times/)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "with exact count" do
|
162
|
+
it "passes if the block performs slower than sample" do
|
163
|
+
expect { 1 << 1 }.to perform_slower_than { 1 << 1 }.exactly(1).times
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "with at_most count" do
|
168
|
+
it "passes if the block performs faster than sample" do
|
169
|
+
expect {
|
170
|
+
'x' * 10 * 1024
|
171
|
+
}.to perform_slower_than { 1 << 1 }.at_most(125).times
|
172
|
+
end
|
173
|
+
|
174
|
+
it "fails if the block performs slower than sample more than in 20 times" do
|
175
|
+
expect {
|
176
|
+
expect {
|
177
|
+
'x' * 10 * 1024
|
178
|
+
}.to perform_slower_than { 1 << 1 }.at_most(2).times
|
179
|
+
}.to raise_error(/expected given block to perform slower than comparison block by at_most \d+ times, but performed slower by \d+.\d+ times/)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
RSpec.describe '#perform_at_least' do
|
4
4
|
|
5
|
+
it "allows to configure matcher timings" do
|
6
|
+
bench = double(run: [10_000, 100])
|
7
|
+
allow(::Benchmark::Perf::Iteration).to receive(:new).and_return(bench)
|
8
|
+
expect {
|
9
|
+
'x' * 1024 * 10
|
10
|
+
}.to perform_at_least(10_000, warmup: 0.2, time: 0.3)
|
11
|
+
|
12
|
+
expect(::Benchmark::Perf::Iteration).to have_received(:new).
|
13
|
+
with(time: 0.3, warmup: 0.2)
|
14
|
+
end
|
15
|
+
|
5
16
|
context "expect { ... }.to perform_at_least(...).ips" do
|
6
17
|
it "passes if the block perfoms more than 10K ips" do
|
7
18
|
expect {
|
@@ -2,11 +2,18 @@
|
|
2
2
|
|
3
3
|
RSpec.describe 'RSpec::Benchmark::TimingMatcher', '#perform_under' do
|
4
4
|
it "propagates error inside expectation" do
|
5
|
-
expect {
|
5
|
+
expect {
|
6
6
|
expect { raise 'boom' }.to perform_under(0.01).sec
|
7
7
|
}.to raise_error(StandardError, /boom/)
|
8
8
|
end
|
9
9
|
|
10
|
+
it "allows to configure warmup cycles" do
|
11
|
+
bench = double(run: [0.005, 0.00001])
|
12
|
+
allow(::Benchmark::Perf::ExecutionTime).to receive(:new).and_return(bench)
|
13
|
+
expect { 'x' * 1024 * 10 }.to perform_under(0.006, warmup: 2).sec.and_sample(2)
|
14
|
+
expect(::Benchmark::Perf::ExecutionTime).to have_received(:new).with(warmup: 2)
|
15
|
+
end
|
16
|
+
|
10
17
|
context "expect { ... }.to perfom_under(...).and_sample" do
|
11
18
|
it "passes if the block performs under threshold" do
|
12
19
|
expect {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-benchmark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-perf
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- Rakefile
|
97
97
|
- lib/rspec-benchmark.rb
|
98
98
|
- lib/rspec/benchmark.rb
|
99
|
+
- lib/rspec/benchmark/comparison_matcher.rb
|
99
100
|
- lib/rspec/benchmark/format_time.rb
|
100
101
|
- lib/rspec/benchmark/iteration_matcher.rb
|
101
102
|
- lib/rspec/benchmark/matchers.rb
|
@@ -103,6 +104,7 @@ files:
|
|
103
104
|
- lib/rspec/benchmark/version.rb
|
104
105
|
- rspec-benchmark.gemspec
|
105
106
|
- spec/spec_helper.rb
|
107
|
+
- spec/unit/comparison_matcher_spec.rb
|
106
108
|
- spec/unit/format_time_spec.rb
|
107
109
|
- spec/unit/perform_at_least_spec.rb
|
108
110
|
- spec/unit/perform_under_spec.rb
|
@@ -134,6 +136,7 @@ specification_version: 4
|
|
134
136
|
summary: Performance testing matchers for RSpec
|
135
137
|
test_files:
|
136
138
|
- spec/spec_helper.rb
|
139
|
+
- spec/unit/comparison_matcher_spec.rb
|
137
140
|
- spec/unit/format_time_spec.rb
|
138
141
|
- spec/unit/perform_at_least_spec.rb
|
139
142
|
- spec/unit/perform_under_spec.rb
|