leafy 0.0.3 → 0.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.
@@ -0,0 +1,5 @@
1
+ module Leafy
2
+ module Core
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
data/puma.rb ADDED
@@ -0,0 +1,22 @@
1
+ # https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server
2
+
3
+ workers Integer(ENV['WEB_CONCURRENCY'] || 2)
4
+ threads_count = Integer(ENV['MAX_THREADS'] || 5)
5
+ threads threads_count, threads_count
6
+
7
+ preload_app!
8
+
9
+ rackup DefaultRackup
10
+ environment ENV['RACK_ENV'] || 'development'
11
+
12
+ on_worker_boot do |index|
13
+ require 'leafy/core/console_reporter'
14
+ # global $registry is set by the master process when preloading app
15
+ reporter = Leafy::Core::ConsoleReporter::Builder.for_registry($registry) do
16
+ output_to STDERR
17
+ shutdown_executor_on_stop true
18
+ end
19
+ offset = 10 / @options[:workers]
20
+ reporter.start((index + 1) * offset, 10) # report every 10 seconds
21
+ puts("started: #{reporter}\n")
22
+ end
@@ -0,0 +1,362 @@
1
+ require 'leafy/core/console_reporter'
2
+
3
+ RSpec.describe Leafy::Core::ConsoleReporter do
4
+
5
+ let(:output) { StringIO.new }
6
+ let(:registry) { double(Leafy::Core::MetricRegistry) }
7
+
8
+ let(:clock) do
9
+ clock = double(Leafy::Core::Clock)
10
+ allow(clock).to receive(:time).and_return(1363568676000)
11
+ clock
12
+ end
13
+
14
+ let(:reporter) do
15
+ Leafy::Core::ConsoleReporter::Builder
16
+ .for_registry(registry)
17
+ .output_to(output)
18
+ .with_clock(clock)
19
+ .build
20
+ end
21
+
22
+ it 'reportsGaugeValues' do
23
+ gauge = Leafy::Core::Gauge.new { 1 }
24
+
25
+ reporter.do_report({"gauge" => gauge},
26
+ {},
27
+ {},
28
+ {},
29
+ {})
30
+
31
+ expect(output.string).to eq [
32
+ "1970-01-16 18:46:08 UTC ========================================================",
33
+ "",
34
+ "-- Gauges ----------------------------------------------------------------------",
35
+ "gauge",
36
+ " value = 1",
37
+ "",
38
+ "",
39
+ ""
40
+ ].join("\n")
41
+ end
42
+
43
+
44
+ it 'reportsCounterValues' do
45
+ counter = double(Leafy::Core::Counter.class)
46
+ allow(counter).to receive(:count).and_return(100)
47
+
48
+ reporter.do_report({},
49
+ {"test.counter" => counter},
50
+ {},
51
+ {},
52
+ {})
53
+
54
+ expect(output.string).to eq [
55
+ "1970-01-16 18:46:08 UTC ========================================================",
56
+ "",
57
+ "-- Counters --------------------------------------------------------------------",
58
+ "test.counter",
59
+ " count = 100",
60
+ "",
61
+ "",
62
+ ""
63
+ ].join("\n")
64
+ end
65
+
66
+
67
+ it 'reportsHistogramValues' do
68
+ histogram = double(Leafy::Core::Histogram.class)
69
+ allow(histogram).to receive(:count).and_return(1)
70
+
71
+ snapshot = double(Leafy::Core::Snapshot.class)
72
+ allow(snapshot).to receive(:max).and_return(2)
73
+ allow(snapshot).to receive(:mean).and_return(3.0)
74
+ allow(snapshot).to receive(:min).and_return(4)
75
+ allow(snapshot).to receive(:std_dev).and_return(5.0)
76
+ allow(snapshot).to receive(:median).and_return(6.0)
77
+ allow(snapshot).to receive(:get_75th_percentile).and_return(7.0)
78
+ allow(snapshot).to receive(:get_95th_percentile).and_return(8.0)
79
+ allow(snapshot).to receive(:get_98th_percentile).and_return(9.0)
80
+ allow(snapshot).to receive(:get_99th_percentile).and_return(10.0)
81
+ allow(snapshot).to receive(:get_999th_percentile).and_return(11.0)
82
+
83
+ allow(histogram).to receive(:snapshot).and_return(snapshot)
84
+
85
+ reporter.do_report({},
86
+ {},
87
+ {"test.histogram" => histogram},
88
+ {},
89
+ {})
90
+
91
+ expect(output.string).to eq [
92
+ "1970-01-16 18:46:08 UTC ========================================================",
93
+ "",
94
+ "-- Histograms ------------------------------------------------------------------",
95
+ "test.histogram",
96
+ " count = 1",
97
+ " min = 4",
98
+ " max = 2",
99
+ " mean = 3.00",
100
+ " stddev = 5.00",
101
+ " median = 6.00",
102
+ " 75% <= 7.00",
103
+ " 95% <= 8.00",
104
+ " 98% <= 9.00",
105
+ " 99% <= 10.00",
106
+ " 99.9% <= 11.00",
107
+ "",
108
+ "",
109
+ ""
110
+ ].join("\n")
111
+ end
112
+
113
+
114
+ it 'reportsMeterValues' do
115
+ meter = double(Leafy::Core::Meter.class)
116
+ allow(meter).to receive(:count).and_return(1)
117
+ allow(meter).to receive(:mean_rate).and_return(2.0)
118
+ allow(meter).to receive(:one_minute_rate).and_return(3.0)
119
+ allow(meter).to receive(:five_minute_rate).and_return(4.0)
120
+ allow(meter).to receive(:fifteen_minute_rate).and_return(5.0)
121
+
122
+ reporter.do_report({},
123
+ {},
124
+ {},
125
+ {"test.meter" => meter},
126
+ {})
127
+
128
+ expect(output.string).to eq [
129
+ "1970-01-16 18:46:08 UTC ========================================================",
130
+ "",
131
+ "-- Meters ----------------------------------------------------------------------",
132
+ "test.meter",
133
+ " count = 1",
134
+ " mean rate = 2.00 events/second",
135
+ " 1-minute rate = 3.00 events/second",
136
+ " 5-minute rate = 4.00 events/second",
137
+ " 15-minute rate = 5.00 events/second",
138
+ "",
139
+ "",
140
+ ""
141
+ ].join("\n")
142
+ end
143
+
144
+
145
+ it 'reportsTimerValues' do
146
+ timer = double(Leafy::Core::Timer.class)
147
+ allow(timer).to receive(:count).and_return(1)
148
+ allow(timer).to receive(:mean_rate).and_return(2.0)
149
+ allow(timer).to receive(:one_minute_rate).and_return(3.0)
150
+ allow(timer).to receive(:five_minute_rate).and_return(4.0)
151
+ allow(timer).to receive(:fifteen_minute_rate).and_return(5.0)
152
+
153
+ snapshot = double(Leafy::Core::Snapshot.class)
154
+ allow(snapshot).to receive(:max).and_return(100000000)
155
+ allow(snapshot).to receive(:mean).and_return(200000000.0)
156
+ allow(snapshot).to receive(:min).and_return(300000000.0)
157
+ allow(snapshot).to receive(:std_dev).and_return(400000000.0)
158
+ allow(snapshot).to receive(:median).and_return(500000000.0)
159
+ allow(snapshot).to receive(:get_75th_percentile).and_return(600000000.0)
160
+ allow(snapshot).to receive(:get_95th_percentile).and_return(700000000.0)
161
+ allow(snapshot).to receive(:get_98th_percentile).and_return(800000000.0)
162
+ allow(snapshot).to receive(:get_99th_percentile).and_return(900000000.0)
163
+ allow(snapshot).to receive(:get_999th_percentile).and_return(1000000000.0)
164
+
165
+ allow(timer).to receive(:snapshot).and_return(snapshot)
166
+
167
+ reporter.do_report({},
168
+ {},
169
+ {},
170
+ {},
171
+ {"test.another.timer" => timer})
172
+
173
+ expect(output.string).to eq [
174
+ "1970-01-16 18:46:08 UTC ========================================================",
175
+ "",
176
+ "-- Timers ----------------------------------------------------------------------",
177
+ "test.another.timer",
178
+ " count = 1",
179
+ " mean rate = 2.00 calls/second",
180
+ " 1-minute rate = 3.00 calls/second",
181
+ " 5-minute rate = 4.00 calls/second",
182
+ " 15-minute rate = 5.00 calls/second",
183
+ " min = 300.00 milliseconds",
184
+ " max = 100.00 milliseconds",
185
+ " mean = 200.00 milliseconds",
186
+ " stddev = 400.00 milliseconds",
187
+ " median = 500.00 milliseconds",
188
+ " 75% <= 600.00 milliseconds",
189
+ " 95% <= 700.00 milliseconds",
190
+ " 98% <= 800.00 milliseconds",
191
+ " 99% <= 900.00 milliseconds",
192
+ " 99.9% <= 1000.00 milliseconds",
193
+ "",
194
+ "",
195
+ ""
196
+ ].join("\n")
197
+ end
198
+
199
+
200
+ # it 'reportMeterWithDisabledAttributes' do
201
+ # Set<MetricAttribute> disabledMetricAttributes = EnumSet.of(MetricAttribute.M15_RATE, MetricAttribute.M5_RATE, MetricAttribute.COUNT)
202
+
203
+ # final ConsoleReporter customReporter = ConsoleReporter.forRegistry(registry)
204
+ # .outputTo(output)
205
+ # .formattedFor(locale)
206
+ # .withClock(clock)
207
+ # .formattedFor(timeZone)
208
+ # .convertRatesTo(TimeUnit.SECONDS)
209
+ # .convertDurationsTo(TimeUnit.MILLISECONDS)
210
+ # .filter(MetricFilter.ALL)
211
+ # .disabledMetricAttributes(disabledMetricAttributes)
212
+ # .build()
213
+
214
+ # final Meter meter = double(Meter.class)
215
+ # when(meter).to receive(:Count()).and_return(1L)
216
+ # when(meter).to receive(:MeanRate()).and_return(2.0)
217
+ # when(meter).to receive(:OneMinuteRate()).and_return(3.0)
218
+ # when(meter).to receive(:FiveMinuteRate()).and_return(4.0)
219
+ # when(meter).to receive(:FifteenMinuteRate()).and_return(5.0)
220
+
221
+ # customReporter.report({},
222
+ # {},
223
+ # {},
224
+ # {"test.meter" => meter),
225
+ # {})
226
+
227
+ # expect(output.string).to eq
228
+ # [
229
+ # "3/17/13 6:04:36 PM =============================================================",
230
+ # "",
231
+ # "-- Meters ----------------------------------------------------------------------",
232
+ # "test.meter",
233
+ # " mean rate = 2.00 events/second",
234
+ # " 1-minute rate = 3.00 events/second",
235
+ # "",
236
+ # ""
237
+ # ].join("\n")
238
+ # }
239
+
240
+
241
+ # it 'reportTimerWithDisabledAttributes' do
242
+ # Set<MetricAttribute> disabledMetricAttributes = EnumSet.of(MetricAttribute.P50, MetricAttribute.P999, MetricAttribute.M5_RATE, MetricAttribute.MAX)
243
+
244
+ # final ConsoleReporter customReporter = ConsoleReporter.forRegistry(registry)
245
+ # .outputTo(output)
246
+ # .formattedFor(locale)
247
+ # .withClock(clock)
248
+ # .formattedFor(timeZone)
249
+ # .convertRatesTo(TimeUnit.SECONDS)
250
+ # .convertDurationsTo(TimeUnit.MILLISECONDS)
251
+ # .filter(MetricFilter.ALL)
252
+ # .disabledMetricAttributes(disabledMetricAttributes)
253
+ # .build()
254
+
255
+ # final Timer timer = double(Timer.class)
256
+ # when(timer).to receive(:Count()).and_return(1L)
257
+ # when(timer).to receive(:MeanRate()).and_return(2.0)
258
+ # when(timer).to receive(:OneMinuteRate()).and_return(3.0)
259
+ # when(timer).to receive(:FiveMinuteRate()).and_return(4.0)
260
+ # when(timer).to receive(:FifteenMinuteRate()).and_return(5.0)
261
+
262
+ # final Snapshot snapshot = double(Snapshot.class)
263
+ # when(snapshot).to receive(:Max()).and_return(TimeUnit.MILLISECONDS.toNanos(100))
264
+ # when(snapshot).to receive(:Mean()).and_return((double) TimeUnit.MILLISECONDS.toNanos(200))
265
+ # when(snapshot).to receive(:Min()).and_return(TimeUnit.MILLISECONDS.toNanos(300))
266
+ # when(snapshot).to receive(:StdDev()).and_return((double) TimeUnit.MILLISECONDS.toNanos(400))
267
+ # when(snapshot).to receive(:Median()).and_return((double) TimeUnit.MILLISECONDS.toNanos(500))
268
+ # when(snapshot).to receive(:75thPercentile()).and_return((double) TimeUnit.MILLISECONDS.toNanos(600))
269
+ # when(snapshot).to receive(:95thPercentile()).and_return((double) TimeUnit.MILLISECONDS.toNanos(700))
270
+ # when(snapshot).to receive(:98thPercentile()).and_return((double) TimeUnit.MILLISECONDS.toNanos(800))
271
+ # when(snapshot).to receive(:99thPercentile()).and_return((double) TimeUnit.MILLISECONDS.toNanos(900))
272
+ # when(snapshot).to receive(:999thPercentile()).and_return((double) TimeUnit.MILLISECONDS
273
+ # .toNanos(1000))
274
+
275
+ # when(timer).to receive(:Snapshot()).and_return(snapshot)
276
+
277
+ # customReporter.report({},
278
+ # {},
279
+ # {},
280
+ # {},
281
+ # {"test.another.timer" => timer})
282
+
283
+ # expect(output.string).to eq
284
+ # [
285
+ # "3/17/13 6:04:36 PM =============================================================",
286
+ # "",
287
+ # "-- Timers ----------------------------------------------------------------------",
288
+ # "test.another.timer",
289
+ # " count = 1",
290
+ # " mean rate = 2.00 calls/second",
291
+ # " 1-minute rate = 3.00 calls/second",
292
+ # " 15-minute rate = 5.00 calls/second",
293
+ # " min = 300.00 milliseconds",
294
+ # " mean = 200.00 milliseconds",
295
+ # " stddev = 400.00 milliseconds",
296
+ # " 75% <= 600.00 milliseconds",
297
+ # " 95% <= 700.00 milliseconds",
298
+ # " 98% <= 800.00 milliseconds",
299
+ # " 99% <= 900.00 milliseconds",
300
+ # "",
301
+ # ""
302
+ # ].join("\n")
303
+ # }
304
+
305
+
306
+ # it 'reportHistogramWithDisabledAttributes' do
307
+ # Set<MetricAttribute> disabledMetricAttributes = EnumSet.of(MetricAttribute.MIN, MetricAttribute.MAX, MetricAttribute.STDDEV, MetricAttribute.P95)
308
+
309
+ # final ConsoleReporter customReporter = ConsoleReporter.forRegistry(registry)
310
+ # .outputTo(output)
311
+ # .formattedFor(locale)
312
+ # .withClock(clock)
313
+ # .formattedFor(timeZone)
314
+ # .convertRatesTo(TimeUnit.SECONDS)
315
+ # .convertDurationsTo(TimeUnit.MILLISECONDS)
316
+ # .filter(MetricFilter.ALL)
317
+ # .disabledMetricAttributes(disabledMetricAttributes)
318
+ # .build()
319
+
320
+ # final Histogram histogram = double(Histogram.class)
321
+ # when(histogram).to receive(:Count()).and_return(1L)
322
+
323
+ # final Snapshot snapshot = double(Snapshot.class)
324
+ # when(snapshot).to receive(:Max()).and_return(2L)
325
+ # when(snapshot).to receive(:Mean()).and_return(3.0)
326
+ # when(snapshot).to receive(:Min()).and_return(4L)
327
+ # when(snapshot).to receive(:StdDev()).and_return(5.0)
328
+ # when(snapshot).to receive(:Median()).and_return(6.0)
329
+ # when(snapshot).to receive(:75thPercentile()).and_return(7.0)
330
+ # when(snapshot).to receive(:95thPercentile()).and_return(8.0)
331
+ # when(snapshot).to receive(:98thPercentile()).and_return(9.0)
332
+ # when(snapshot).to receive(:99thPercentile()).and_return(10.0)
333
+ # when(snapshot).to receive(:999thPercentile()).and_return(11.0)
334
+
335
+ # when(histogram).to receive(:Snapshot()).and_return(snapshot)
336
+
337
+ # customReporter.report({},
338
+ # {},
339
+ # {"test.histogram" => histogram},
340
+ # {},
341
+ # {})
342
+
343
+ # expect(output.string).to eq
344
+ # [
345
+ # "3/17/13 6:04:36 PM =============================================================",
346
+ # "",
347
+ # "-- Histograms ------------------------------------------------------------------",
348
+ # "test.histogram",
349
+ # " count = 1",
350
+ # " mean = 3.00",
351
+ # " median = 6.00",
352
+ # " 75% <= 7.00",
353
+ # " 98% <= 9.00",
354
+ # " 99% <= 10.00",
355
+ # " 99.9% <= 11.00",
356
+ # "",
357
+ # ""
358
+ # ].join("\n")
359
+ # }
360
+
361
+
362
+ end
@@ -0,0 +1,50 @@
1
+ require 'leafy/core/counter'
2
+
3
+ RSpec.describe Leafy::Core::Counter do
4
+
5
+ it 'starts at zero' do
6
+ expect(subject.count).to eq 0
7
+ end
8
+
9
+
10
+ it 'incrementsByOne' do
11
+ subject.inc
12
+
13
+ expect(subject.count).to eq 1
14
+ end
15
+
16
+
17
+ it 'incrementsByAnArbitraryDelta' do
18
+ subject.inc(12)
19
+
20
+ expect(subject.count).to eq 12
21
+ end
22
+
23
+
24
+ it 'decrementsByOne' do
25
+ subject.dec
26
+
27
+ expect(subject.count).to eq -1
28
+ end
29
+
30
+
31
+ it 'decrementsByAnArbitraryDelta' do
32
+ subject.dec(12)
33
+
34
+ expect(subject.count).to eq -12
35
+ end
36
+
37
+
38
+ it 'incrementByNegativeDelta' do
39
+ subject.inc(-12)
40
+
41
+ expect(subject.count).to eq -12
42
+ end
43
+
44
+
45
+ it 'decrementByNegativeDelta' do
46
+ subject.dec(-12)
47
+
48
+ expect(subject.count).to eq 12
49
+ end
50
+ end
@@ -0,0 +1,208 @@
1
+ require 'leafy/core/ewma'
2
+
3
+ RSpec.describe Leafy::Core::EWMA do
4
+
5
+ it 'a one minute EWMA with a value of three' do
6
+ ewma = Leafy::Core::EWMA.oneMinuteEWMA
7
+ ewma.update(3)
8
+ ewma.tick
9
+
10
+ expect(Number[ewma.rate]).to eql(Number[0.6, 0.000001])
11
+
12
+ 12.times { ewma.tick }
13
+
14
+ expect(Number[ewma.rate]).to eql(Number[0.22072766, 0.000001])
15
+
16
+ 12.times { ewma.tick }
17
+
18
+ expect(Number[ewma.rate]).to eql(Number[0.08120117, 0.000001])
19
+
20
+ 12.times { ewma.tick }
21
+
22
+ expect(Number[ewma.rate]).to eql(Number[0.02987224, 0.000001])
23
+
24
+ 12.times { ewma.tick }
25
+
26
+ expect(Number[ewma.rate]).to eql(Number[0.01098938, 0.000001])
27
+
28
+ 12.times { ewma.tick }
29
+
30
+ expect(Number[ewma.rate]).to eql(Number[0.00404277, 0.000001])
31
+
32
+ 12.times { ewma.tick }
33
+
34
+ expect(Number[ewma.rate]).to eql(Number[0.00148725, 0.000001])
35
+
36
+ 12.times { ewma.tick }
37
+
38
+ expect(Number[ewma.rate]).to eql(Number[0.00054713, 0.000001])
39
+
40
+ 12.times { ewma.tick }
41
+
42
+ expect(Number[ewma.rate]).to eql(Number[0.00020128, 0.000001])
43
+
44
+ 12.times { ewma.tick }
45
+
46
+ expect(Number[ewma.rate]).to eql(Number[0.00007405, 0.000001])
47
+
48
+ 12.times { ewma.tick }
49
+
50
+ expect(Number[ewma.rate]).to eql(Number[0.00002724, 0.000001])
51
+
52
+ 12.times { ewma.tick }
53
+
54
+ expect(Number[ewma.rate]).to eql(Number[0.00001002, 0.000001])
55
+
56
+ 12.times { ewma.tick }
57
+
58
+ expect(Number[ewma.rate]).to eql(Number[0.00000369, 0.000001])
59
+
60
+ 12.times { ewma.tick }
61
+
62
+ expect(Number[ewma.rate]).to eql(Number[0.00000136, 0.000001])
63
+
64
+ 12.times { ewma.tick }
65
+
66
+ expect(Number[ewma.rate]).to eql(Number[0.00000050, 0.000001])
67
+
68
+ 12.times { ewma.tick }
69
+
70
+ expect(Number[ewma.rate]).to eql(Number[0.00000018, 0.000001])
71
+ end
72
+
73
+ it 'a five minute EWMA with a value of three' do
74
+ ewma = Leafy::Core::EWMA.fiveMinuteEWMA
75
+ ewma.update(3)
76
+ ewma.tick
77
+
78
+ expect(Number[ewma.rate]).to eql(Number[0.6, 0.000001])
79
+
80
+ 12.times { ewma.tick }
81
+
82
+ expect(Number[ewma.rate]).to eql(Number[0.49123845, 0.000001])
83
+
84
+ 12.times { ewma.tick }
85
+
86
+ expect(Number[ewma.rate]).to eql(Number[0.40219203, 0.000001])
87
+
88
+ 12.times { ewma.tick }
89
+
90
+ expect(Number[ewma.rate]).to eql(Number[0.32928698, 0.000001])
91
+
92
+ 12.times { ewma.tick }
93
+
94
+ expect(Number[ewma.rate]).to eql(Number[0.26959738, 0.000001])
95
+
96
+ 12.times { ewma.tick }
97
+
98
+ expect(Number[ewma.rate]).to eql(Number[0.22072766, 0.000001])
99
+
100
+ 12.times { ewma.tick }
101
+
102
+ expect(Number[ewma.rate]).to eql(Number[0.18071653, 0.000001])
103
+
104
+ 12.times { ewma.tick }
105
+
106
+ expect(Number[ewma.rate]).to eql(Number[0.14795818, 0.000001])
107
+
108
+ 12.times { ewma.tick }
109
+
110
+ expect(Number[ewma.rate]).to eql(Number[0.12113791, 0.000001])
111
+
112
+ 12.times { ewma.tick }
113
+
114
+ expect(Number[ewma.rate]).to eql(Number[0.09917933, 0.000001])
115
+
116
+ 12.times { ewma.tick }
117
+
118
+ expect(Number[ewma.rate]).to eql(Number[0.08120117, 0.000001])
119
+
120
+ 12.times { ewma.tick }
121
+
122
+ expect(Number[ewma.rate]).to eql(Number[0.06648190, 0.000001])
123
+
124
+ 12.times { ewma.tick }
125
+
126
+ expect(Number[ewma.rate]).to eql(Number[0.05443077, 0.000001])
127
+
128
+ 12.times { ewma.tick }
129
+
130
+ expect(Number[ewma.rate]).to eql(Number[0.04456415, 0.000001])
131
+
132
+ 12.times { ewma.tick }
133
+
134
+ expect(Number[ewma.rate]).to eql(Number[0.03648604, 0.000001])
135
+
136
+ 12.times { ewma.tick }
137
+
138
+ expect(Number[ewma.rate]).to eql(Number[0.02987224, 0.000001])
139
+ end
140
+
141
+ it 'a fifteen minute EWMA with a value of three' do
142
+ ewma = Leafy::Core::EWMA.fifteenMinuteEWMA
143
+ ewma.update(3)
144
+ ewma.tick
145
+
146
+ expect(Number[ewma.rate]).to eql(Number[0.6, 0.000001])
147
+
148
+ 12.times { ewma.tick }
149
+
150
+ expect(Number[ewma.rate]).to eql(Number[0.56130419, 0.000001])
151
+
152
+ 12.times { ewma.tick }
153
+
154
+ expect(Number[ewma.rate]).to eql(Number[0.52510399, 0.000001])
155
+
156
+ 12.times { ewma.tick }
157
+
158
+ expect(Number[ewma.rate]).to eql(Number[0.49123845, 0.000001])
159
+
160
+ 12.times { ewma.tick }
161
+
162
+ expect(Number[ewma.rate]).to eql(Number[0.45955700, 0.000001])
163
+
164
+ 12.times { ewma.tick }
165
+
166
+ expect(Number[ewma.rate]).to eql(Number[0.42991879, 0.000001])
167
+
168
+ 12.times { ewma.tick }
169
+
170
+ expect(Number[ewma.rate]).to eql(Number[0.40219203, 0.000001])
171
+
172
+ 12.times { ewma.tick }
173
+
174
+ expect(Number[ewma.rate]).to eql(Number[0.37625345, 0.000001])
175
+
176
+ 12.times { ewma.tick }
177
+
178
+ expect(Number[ewma.rate]).to eql(Number[0.35198773, 0.000001])
179
+
180
+ 12.times { ewma.tick }
181
+
182
+ expect(Number[ewma.rate]).to eql(Number[0.32928698, 0.000001])
183
+
184
+ 12.times { ewma.tick }
185
+
186
+ expect(Number[ewma.rate]).to eql(Number[0.30805027, 0.000001])
187
+
188
+ 12.times { ewma.tick }
189
+
190
+ expect(Number[ewma.rate]).to eql(Number[0.28818318, 0.000001])
191
+
192
+ 12.times { ewma.tick }
193
+
194
+ expect(Number[ewma.rate]).to eql(Number[0.26959738, 0.000001])
195
+
196
+ 12.times { ewma.tick }
197
+
198
+ expect(Number[ewma.rate]).to eql(Number[0.25221023, 0.000001])
199
+
200
+ 12.times { ewma.tick }
201
+
202
+ expect(Number[ewma.rate]).to eql(Number[0.23594443, 0.000001])
203
+
204
+ 12.times { ewma.tick }
205
+
206
+ expect(Number[ewma.rate]).to eql(Number[0.22072766, 0.000001])
207
+ end
208
+ end