radius-spec 0.2.1 → 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/.rubocop.yml +1 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +7 -4
- data/benchmarks/bm_setup.rb +69 -0
- data/benchmarks/call_vs_yield.rb +148 -0
- data/benchmarks/case_equality_vs_class_check.rb +73 -0
- data/benchmarks/cover_vs_include.rb +106 -0
- data/benchmarks/delete_vs_tr.rb +100 -0
- data/benchmarks/double_negation.rb +167 -0
- data/benchmarks/empty_literal.rb +75 -0
- data/benchmarks/format_string.rb +58 -0
- data/benchmarks/format_string_token.rb +160 -0
- data/benchmarks/gsub_vs_tr.rb +95 -0
- data/benchmarks/hash_merge.rb +112 -0
- data/benchmarks/kwargs.rb +159 -0
- data/benchmarks/max_ternary.rb +105 -0
- data/benchmarks/max_ternary_micro.rb +129 -0
- data/benchmarks/unfreeze_string.rb +86 -0
- data/benchmarks/unpack_first.rb +54 -0
- data/bin/ci +1 -1
- data/bin/ci-code-review +28 -0
- data/common_rubocop.yml +83 -14
- data/lib/radius/spec/version.rb +1 -1
- data/radius-spec.gemspec +1 -0
- metadata +35 -4
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Run from the command line: bundle exec ruby benchmarks/max_ternary_micro.rb
|
4
|
+
require_relative 'bm_setup'
|
5
|
+
|
6
|
+
display_benchmark_header
|
7
|
+
|
8
|
+
section "Min First" do |bench|
|
9
|
+
x = 1
|
10
|
+
y = 2
|
11
|
+
|
12
|
+
bench.report("max") do |times|
|
13
|
+
i = 0
|
14
|
+
while i < times
|
15
|
+
[x, y].max
|
16
|
+
i += 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
bench.report("ternary") do |times|
|
21
|
+
i = 0
|
22
|
+
while i < times
|
23
|
+
(x < y) ? y : x
|
24
|
+
i += 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
section "Max First" do |bench|
|
30
|
+
x = 2
|
31
|
+
y = 1
|
32
|
+
|
33
|
+
bench.report("max") do |times|
|
34
|
+
i = 0
|
35
|
+
while i < times
|
36
|
+
[x, y].max
|
37
|
+
i += 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
bench.report("ternary") do |times|
|
42
|
+
i = 0
|
43
|
+
while i < times
|
44
|
+
(x < y) ? y : x
|
45
|
+
i += 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
section "Equal values" do |bench|
|
51
|
+
x = 2
|
52
|
+
y = 2
|
53
|
+
|
54
|
+
bench.report("max") do |times|
|
55
|
+
i = 0
|
56
|
+
while i < times
|
57
|
+
[x, y].max
|
58
|
+
i += 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
bench.report("ternary") do |times|
|
63
|
+
i = 0
|
64
|
+
while i < times
|
65
|
+
(x < y) ? y : x
|
66
|
+
i += 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
__END__
|
72
|
+
|
73
|
+
### Environment
|
74
|
+
|
75
|
+
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin16]
|
76
|
+
GC Disabled: false
|
77
|
+
|
78
|
+
### Test Cases
|
79
|
+
|
80
|
+
#### Min First
|
81
|
+
|
82
|
+
```
|
83
|
+
Warming up --------------------------------------
|
84
|
+
max 318.262k i/100ms
|
85
|
+
ternary 330.711k i/100ms
|
86
|
+
Calculating -------------------------------------
|
87
|
+
max 38.997M (± 0.6%) i/s - 193.822M in 5.001947s
|
88
|
+
ternary 48.280M (± 0.5%) i/s - 240.096M in 5.002313s
|
89
|
+
with 95.0% confidence
|
90
|
+
|
91
|
+
Comparison:
|
92
|
+
ternary: 48279773.6 i/s
|
93
|
+
max: 38996762.1 i/s - 1.24x (± 0.01) slower
|
94
|
+
with 95.0% confidence
|
95
|
+
```
|
96
|
+
|
97
|
+
#### Max First
|
98
|
+
|
99
|
+
```
|
100
|
+
Warming up --------------------------------------
|
101
|
+
max 336.333k i/100ms
|
102
|
+
ternary 344.267k i/100ms
|
103
|
+
Calculating -------------------------------------
|
104
|
+
max 38.699M (± 0.7%) i/s - 192.046M in 5.000931s
|
105
|
+
ternary 50.601M (± 0.6%) i/s - 251.315M in 5.002150s
|
106
|
+
with 95.0% confidence
|
107
|
+
|
108
|
+
Comparison:
|
109
|
+
ternary: 50601023.9 i/s
|
110
|
+
max: 38699482.7 i/s - 1.31x (± 0.01) slower
|
111
|
+
with 95.0% confidence
|
112
|
+
```
|
113
|
+
|
114
|
+
#### Equal values
|
115
|
+
|
116
|
+
```
|
117
|
+
Warming up --------------------------------------
|
118
|
+
max 331.543k i/100ms
|
119
|
+
ternary 342.686k i/100ms
|
120
|
+
Calculating -------------------------------------
|
121
|
+
max 39.661M (± 0.6%) i/s - 197.268M in 5.004271s
|
122
|
+
ternary 47.147M (± 0.5%) i/s - 234.740M in 5.006089s
|
123
|
+
with 95.0% confidence
|
124
|
+
|
125
|
+
Comparison:
|
126
|
+
ternary: 47147208.6 i/s
|
127
|
+
max: 39660659.9 i/s - 1.19x (± 0.01) slower
|
128
|
+
with 95.0% confidence
|
129
|
+
```
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Run from the command line: bundle exec ruby benchmarks/unfreeze_string.rb
|
4
|
+
require_relative 'bm_setup'
|
5
|
+
|
6
|
+
display_benchmark_header
|
7
|
+
|
8
|
+
# rubocop:disable Performance/UnfreezeString
|
9
|
+
section "Unfreezing empty string" do |bench|
|
10
|
+
bench.report("String.new") do
|
11
|
+
String.new
|
12
|
+
end
|
13
|
+
|
14
|
+
bench.report("+") do
|
15
|
+
+""
|
16
|
+
end
|
17
|
+
|
18
|
+
bench.report("dup") do
|
19
|
+
"".dup
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
STRING = "Any String"
|
24
|
+
section "Unfreezing string" do |bench|
|
25
|
+
bench.report("String.new") do
|
26
|
+
String.new(STRING)
|
27
|
+
end
|
28
|
+
|
29
|
+
bench.report("+") do
|
30
|
+
+STRING
|
31
|
+
end
|
32
|
+
|
33
|
+
bench.report("dup") do
|
34
|
+
STRING.dup
|
35
|
+
end
|
36
|
+
end
|
37
|
+
# rubocop:enable Performance/UnfreezeString
|
38
|
+
|
39
|
+
__END__
|
40
|
+
|
41
|
+
### Environment
|
42
|
+
|
43
|
+
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin16]
|
44
|
+
GC Disabled: false
|
45
|
+
|
46
|
+
### Test Cases
|
47
|
+
|
48
|
+
#### Unfreezing empty string
|
49
|
+
|
50
|
+
```
|
51
|
+
Warming up --------------------------------------
|
52
|
+
String.new 262.027k i/100ms
|
53
|
+
+ 286.997k i/100ms
|
54
|
+
dup 217.963k i/100ms
|
55
|
+
Calculating -------------------------------------
|
56
|
+
String.new 6.791M (± 0.9%) i/s - 34.064M in 5.029927s
|
57
|
+
+ 8.811M (± 1.1%) i/s - 43.911M in 5.011455s
|
58
|
+
dup 4.627M (± 1.0%) i/s - 23.104M in 5.007394s
|
59
|
+
with 95.0% confidence
|
60
|
+
|
61
|
+
Comparison:
|
62
|
+
+: 8810714.9 i/s
|
63
|
+
String.new: 6791074.6 i/s - 1.30x (± 0.02) slower
|
64
|
+
dup: 4626875.0 i/s - 1.90x (± 0.03) slower
|
65
|
+
with 95.0% confidence
|
66
|
+
```
|
67
|
+
|
68
|
+
#### Unfreezing string
|
69
|
+
|
70
|
+
```
|
71
|
+
Warming up --------------------------------------
|
72
|
+
String.new 220.258k i/100ms
|
73
|
+
+ 287.795k i/100ms
|
74
|
+
dup 214.192k i/100ms
|
75
|
+
Calculating -------------------------------------
|
76
|
+
String.new 4.624M (± 0.8%) i/s - 23.127M in 5.010887s
|
77
|
+
+ 8.946M (± 0.9%) i/s - 44.608M in 5.001680s
|
78
|
+
dup 4.513M (± 0.9%) i/s - 22.704M in 5.041383s
|
79
|
+
with 95.0% confidence
|
80
|
+
|
81
|
+
Comparison:
|
82
|
+
+: 8946340.5 i/s
|
83
|
+
String.new: 4624267.9 i/s - 1.93x (± 0.02) slower
|
84
|
+
dup: 4513230.8 i/s - 1.98x (± 0.02) slower
|
85
|
+
with 95.0% confidence
|
86
|
+
```
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Run from the command line: bundle exec ruby benchmarks/unpack_first.rb
|
4
|
+
require_relative 'bm_setup'
|
5
|
+
|
6
|
+
display_benchmark_header
|
7
|
+
|
8
|
+
PACKED_STRING = "foo"
|
9
|
+
PACKED_FORMAT = "h*"
|
10
|
+
|
11
|
+
# rubocop:disable Style/UnpackFirst
|
12
|
+
section "Unpacking strings" do |bench|
|
13
|
+
bench.report("unpack.first") do
|
14
|
+
PACKED_STRING.unpack(PACKED_FORMAT).first
|
15
|
+
end
|
16
|
+
|
17
|
+
bench.report("unpack[0]") do
|
18
|
+
PACKED_STRING.unpack(PACKED_FORMAT)[0]
|
19
|
+
end
|
20
|
+
|
21
|
+
bench.report("unpack1") do
|
22
|
+
PACKED_STRING.unpack1(PACKED_FORMAT)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# rubocop:enable Style/UnpackFirst
|
26
|
+
|
27
|
+
__END__
|
28
|
+
|
29
|
+
### Environment
|
30
|
+
|
31
|
+
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin16]
|
32
|
+
GC Disabled: false
|
33
|
+
|
34
|
+
### Test Cases
|
35
|
+
|
36
|
+
#### Unpacking strings
|
37
|
+
|
38
|
+
```
|
39
|
+
Warming up --------------------------------------
|
40
|
+
unpack.first 228.848k i/100ms
|
41
|
+
unpack[0] 225.375k i/100ms
|
42
|
+
unpack1 254.431k i/100ms
|
43
|
+
Calculating -------------------------------------
|
44
|
+
unpack.first 5.074M (± 1.0%) i/s - 25.402M in 5.021645s
|
45
|
+
unpack[0] 5.412M (± 1.0%) i/s - 27.045M in 5.012499s
|
46
|
+
unpack1 7.185M (± 0.9%) i/s - 35.875M in 5.011588s
|
47
|
+
with 95.0% confidence
|
48
|
+
|
49
|
+
Comparison:
|
50
|
+
unpack1: 7184877.9 i/s
|
51
|
+
unpack[0]: 5412005.1 i/s - 1.33x (± 0.02) slower
|
52
|
+
unpack.first: 5074389.3 i/s - 1.42x (± 0.02) slower
|
53
|
+
with 95.0% confidence
|
54
|
+
```
|
data/bin/ci
CHANGED
data/bin/ci-code-review
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# See:
|
4
|
+
# - https://docs.travis-ci.com/user/environment-variables/#Convenience-Variables
|
5
|
+
# - https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables
|
6
|
+
# - https://docs.travis-ci.com/user/pull-requests/#Pull-Requests-and-Security-Restrictions
|
7
|
+
if [[ "$TRAVIS_PULL_REQUEST" = "false" ]] || [[ "$TRAVIS_BRANCH" = "production" ]]; then
|
8
|
+
exit
|
9
|
+
fi
|
10
|
+
|
11
|
+
set -e
|
12
|
+
cd "$(dirname "$0")/.."
|
13
|
+
|
14
|
+
REVIEWDOG_VERSION="0.9.9"
|
15
|
+
|
16
|
+
if ! [ "$(./bin/reviewdog -version)" = "$REVIEWDOG_VERSION" ]; then
|
17
|
+
echo "Installing reviewdog version ${REVIEWDOG_VERSION}..."
|
18
|
+
curl -fsSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 \
|
19
|
+
-o ./bin/reviewdog
|
20
|
+
chmod +x ./bin/reviewdog
|
21
|
+
fi
|
22
|
+
|
23
|
+
echo Rubocop Version: $(./bin/rubocop --version)
|
24
|
+
echo Review Dog Version: $(./bin/reviewdog -version)
|
25
|
+
|
26
|
+
# Add `-diff="git diff master"` to reviewdog args when running locally
|
27
|
+
./bin/rubocop --config .rubocop.yml --extra-details --display-style-guide --rails | \
|
28
|
+
./bin/reviewdog -f=rubocop -reporter=github-pr-check
|
data/common_rubocop.yml
CHANGED
@@ -12,9 +12,6 @@ AllCops:
|
|
12
12
|
- 'bin/yard'
|
13
13
|
# Exclude vendored content
|
14
14
|
- 'vendor/**/*'
|
15
|
-
Include:
|
16
|
-
- '**/Brewfile'
|
17
|
-
- '**/Rakefile'
|
18
15
|
|
19
16
|
# Modifiers should be indented as deep as method definitions, or as deep as the
|
20
17
|
# class/module keyword, depending on configuration.
|
@@ -34,20 +31,14 @@ Layout/AccessModifierIndentation:
|
|
34
31
|
Layout/BlockAlignment:
|
35
32
|
Enabled: false
|
36
33
|
|
37
|
-
# Disabling this until it is fixed to handle multi-line method chains where the
|
38
|
-
# first method call is multi-line.
|
39
|
-
#
|
40
|
-
# See # https://github.com/bbatsov/rubocop/issues/5650
|
41
|
-
Layout/ClosingParenthesisIndentation:
|
42
|
-
Enabled: false
|
43
|
-
|
44
34
|
# Disabling this until it is fixed to handle multi-line method chains where the
|
45
35
|
# first method call is multi-line.
|
46
36
|
#
|
47
37
|
# See # https://github.com/bbatsov/rubocop/issues/5650
|
48
38
|
#
|
49
39
|
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
50
|
-
# SupportedStyles: consistent,
|
40
|
+
# SupportedStyles: consistent, consistent_relative_to_receiver,
|
41
|
+
# special_for_inner_method_call, special_for_inner_method_call_in_parentheses
|
51
42
|
Layout/FirstParameterIndentation:
|
52
43
|
Enabled: false
|
53
44
|
|
@@ -160,8 +151,7 @@ Naming/FileName:
|
|
160
151
|
# Blacklist: END, (?-mix:EO[A-Z]{1})
|
161
152
|
Naming/HeredocDelimiterNaming:
|
162
153
|
Blacklist:
|
163
|
-
- 'END'
|
164
|
-
- '(?-mix:EO[A-EG-Z]{1})'
|
154
|
+
- !ruby/regexp '/(^|\s)(EO[A-EG-Z]{1}|END)(\s|$)/'
|
165
155
|
|
166
156
|
# `alias` behavior changes on scope. In general we expect the behavior to be
|
167
157
|
# that which is defined by `alias_method`.
|
@@ -173,6 +163,20 @@ Naming/HeredocDelimiterNaming:
|
|
173
163
|
Style/Alias:
|
174
164
|
EnforcedStyle: prefer_alias_method
|
175
165
|
|
166
|
+
# Keeping with our semantic style we allow use of `and` / `or` conditionals
|
167
|
+
# when it is used for control flow:
|
168
|
+
#
|
169
|
+
# system("some command") or system("another command")
|
170
|
+
#
|
171
|
+
# Used in this manner it provides additional semantic clues to the intent of
|
172
|
+
# the code. However, when there is a conditional, or the intent is to perform
|
173
|
+
# a boolean comparison, the `&&` / `||` style should be used.
|
174
|
+
#
|
175
|
+
# Configuration parameters: EnforcedStyle.
|
176
|
+
# SupportedStyles: always, conditionals
|
177
|
+
Style/AndOr:
|
178
|
+
EnforcedStyle: conditionals
|
179
|
+
|
176
180
|
# These days most people have editors which support unicode and other
|
177
181
|
# non-ASCII characters.
|
178
182
|
#
|
@@ -209,6 +213,7 @@ Style/BlockDelimiters:
|
|
209
213
|
- with_object
|
210
214
|
FunctionalMethods:
|
211
215
|
- each_with_object
|
216
|
+
- find
|
212
217
|
- git_source
|
213
218
|
- let
|
214
219
|
- let!
|
@@ -221,6 +226,51 @@ Style/BlockDelimiters:
|
|
221
226
|
- proc
|
222
227
|
- it
|
223
228
|
|
229
|
+
# The double negation idiom is a common Ruby-ism. All languages have various
|
230
|
+
# idioms and part of learning the language is learning the common idioms. Once
|
231
|
+
# learning the meaning it is not cryptic as Rubocop implies.
|
232
|
+
#
|
233
|
+
# > Double negation converts converts a value to boolean.
|
234
|
+
# >
|
235
|
+
# > It converts "truthy" values to `true` and "falsey" values, `nil` and
|
236
|
+
# > `false`, to `false`.
|
237
|
+
#
|
238
|
+
# The [Rubocop style guide](https://github.com/rubocop-hq/ruby-style-guide#no-bang-bang)
|
239
|
+
# does have a valid complaint about it's use in a conditional:
|
240
|
+
#
|
241
|
+
# > you don't need this explicit conversion in the condition of a control
|
242
|
+
# > expression; using it only obscures your intention...
|
243
|
+
# >
|
244
|
+
# > ```ruby
|
245
|
+
# > # bad
|
246
|
+
# > x = 'test'
|
247
|
+
# > # obscure nil check
|
248
|
+
# > if !!x
|
249
|
+
# > # body omitted
|
250
|
+
# > end
|
251
|
+
# >
|
252
|
+
# > # good
|
253
|
+
# > x = 'test'
|
254
|
+
# > if x
|
255
|
+
# > # body omitted
|
256
|
+
# > end
|
257
|
+
# > ```
|
258
|
+
#
|
259
|
+
# This is true and we completely agree. However the check isn't limited to just
|
260
|
+
# conditional control expressions. It affects any use of the idiom.
|
261
|
+
#
|
262
|
+
# We believe using the idiom is completely valid for predicate methods to
|
263
|
+
# ensure either a `true` or `false` return, instead of just a "truthy" or
|
264
|
+
# "falsey" response. As it is an op it is a bit faster than the alternative of
|
265
|
+
# sending `nil?` to the object and more concise than using `obj == nil`. It
|
266
|
+
# also works with something that is potentially `false` as expected.
|
267
|
+
#
|
268
|
+
# As we cannot customize this to only limit it to the conditional control
|
269
|
+
# expressions, or instances which may be better replaced with something else
|
270
|
+
# (like `blank?`), we are disabling it.
|
271
|
+
Style/DoubleNegation:
|
272
|
+
Enabled: false
|
273
|
+
|
224
274
|
# Using `case` instead of an `if` expression when the case condition is empty
|
225
275
|
# can be more expressive of intent. Using multiple "cases" informs the reader
|
226
276
|
# that all of the conditions are related or coupled in a meaningful way.
|
@@ -301,7 +351,17 @@ Style/NumericPredicate:
|
|
301
351
|
Enabled: false
|
302
352
|
|
303
353
|
# Prefer slashes for simple expressions. For multi-line use percent literal
|
304
|
-
# to support comments and other advanced features.
|
354
|
+
# to support comments and other advanced features. By using the mixed style we
|
355
|
+
# are choosing to use `%r{}` for multi-line regexps. In general we are not a
|
356
|
+
# fan of single vs multi-line dictating a style. We do make an exception in
|
357
|
+
# this case because of the parity the braces give to general code block
|
358
|
+
# grouping:
|
359
|
+
#
|
360
|
+
# regex = %r{
|
361
|
+
# foo
|
362
|
+
# (bar)
|
363
|
+
# (baz)
|
364
|
+
# }x
|
305
365
|
#
|
306
366
|
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
|
307
367
|
# SupportedStyles: slashes, percent_r, mixed
|
@@ -358,6 +418,15 @@ Style/RescueStandardError:
|
|
358
418
|
Style/StringLiterals:
|
359
419
|
Enabled: false
|
360
420
|
|
421
|
+
# As with regular string literals we have no real preference for this. Forcing
|
422
|
+
# one style of strings over others for this case just adds to Rubocop noise and
|
423
|
+
# in our experience developer frustration.
|
424
|
+
#
|
425
|
+
# Configuration parameters: EnforcedStyle.
|
426
|
+
# SupportedStyles: single_quotes, double_quotes
|
427
|
+
Style/StringLiteralsInInterpolation:
|
428
|
+
Enabled: false
|
429
|
+
|
361
430
|
# We don't feel too strongly about percent vs bracket array style. We tend to
|
362
431
|
# use the percent style, which also happens to be Rubocop's default. So for
|
363
432
|
# pedantic consistency we'll enforce this.
|