ddmetrics 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b88f4608168f197c67e407f072a257e5fd6b76839c72a3dc0f63b326bc363534
4
- data.tar.gz: 043c06c1a3414422f5f8a442dbec24e634a086f09265a60dc9bb1dd22ef12b7f
3
+ metadata.gz: 39768ef4439441b98cfdb0a376d40e2bddd019c3d9afd39565ff949bd7b95409
4
+ data.tar.gz: be2ae1de043350f9edb5824fb735b40f576d959fdc648f365339c396b06a6dbe
5
5
  SHA512:
6
- metadata.gz: c36890a111a870ec0286c02e8d5320ddd5b9ec5d7b3fa7d6809065d7c655a806698a8787e9a07f69468c727c8222775e44ac2935ac357c9fdec896387fe7b69b
7
- data.tar.gz: cf4122e405770d4fc787628660366bc634bbd0d29d41e9002b8564cf56dbccf7a74936a602119e01fb5505d41aff01df9cc3008f8fc72d06685c37f8b19f69d0
6
+ metadata.gz: 97defa4e6aab76e2d7d64f4b5099413157e2078f54674a38ca24ddf827629f92a2b2c4ee9a891c1ef08dd7c71a2990d8323f969750f8c2de3474de057ed01f2c
7
+ data.tar.gz: fd283484e52ef65e6941ec203a3077485d1ccbebe70ffdee0a5e50a7435711313329ba78090c614e7b1b42e077dc53594bc9d51c3b81f9ee7033d3091ea2512b
data/.rubocop.yml CHANGED
@@ -1,3 +1,11 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - rubocop-rake
5
+ - rubocop-rspec
6
+
7
+
8
+
1
9
  # ----- CONFIGURED -----
2
10
 
3
11
  AllCops:
@@ -7,10 +15,13 @@ AllCops:
7
15
  Style/TrailingCommaInArguments:
8
16
  EnforcedStyleForMultiline: comma
9
17
 
10
- Style/TrailingCommaInLiteral:
18
+ Style/TrailingCommaInArrayLiteral:
11
19
  EnforcedStyleForMultiline: comma
12
20
 
13
- Layout/IndentArray:
21
+ Style/TrailingCommaInHashLiteral:
22
+ EnforcedStyleForMultiline: comma
23
+
24
+ Layout/FirstArrayElementIndentation:
14
25
  EnforcedStyle: consistent
15
26
 
16
27
  # Documentation lives elsewhere, and not everything needs to be documented.
@@ -28,32 +39,293 @@ Lint/AmbiguousBlockAssociation:
28
39
 
29
40
  # Cops for metrics are disabled because they should not cause tests to fail.
30
41
 
31
- Metrics/AbcSize:
32
- Enabled: false
33
-
34
- Metrics/BlockLength:
35
- Enabled: false
36
-
37
- Metrics/BlockNesting:
42
+ Metrics:
38
43
  Enabled: false
39
44
 
40
- Metrics/ClassLength:
45
+ Layout/LineLength:
41
46
  Enabled: false
42
47
 
43
- Metrics/CyclomaticComplexity:
44
- Enabled: false
45
48
 
46
- Metrics/LineLength:
47
- Enabled: false
48
49
 
49
- Metrics/MethodLength:
50
- Enabled: false
50
+ # ----- NEW -----
51
51
 
52
- Metrics/ModuleLength:
53
- Enabled: false
54
-
55
- Metrics/ParameterLists:
56
- Enabled: false
57
-
58
- Metrics/PerceivedComplexity:
59
- Enabled: false
52
+ Gemspec/DeprecatedAttributeAssignment: # new in 1.30
53
+ Enabled: true
54
+ Gemspec/DevelopmentDependencies: # new in 1.44
55
+ Enabled: true
56
+ Gemspec/RequireMFA: # new in 1.23
57
+ Enabled: true
58
+ Layout/LineContinuationLeadingSpace: # new in 1.31
59
+ Enabled: true
60
+ Layout/LineContinuationSpacing: # new in 1.31
61
+ Enabled: true
62
+ Layout/LineEndStringConcatenationIndentation: # new in 1.18
63
+ Enabled: true
64
+ Layout/SpaceBeforeBrackets: # new in 1.7
65
+ Enabled: true
66
+ Lint/AmbiguousAssignment: # new in 1.7
67
+ Enabled: true
68
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
69
+ Enabled: true
70
+ Lint/AmbiguousRange: # new in 1.19
71
+ Enabled: true
72
+ Lint/ConstantOverwrittenInRescue: # new in 1.31
73
+ Enabled: true
74
+ Lint/DeprecatedConstants: # new in 1.8
75
+ Enabled: true
76
+ Lint/DuplicateBranch: # new in 1.3
77
+ Enabled: true
78
+ Lint/DuplicateMagicComment: # new in 1.37
79
+ Enabled: true
80
+ Lint/DuplicateMatchPattern: # new in 1.50
81
+ Enabled: true
82
+ Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
83
+ Enabled: true
84
+ Lint/EmptyBlock: # new in 1.1
85
+ Enabled: true
86
+ Lint/EmptyClass: # new in 1.3
87
+ Enabled: true
88
+ Lint/EmptyInPattern: # new in 1.16
89
+ Enabled: true
90
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
91
+ Enabled: true
92
+ Lint/LambdaWithoutLiteralBlock: # new in 1.8
93
+ Enabled: true
94
+ Lint/MixedCaseRange: # new in 1.53
95
+ Enabled: true
96
+ Lint/NoReturnInBeginEndBlocks: # new in 1.2
97
+ Enabled: true
98
+ Lint/NonAtomicFileOperation: # new in 1.31
99
+ Enabled: true
100
+ Lint/NumberedParameterAssignment: # new in 1.9
101
+ Enabled: true
102
+ Lint/OrAssignmentToConstant: # new in 1.9
103
+ Enabled: true
104
+ Lint/RedundantDirGlobSort: # new in 1.8
105
+ Enabled: true
106
+ Lint/RedundantRegexpQuantifiers: # new in 1.53
107
+ Enabled: true
108
+ Lint/RefinementImportMethods: # new in 1.27
109
+ Enabled: true
110
+ Lint/RequireRangeParentheses: # new in 1.32
111
+ Enabled: true
112
+ Lint/RequireRelativeSelfPath: # new in 1.22
113
+ Enabled: true
114
+ Lint/SymbolConversion: # new in 1.9
115
+ Enabled: true
116
+ Lint/ToEnumArguments: # new in 1.1
117
+ Enabled: true
118
+ Lint/TripleQuotes: # new in 1.9
119
+ Enabled: true
120
+ Lint/UnexpectedBlockArity: # new in 1.5
121
+ Enabled: true
122
+ Lint/UnmodifiedReduceAccumulator: # new in 1.1
123
+ Enabled: true
124
+ Lint/UselessRescue: # new in 1.43
125
+ Enabled: true
126
+ Lint/UselessRuby2Keywords: # new in 1.23
127
+ Enabled: true
128
+ Naming/BlockForwarding: # new in 1.24
129
+ Enabled: true
130
+ Security/CompoundHash: # new in 1.28
131
+ Enabled: true
132
+ Security/IoMethods: # new in 1.22
133
+ Enabled: true
134
+ Style/ArgumentsForwarding: # new in 1.1
135
+ Enabled: true
136
+ Style/ArrayIntersect: # new in 1.40
137
+ Enabled: true
138
+ Style/CollectionCompact: # new in 1.2
139
+ Enabled: true
140
+ Style/ComparableClamp: # new in 1.44
141
+ Enabled: true
142
+ Style/ConcatArrayLiterals: # new in 1.41
143
+ Enabled: true
144
+ Style/DataInheritance: # new in 1.49
145
+ Enabled: true
146
+ Style/DirEmpty: # new in 1.48
147
+ Enabled: true
148
+ Style/DocumentDynamicEvalDefinition: # new in 1.1
149
+ Enabled: true
150
+ Style/EmptyHeredoc: # new in 1.32
151
+ Enabled: true
152
+ Style/EndlessMethod: # new in 1.8
153
+ Enabled: true
154
+ Style/EnvHome: # new in 1.29
155
+ Enabled: true
156
+ Style/ExactRegexpMatch: # new in 1.51
157
+ Enabled: true
158
+ Style/FetchEnvVar: # new in 1.28
159
+ Enabled: true
160
+ Style/FileEmpty: # new in 1.48
161
+ Enabled: true
162
+ Style/FileRead: # new in 1.24
163
+ Enabled: true
164
+ Style/FileWrite: # new in 1.24
165
+ Enabled: true
166
+ Style/HashConversion: # new in 1.10
167
+ Enabled: true
168
+ Style/HashExcept: # new in 1.7
169
+ Enabled: true
170
+ Style/IfWithBooleanLiteralBranches: # new in 1.9
171
+ Enabled: true
172
+ Style/InPatternThen: # new in 1.16
173
+ Enabled: true
174
+ Style/MagicCommentFormat: # new in 1.35
175
+ Enabled: true
176
+ Style/MapCompactWithConditionalBlock: # new in 1.30
177
+ Enabled: true
178
+ Style/MapToHash: # new in 1.24
179
+ Enabled: true
180
+ Style/MapToSet: # new in 1.42
181
+ Enabled: true
182
+ Style/MinMaxComparison: # new in 1.42
183
+ Enabled: true
184
+ Style/MultilineInPatternThen: # new in 1.16
185
+ Enabled: true
186
+ Style/NegatedIfElseCondition: # new in 1.2
187
+ Enabled: true
188
+ Style/NestedFileDirname: # new in 1.26
189
+ Enabled: true
190
+ Style/NilLambda: # new in 1.3
191
+ Enabled: true
192
+ Style/NumberedParameters: # new in 1.22
193
+ Enabled: true
194
+ Style/NumberedParametersLimit: # new in 1.22
195
+ Enabled: true
196
+ Style/ObjectThen: # new in 1.28
197
+ Enabled: true
198
+ Style/OpenStructUse: # new in 1.23
199
+ Enabled: true
200
+ Style/OperatorMethodCall: # new in 1.37
201
+ Enabled: true
202
+ Style/QuotedSymbols: # new in 1.16
203
+ Enabled: true
204
+ Style/RedundantArgument: # new in 1.4
205
+ Enabled: true
206
+ Style/RedundantArrayConstructor: # new in 1.52
207
+ Enabled: true
208
+ Style/RedundantConstantBase: # new in 1.40
209
+ Enabled: true
210
+ Style/RedundantCurrentDirectoryInPath: # new in 1.53
211
+ Enabled: true
212
+ Style/RedundantDoubleSplatHashBraces: # new in 1.41
213
+ Enabled: true
214
+ Style/RedundantEach: # new in 1.38
215
+ Enabled: true
216
+ Style/RedundantFilterChain: # new in 1.52
217
+ Enabled: true
218
+ Style/RedundantHeredocDelimiterQuotes: # new in 1.45
219
+ Enabled: true
220
+ Style/RedundantInitialize: # new in 1.27
221
+ Enabled: true
222
+ Style/RedundantLineContinuation: # new in 1.49
223
+ Enabled: true
224
+ Style/RedundantRegexpArgument: # new in 1.53
225
+ Enabled: true
226
+ Style/RedundantRegexpConstructor: # new in 1.52
227
+ Enabled: true
228
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
229
+ Enabled: true
230
+ Style/RedundantStringEscape: # new in 1.37
231
+ Enabled: true
232
+ Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
233
+ Enabled: true
234
+ Style/SelectByRegexp: # new in 1.22
235
+ Enabled: true
236
+ Style/SingleLineDoEndBlock: # new in 1.57
237
+ Enabled: true
238
+ Style/StringChars: # new in 1.12
239
+ Enabled: true
240
+ Style/SwapValues: # new in 1.1
241
+ Enabled: true
242
+ Style/YAMLFileRead: # new in 1.53
243
+ Enabled: true
244
+ Capybara/ClickLinkOrButtonStyle: # new in 2.19
245
+ Enabled: true
246
+ Capybara/MatchStyle: # new in 2.17
247
+ Enabled: true
248
+ Capybara/NegationMatcher: # new in 2.14
249
+ Enabled: true
250
+ Capybara/SpecificActions: # new in 2.14
251
+ Enabled: true
252
+ Capybara/SpecificFinders: # new in 2.13
253
+ Enabled: true
254
+ Capybara/SpecificMatcher: # new in 2.12
255
+ Enabled: true
256
+ Capybara/RSpec/HaveSelector: # new in 2.19
257
+ Enabled: true
258
+ Capybara/RSpec/PredicateMatcher: # new in 2.19
259
+ Enabled: true
260
+ FactoryBot/AssociationStyle: # new in 2.23
261
+ Enabled: true
262
+ FactoryBot/ConsistentParenthesesStyle: # new in 2.14
263
+ Enabled: true
264
+ FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
265
+ Enabled: true
266
+ FactoryBot/FactoryNameStyle: # new in 2.16
267
+ Enabled: true
268
+ FactoryBot/IdSequence: # new in <<next>>
269
+ Enabled: true
270
+ FactoryBot/RedundantFactoryOption: # new in 2.23
271
+ Enabled: true
272
+ FactoryBot/SyntaxMethods: # new in 2.7
273
+ Enabled: true
274
+ RSpec/BeEmpty: # new in 2.20
275
+ Enabled: true
276
+ RSpec/BeEq: # new in 2.9.0
277
+ Enabled: true
278
+ RSpec/BeNil: # new in 2.9.0
279
+ Enabled: true
280
+ RSpec/ChangeByZero: # new in 2.11
281
+ Enabled: true
282
+ RSpec/ContainExactly: # new in 2.19
283
+ Enabled: true
284
+ RSpec/DuplicatedMetadata: # new in 2.16
285
+ Enabled: true
286
+ RSpec/EmptyMetadata: # new in 2.24
287
+ Enabled: true
288
+ RSpec/Eq: # new in 2.24
289
+ Enabled: true
290
+ RSpec/ExcessiveDocstringSpacing: # new in 2.5
291
+ Enabled: true
292
+ RSpec/IdenticalEqualityAssertion: # new in 2.4
293
+ Enabled: true
294
+ RSpec/IndexedLet: # new in 2.20
295
+ Enabled: true
296
+ RSpec/MatchArray: # new in 2.19
297
+ Enabled: true
298
+ RSpec/MetadataStyle: # new in 2.24
299
+ Enabled: true
300
+ RSpec/NoExpectationExample: # new in 2.13
301
+ Enabled: true
302
+ RSpec/PendingWithoutReason: # new in 2.16
303
+ Enabled: true
304
+ RSpec/ReceiveMessages: # new in 2.23
305
+ Enabled: true
306
+ RSpec/RedundantAround: # new in 2.19
307
+ Enabled: true
308
+ RSpec/SkipBlockInsideExample: # new in 2.19
309
+ Enabled: true
310
+ RSpec/SortMetadata: # new in 2.14
311
+ Enabled: true
312
+ RSpec/SpecFilePathFormat: # new in 2.24
313
+ Enabled: true
314
+ RSpec/SpecFilePathSuffix: # new in 2.24
315
+ Enabled: true
316
+ RSpec/SubjectDeclaration: # new in 2.5
317
+ Enabled: true
318
+ RSpec/VerifiedDoubleReference: # new in 2.10.0
319
+ Enabled: true
320
+ RSpec/Rails/AvoidSetupHook: # new in 2.4
321
+ Enabled: true
322
+ RSpec/Rails/HaveHttpStatus: # new in 2.12
323
+ Enabled: true
324
+ RSpec/Rails/InferredSpecType: # new in 2.14
325
+ Enabled: true
326
+ RSpec/Rails/MinitestAssertions: # new in 2.17
327
+ Enabled: true
328
+ RSpec/Rails/NegationBeValid: # new in 2.23
329
+ Enabled: true
330
+ RSpec/Rails/TravelAround: # new in 2.19
331
+ Enabled: true
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,112 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --exclude-limit 300`
3
+ # on 2023-10-23 14:11:14 UTC using RuboCop version 1.57.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ # Configuration parameters: EnforcedStyle.
12
+ # SupportedStyles: be, be_nil
13
+ RSpec/BeNil:
14
+ Exclude:
15
+ - 'spec/ddmetrics_spec.rb'
16
+
17
+ # Offense count: 15
18
+ # Configuration parameters: Prefixes, AllowedPatterns.
19
+ # Prefixes: when, with, without
20
+ RSpec/ContextWording:
21
+ Exclude:
22
+ - 'spec/ddmetrics/basic_summary_spec.rb'
23
+ - 'spec/ddmetrics/counter_spec.rb'
24
+ - 'spec/ddmetrics/stats_spec.rb'
25
+ - 'spec/ddmetrics/summary_spec.rb'
26
+ - 'spec/ddmetrics/table_spec.rb'
27
+
28
+ # Offense count: 3
29
+ # This cop supports safe autocorrection (--autocorrect).
30
+ # Configuration parameters: AllowConsecutiveOneLiners.
31
+ RSpec/EmptyLineAfterHook:
32
+ Exclude:
33
+ - 'spec/ddmetrics/basic_summary_spec.rb'
34
+ - 'spec/ddmetrics/counter_spec.rb'
35
+
36
+ # Offense count: 9
37
+ # Configuration parameters: CountAsOne.
38
+ RSpec/ExampleLength:
39
+ Max: 9
40
+
41
+ # Offense count: 1
42
+ # This cop supports unsafe autocorrection (--autocorrect-all).
43
+ # Configuration parameters: EnforcedStyle.
44
+ # SupportedStyles: method_call, block
45
+ RSpec/ExpectChange:
46
+ Exclude:
47
+ - 'spec/ddmetrics/basic_counter_spec.rb'
48
+
49
+ # Offense count: 8
50
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
51
+ # Include: **/*_spec*rb*, **/spec/**/*
52
+ RSpec/FilePath:
53
+ Exclude:
54
+ - 'spec/ddmetrics/basic_counter_spec.rb'
55
+ - 'spec/ddmetrics/basic_summary_spec.rb'
56
+ - 'spec/ddmetrics/counter_spec.rb'
57
+ - 'spec/ddmetrics/stats_spec.rb'
58
+ - 'spec/ddmetrics/stopwatch_spec.rb'
59
+ - 'spec/ddmetrics/summary_spec.rb'
60
+ - 'spec/ddmetrics/table_spec.rb'
61
+ - 'spec/ddmetrics_spec.rb'
62
+
63
+ # Offense count: 2
64
+ # This cop supports safe autocorrection (--autocorrect).
65
+ RSpec/MatchArray:
66
+ Exclude:
67
+ - 'spec/ddmetrics/counter_spec.rb'
68
+ - 'spec/ddmetrics/summary_spec.rb'
69
+
70
+ # Offense count: 6
71
+ RSpec/MultipleExpectations:
72
+ Max: 6
73
+
74
+ # Offense count: 32
75
+ # Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
76
+ # SupportedStyles: always, named_only
77
+ RSpec/NamedSubject:
78
+ Exclude:
79
+ - 'spec/ddmetrics/basic_counter_spec.rb'
80
+ - 'spec/ddmetrics/basic_summary_spec.rb'
81
+ - 'spec/ddmetrics/counter_spec.rb'
82
+ - 'spec/ddmetrics/stats_spec.rb'
83
+ - 'spec/ddmetrics/summary_spec.rb'
84
+
85
+ # Offense count: 8
86
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
87
+ # Include: **/*_spec.rb
88
+ RSpec/SpecFilePathFormat:
89
+ Exclude:
90
+ - '**/spec/routing/**/*'
91
+ - 'spec/ddmetrics/basic_counter_spec.rb'
92
+ - 'spec/ddmetrics/basic_summary_spec.rb'
93
+ - 'spec/ddmetrics/counter_spec.rb'
94
+ - 'spec/ddmetrics/stats_spec.rb'
95
+ - 'spec/ddmetrics/stopwatch_spec.rb'
96
+ - 'spec/ddmetrics/summary_spec.rb'
97
+ - 'spec/ddmetrics/table_spec.rb'
98
+ - 'spec/ddmetrics_spec.rb'
99
+
100
+ # Offense count: 1
101
+ # This cop supports safe autocorrection (--autocorrect).
102
+ Rake/Desc:
103
+ Exclude:
104
+ - 'Rakefile'
105
+
106
+ # Offense count: 2
107
+ # This cop supports unsafe autocorrection (--autocorrect-all).
108
+ # Configuration parameters: Mode.
109
+ Style/StringConcatenation:
110
+ Exclude:
111
+ - 'lib/ddmetrics/table.rb'
112
+ - 'scripts/release'
data/Gemfile CHANGED
@@ -5,11 +5,13 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  group :devel do
8
- gem 'codecov', require: false
9
8
  gem 'fuubar'
10
9
  gem 'rake'
11
10
  gem 'rspec'
12
11
  gem 'rspec-its'
13
- gem 'rubocop', '~> 0.52'
12
+ gem 'rubocop', '~> 1.57'
13
+ gem 'rubocop-rake', '~> 0.6.0'
14
+ gem 'rubocop-rspec', '~> 2.24'
15
+ gem 'simplecov', require: false
14
16
  gem 'timecop', '~> 0.9'
15
17
  end
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 Denis Defreyne
3
+ Copyright (c) 2017–2018 Denis Defreyne
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/NEWS.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # DDMetrics news
2
2
 
3
+ ## 1.1.0 (2023-10-31)
4
+
5
+ Features:
6
+
7
+ * Added `Stopwatch#run`
8
+
9
+ ## 1.0.1 (2018-07-19)
10
+
11
+ Enhancements:
12
+
13
+ * Improved formatting of labels in tables (#7)
14
+
3
15
  ## 1.0.0 (2018-01-07)
4
16
 
5
17
  (identical to 1.0.0rc1)
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
  [![Gem downloads](https://img.shields.io/gem/dt/ddmetrics.svg)](http://rubygems.org/gems/ddmetrics)
3
3
  [![Build status](https://img.shields.io/travis/ddfreyne/ddmetrics.svg)](https://travis-ci.org/ddfreyne/ddmetrics)
4
4
  [![Code Climate](https://img.shields.io/codeclimate/github/ddfreyne/ddmetrics.svg)](https://codeclimate.com/github/ddfreyne/ddmetrics)
5
- [![Code Coverage](https://img.shields.io/codecov/c/github/ddfreyne/ddmetrics.svg)](https://codecov.io/gh/ddfreyne/ddmetrics)
6
5
 
7
6
  # DDMetrics
8
7
 
@@ -89,11 +88,11 @@ puts cache.counter
89
88
  ```
90
89
 
91
90
  ```
92
- │ count
93
- ──────────────┼──────
94
- type=get_miss2
95
- type=set1
96
- type=get_hit 3
91
+ type │ count
92
+ ─────────┼──────
93
+ get_hit 3
94
+ get_miss2
95
+ set1
97
96
  ```
98
97
 
99
98
  ## Scope
@@ -205,10 +204,10 @@ puts summary
205
204
  Output:
206
205
 
207
206
  ```
208
- │ count min .50 .90 .95 max tot
209
- ────────────┼────────────────────────────────────────────────
210
- filter=erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
211
- filter=haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
207
+ filter │ count min .50 .90 .95 max tot
208
+ ───────┼────────────────────────────────────────────────
209
+ erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
210
+ haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
212
211
  ```
213
212
 
214
213
  ### Stopwatch
@@ -235,6 +234,25 @@ puts "That took #{stopwatch.duration}s."
235
234
  # Output: That took 2.012879s.
236
235
  ```
237
236
 
237
+ You can use `#run` with a block for convenience:
238
+
239
+ ```ruby
240
+ stopwatch.run do
241
+ sleep 1
242
+ end
243
+ ```
244
+
245
+ `#run` will return the value of the block:
246
+
247
+ ```ruby
248
+ result = stopwatch.run do
249
+ sleep 1
250
+ 'Donkey'
251
+ end
252
+ puts result
253
+ # Output: Donkey
254
+ ```
255
+
238
256
  You can query whether or not a stopwatch is running using `#running?`; `#stopped?` is the opposite of `#running?`.
239
257
 
240
258
  ## Development
data/ddmetrics.gemspec CHANGED
@@ -16,4 +16,5 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0")
18
18
  spec.require_paths = ['lib']
19
+ spec.metadata['rubygems_mfa_required'] = 'true'
19
20
  end
@@ -30,6 +30,7 @@ module DDMetrics
30
30
  # @api private
31
31
  def validate_label(label)
32
32
  return if label.is_a?(Hash)
33
+
33
34
  raise ArgumentError, 'label argument must be a hash'
34
35
  end
35
36
  end
@@ -3,23 +3,21 @@
3
3
  module DDMetrics
4
4
  class Printer
5
5
  def summary_to_s(summary)
6
- DDMetrics::Table.new(table_for_summary(summary)).to_s
6
+ table_for_summary(summary).to_s
7
7
  end
8
8
 
9
9
  def counter_to_s(counter)
10
- DDMetrics::Table.new(table_for_counter(counter)).to_s
10
+ table_for_counter(counter).to_s
11
11
  end
12
12
 
13
13
  private
14
14
 
15
- def label_to_s(label)
16
- label.to_a.sort.map { |pair| pair.join('=') }.join(' ')
17
- end
18
-
19
15
  def table_for_summary(summary)
20
- headers = ['', 'count', 'min', '.50', '.90', '.95', 'max', 'tot']
16
+ header_labels = nil
17
+ headers = ['count', 'min', '.50', '.90', '.95', 'max', 'tot']
21
18
 
22
19
  rows = summary.labels.map do |label|
20
+ header_labels ||= label.to_a.sort.map(&:first).map(&:to_s)
23
21
  stats = summary.get(label)
24
22
 
25
23
  count = stats.count
@@ -30,20 +28,22 @@ module DDMetrics
30
28
  tot = stats.sum
31
29
  max = stats.max
32
30
 
33
- [label_to_s(label), count.to_s] + [min, p50, p90, p95, max, tot].map { |r| format('%4.2f', r) }
31
+ label.to_a.sort.map(&:last).map(&:to_s) + [count.to_s] + [min, p50, p90, p95, max, tot].map { |r| format('%4.2f', r) }
34
32
  end
35
33
 
36
- [headers] + rows
34
+ DDMetrics::Table.new([header_labels + headers] + rows, num_headers: header_labels.size)
37
35
  end
38
36
 
39
37
  def table_for_counter(counter)
40
- headers = ['', 'count']
38
+ header_labels = nil
39
+ headers = ['count']
41
40
 
42
41
  rows = counter.labels.map do |label|
43
- [label_to_s(label), counter.get(label).to_s]
42
+ header_labels ||= label.to_a.sort.map(&:first).map(&:to_s)
43
+ label.to_a.sort.map(&:last).map(&:to_s) + [counter.get(label).to_s]
44
44
  end
45
45
 
46
- [headers] + rows
46
+ DDMetrics::Table.new([header_labels + headers] + rows, num_headers: header_labels.size)
47
47
  end
48
48
  end
49
49
  end
@@ -22,6 +22,7 @@ module DDMetrics
22
22
 
23
23
  def sum
24
24
  raise EmptyError if @values.empty?
25
+
25
26
  @values.reduce(:+)
26
27
  end
27
28
 
@@ -42,7 +43,7 @@ module DDMetrics
42
43
 
43
44
  target = (@values.size - 1) * fraction.to_f
44
45
  interp = target % 1.0
45
- sorted_values[target.floor] * (1.0 - interp) + sorted_values[target.ceil] * interp
46
+ (sorted_values[target.floor] * (1.0 - interp)) + (sorted_values[target.ceil] * interp)
46
47
  end
47
48
 
48
49
  private
@@ -2,6 +2,8 @@
2
2
 
3
3
  module DDMetrics
4
4
  class Stopwatch
5
+ NANOS_PER_SECOND = 1_000_000_000
6
+
5
7
  class AlreadyRunningError < StandardError
6
8
  def message
7
9
  'Cannot start, because stopwatch is already running'
@@ -21,24 +23,34 @@ module DDMetrics
21
23
  end
22
24
 
23
25
  def initialize
24
- @duration = 0.0
26
+ @duration = 0
25
27
  @last_start = nil
26
28
  end
27
29
 
30
+ def run
31
+ start
32
+ yield
33
+ ensure
34
+ stop
35
+ end
36
+
28
37
  def start
29
38
  raise AlreadyRunningError if running?
30
- @last_start = Time.now
39
+
40
+ @last_start = nanos_now
31
41
  end
32
42
 
33
43
  def stop
34
44
  raise NotRunningError unless running?
35
- @duration += (Time.now - @last_start)
45
+
46
+ @duration += (nanos_now - @last_start)
36
47
  @last_start = nil
37
48
  end
38
49
 
39
50
  def duration
40
51
  raise StillRunningError if running?
41
- @duration
52
+
53
+ @duration.to_f / NANOS_PER_SECOND
42
54
  end
43
55
 
44
56
  def running?
@@ -48,5 +60,11 @@ module DDMetrics
48
60
  def stopped?
49
61
  !running?
50
62
  end
63
+
64
+ private
65
+
66
+ def nanos_now
67
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
68
+ end
51
69
  end
52
70
  end
@@ -2,8 +2,9 @@
2
2
 
3
3
  module DDMetrics
4
4
  class Table
5
- def initialize(rows)
5
+ def initialize(rows, num_headers: 1)
6
6
  @rows = rows
7
+ @num_headers = num_headers
7
8
  end
8
9
 
9
10
  def to_s
@@ -11,8 +12,13 @@ module DDMetrics
11
12
  column_lengths = columns.map { |c| c.map(&:size).max }
12
13
 
13
14
  [].tap do |lines|
15
+ # header
14
16
  lines << row_to_s(@rows[0], column_lengths)
17
+
18
+ # separator
15
19
  lines << separator(column_lengths)
20
+
21
+ # body
16
22
  rows = sort_rows(@rows.drop(1))
17
23
  lines.concat(rows.map { |r| row_to_s(r, column_lengths) })
18
24
  end.join("\n")
@@ -26,14 +32,14 @@ module DDMetrics
26
32
 
27
33
  def row_to_s(row, column_lengths)
28
34
  values = row.zip(column_lengths).map { |text, length| text.rjust(length) }
29
- values[0] + ' │ ' + values[1..-1].join(' ')
35
+ values.take(@num_headers).join(' ') + ' │ ' + values.drop(@num_headers).join(' ')
30
36
  end
31
37
 
32
38
  def separator(column_lengths)
33
39
  (+'').tap do |s|
34
- s << '─' * column_lengths[0]
40
+ s << column_lengths.take(@num_headers).map { |l| '─' * l }.join('───')
35
41
  s << '─┼─'
36
- s << column_lengths[1..-1].map { |l| '─' * l }.join('───')
42
+ s << column_lengths.drop(@num_headers).map { |l| '─' * l }.join('───')
37
43
  end
38
44
  end
39
45
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DDMetrics
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
@@ -97,10 +97,10 @@ describe DDMetrics::Counter do
97
97
 
98
98
  it 'returns table' do
99
99
  expected = <<~TABLE
100
- │ count
101
- ────────────┼──────
102
- filter=erb │ 2
103
- filter=haml │ 1
100
+ filter │ count
101
+ ───────┼──────
102
+ erb │ 2
103
+ haml │ 1
104
104
  TABLE
105
105
 
106
106
  expect(subject.strip).to eq(expected.strip)
@@ -10,29 +10,51 @@ describe DDMetrics::Stopwatch do
10
10
  end
11
11
 
12
12
  it 'records correct duration after start+stop' do
13
- Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
14
13
  stopwatch.start
15
-
16
- Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
14
+ sleep 0.1
17
15
  stopwatch.stop
18
16
 
19
- expect(stopwatch.duration).to eq(1.0)
17
+ expect(stopwatch.duration).to be_within(0.01).of(0.1)
20
18
  end
21
19
 
22
20
  it 'records correct duration after start+stop+start+stop' do
23
- Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
24
21
  stopwatch.start
25
-
26
- Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
22
+ sleep 0.1
27
23
  stopwatch.stop
28
-
29
- Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 3))
24
+ sleep 0.1
30
25
  stopwatch.start
31
-
32
- Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 6))
26
+ sleep 0.1
33
27
  stopwatch.stop
34
28
 
35
- expect(stopwatch.duration).to eq(1.0 + 3.0)
29
+ expect(stopwatch.duration).to be_within(0.02).of(0.2)
30
+ end
31
+
32
+ it 'records correct duration with single #run call' do
33
+ stopwatch.run do
34
+ sleep 0.1
35
+ end
36
+
37
+ expect(stopwatch.duration).to be_within(0.01).of(0.1)
38
+ end
39
+
40
+ it 'records correct duration with multiple #run calls' do
41
+ stopwatch.run do
42
+ sleep 0.1
43
+ end
44
+ stopwatch.run do
45
+ sleep 0.2
46
+ end
47
+
48
+ expect(stopwatch.duration).to be_within(0.03).of(0.3)
49
+ end
50
+
51
+ it 'returns the right value from a #run call' do
52
+ result = stopwatch.run do
53
+ sleep 0.1
54
+ 'donkey'
55
+ end
56
+
57
+ expect(result).to eq('donkey')
36
58
  end
37
59
 
38
60
  it 'errors when stopping when not started' do
@@ -64,21 +64,44 @@ describe DDMetrics::Summary do
64
64
  describe '#to_s' do
65
65
  subject { summary.to_s }
66
66
 
67
- before do
68
- summary.observe(2.1, filter: :erb)
69
- summary.observe(4.1, filter: :erb)
70
- summary.observe(5.3, filter: :haml)
67
+ context 'one label' do
68
+ before do
69
+ summary.observe(2.1, filter: :erb)
70
+ summary.observe(4.1, filter: :erb)
71
+ summary.observe(5.3, filter: :haml)
72
+ end
73
+
74
+ it 'returns table' do
75
+ expected = <<~TABLE
76
+ filter │ count min .50 .90 .95 max tot
77
+ ───────┼────────────────────────────────────────────────
78
+ erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
79
+ haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
80
+ TABLE
81
+
82
+ expect(subject.strip).to eq(expected.strip)
83
+ end
71
84
  end
72
85
 
73
- it 'returns table' do
74
- expected = <<~TABLE
75
- │ count min .50 .90 .95 max tot
76
- ────────────┼────────────────────────────────────────────────
77
- filter=erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
78
- filter=haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
79
- TABLE
86
+ context 'multiple labels' do
87
+ before do
88
+ summary.observe(2.1, filter: :erb, stage: :pre)
89
+ summary.observe(4.1, filter: :erb, stage: :pre)
90
+ summary.observe(1.2, filter: :erb, stage: :post)
91
+ summary.observe(5.3, filter: :haml, stage: :post)
92
+ end
80
93
 
81
- expect(subject.strip).to eq(expected.strip)
94
+ it 'returns table' do
95
+ expected = <<~TABLE
96
+ filter stage │ count min .50 .90 .95 max tot
97
+ ───────────────┼────────────────────────────────────────────────
98
+ erb pre │ 2 2.10 3.10 3.90 4.00 4.10 6.20
99
+ erb post │ 1 1.20 1.20 1.20 1.20 1.20 1.20
100
+ haml post │ 1 5.30 5.30 5.30 5.30 5.30 5.30
101
+ TABLE
102
+
103
+ expect(subject.strip).to eq(expected.strip)
104
+ end
82
105
  end
83
106
  end
84
107
  end
data/spec/spec_helper.rb CHANGED
@@ -3,9 +3,6 @@
3
3
  require 'simplecov'
4
4
  SimpleCov.start
5
5
 
6
- require 'codecov'
7
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
8
-
9
6
  require 'ddmetrics'
10
7
 
11
8
  require 'fuubar'
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddmetrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-07 00:00:00.000000000 Z
11
+ date: 2023-10-31 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description:
13
+ description:
14
14
  email:
15
15
  - denis+rubygems@denis.ws
16
16
  executables: []
@@ -20,6 +20,7 @@ files:
20
20
  - ".gitignore"
21
21
  - ".rspec"
22
22
  - ".rubocop.yml"
23
+ - ".rubocop_todo.yml"
23
24
  - ".travis.yml"
24
25
  - CODE_OF_CONDUCT.md
25
26
  - Gemfile
@@ -53,8 +54,9 @@ files:
53
54
  homepage: https://github.com/ddfreyne/ddmetrics
54
55
  licenses:
55
56
  - MIT
56
- metadata: {}
57
- post_install_message:
57
+ metadata:
58
+ rubygems_mfa_required: 'true'
59
+ post_install_message:
58
60
  rdoc_options: []
59
61
  require_paths:
60
62
  - lib
@@ -69,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
71
  - !ruby/object:Gem::Version
70
72
  version: '0'
71
73
  requirements: []
72
- rubyforge_project:
73
- rubygems_version: 2.7.4
74
- signing_key:
74
+ rubygems_version: 3.4.21
75
+ signing_key:
75
76
  specification_version: 4
76
77
  summary: Non-timeseries measurements for Ruby programs
77
78
  test_files: []