pulse_meter_core 0.5.3 → 0.5.4
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 +5 -13
- data/.rbenv-version +1 -1
- data/.travis.yml +2 -0
- data/pulse_meter_core.gemspec +1 -1
- data/spec/pulse_meter/command_aggregator/async_spec.rb +14 -14
- data/spec/pulse_meter/command_aggregator/sync_spec.rb +5 -5
- data/spec/pulse_meter/command_aggregator/udp_spec.rb +8 -8
- data/spec/pulse_meter/mixins/dumper_spec.rb +27 -27
- data/spec/pulse_meter/mixins/utils_spec.rb +64 -64
- data/spec/pulse_meter/observer/extended_spec.rb +20 -20
- data/spec/pulse_meter/observer_spec.rb +26 -26
- data/spec/pulse_meter/sensor/base_spec.rb +25 -25
- data/spec/pulse_meter/sensor/configuration_spec.rb +21 -21
- data/spec/pulse_meter/sensor/counter_spec.rb +12 -12
- data/spec/pulse_meter/sensor/hashed_counter_spec.rb +9 -9
- data/spec/pulse_meter/sensor/hashed_indicator_spec.rb +10 -10
- data/spec/pulse_meter/sensor/indicator_spec.rb +9 -9
- data/spec/pulse_meter/sensor/multi_spec.rb +13 -13
- data/spec/pulse_meter/sensor/timeline_spec.rb +12 -12
- data/spec/pulse_meter/sensor/timelined/multi_percentile_spec.rb +2 -2
- data/spec/pulse_meter/sensor/timelined/percentile_spec.rb +1 -1
- data/spec/pulse_meter/sensor/uniq_counter_spec.rb +5 -5
- data/spec/pulse_meter/udp_server_spec.rb +9 -9
- data/spec/pulse_meter_spec.rb +21 -21
- data/spec/shared_examples/timeline_sensor.rb +88 -88
- data/spec/shared_examples/timelined_subclass.rb +2 -2
- data/spec/spec_helper.rb +2 -0
- data/spec/support/matchers.rb +2 -2
- metadata +34 -34
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NDZkMjhlYjY1MTdmNTk3YjViYmUwMWYyZDJiMTAxZTZhNGJmNDFkYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a0c168d18d028e8af421aaf61caf93b6a9dd967b
|
4
|
+
data.tar.gz: 146d72d603274caef865142f361de8160498c46a
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NDQzODkyZDliM2JjMmM4MmYyZGQ1MjlmY2UyNzRjZWVmNDU3NjI4NGZiNTdj
|
11
|
-
ZDAzMzliZjMyNzJjNTNjMDNhOTNjYTYwODk0MzQwMmNmNDI2YWY=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
N2IyNTFlYjk3OTMyMjMwODNhMTIyOGNiYjU1MzQxOWU1NGViMTY0ZDA3OGI0
|
14
|
-
MjA1MjcyNDg1NTU3MDQ1OGMwOTdmMGRjNGM3NjU0MjllNzE3ZWUzNzdhNDlm
|
15
|
-
ZmVmNGE4OWNjNGQ2OTJlZmQxODU4NjFkYmQyM2Q3YzYxOTVkYmQ=
|
6
|
+
metadata.gz: 254f9d4029bdf4cdadb305331d77ac94896ec001a82778641560b123306ed510c408dc0917fecf696abb2b93f1f250bf454ce75381ee859916ee4da7e179507f
|
7
|
+
data.tar.gz: cc58c3a1180ebfcb10919b7dc49547e2daed741eef0daf4948482e7068ed9e2f427c4fb776950e57eb4d2338078acc00034e778730f957e1dc5a054b7fc90282
|
data/.rbenv-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.2.2
|
data/.travis.yml
CHANGED
data/pulse_meter_core.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
16
|
gem.name = "pulse_meter_core"
|
17
17
|
gem.require_paths = ["lib"]
|
18
|
-
gem.version = "0.5.
|
18
|
+
gem.version = "0.5.4"
|
19
19
|
|
20
20
|
gem.add_runtime_dependency('json')
|
21
21
|
gem.add_runtime_dependency('redis')
|
@@ -5,48 +5,48 @@ describe PulseMeter::CommandAggregator::Async do
|
|
5
5
|
let(:redis){PulseMeter.redis}
|
6
6
|
|
7
7
|
describe "#multi" do
|
8
|
-
it "
|
8
|
+
it "accumulates redis command and execute in a bulk" do
|
9
9
|
ca.multi do
|
10
10
|
ca.set("xxxx", "zzzz")
|
11
11
|
ca.set("yyyy", "zzzz")
|
12
12
|
sleep 0.1
|
13
|
-
redis.get("xxxx").
|
14
|
-
redis.get("yyyy").
|
13
|
+
expect(redis.get("xxxx")).to be_nil
|
14
|
+
expect(redis.get("yyyy")).to be_nil
|
15
15
|
end
|
16
16
|
ca.wait_for_pending_events
|
17
|
-
redis.get("xxxx").
|
18
|
-
redis.get("yyyy").
|
17
|
+
expect(redis.get("xxxx")).to eq("zzzz")
|
18
|
+
expect(redis.get("yyyy")).to eq("zzzz")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
describe "any other redis instance method" do
|
23
|
-
it "
|
23
|
+
it "is delegated to redis" do
|
24
24
|
ca.set("xxxx", "zzzz")
|
25
25
|
ca.wait_for_pending_events
|
26
|
-
redis.get("xxxx").
|
26
|
+
expect(redis.get("xxxx")).to eq("zzzz")
|
27
27
|
end
|
28
28
|
|
29
|
-
it "
|
29
|
+
it "is aggregated if queue is not overflooded" do
|
30
30
|
redis.set("x", 0)
|
31
31
|
ca.max_queue_length.times{ ca.incr("x") }
|
32
32
|
ca.wait_for_pending_events
|
33
|
-
redis.get("x").to_i.
|
33
|
+
expect(redis.get("x").to_i).to eq(ca.max_queue_length)
|
34
34
|
end
|
35
35
|
|
36
|
-
it "
|
36
|
+
it "is not aggregated if queue is overflooded" do
|
37
37
|
redis.set("x", 0)
|
38
38
|
(ca.max_queue_length * 2).times{ ca.incr("x") }
|
39
39
|
ca.wait_for_pending_events
|
40
|
-
redis.get("x").to_i.
|
40
|
+
expect(redis.get("x").to_i).to be < 2 * ca.max_queue_length
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
describe "#wait_for_pending_events" do
|
45
|
-
it "
|
45
|
+
it "pauses execution until aggregator thread sends all commands ro redis" do
|
46
46
|
ca.set("xxxx", "zzzz")
|
47
|
-
redis.get("xxxx").
|
47
|
+
expect(redis.get("xxxx")).to be_nil
|
48
48
|
ca.wait_for_pending_events
|
49
|
-
redis.get("xxxx").
|
49
|
+
expect(redis.get("xxxx")).to eq("zzzz")
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -5,20 +5,20 @@ describe PulseMeter::CommandAggregator::Sync do
|
|
5
5
|
let(:redis){PulseMeter.redis}
|
6
6
|
|
7
7
|
describe "#multi" do
|
8
|
-
it "
|
8
|
+
it "accumulates redis command and execute in a bulk" do
|
9
9
|
ca.multi do
|
10
10
|
ca.set("xxxx", "zzzz")
|
11
11
|
ca.set("yyyy", "zzzz")
|
12
12
|
end
|
13
|
-
redis.get("xxxx").
|
14
|
-
redis.get("yyyy").
|
13
|
+
expect(redis.get("xxxx")).to eq("zzzz")
|
14
|
+
expect(redis.get("yyyy")).to eq("zzzz")
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
describe "any other redis instance method" do
|
19
|
-
it "
|
19
|
+
it "is delegated to redis" do
|
20
20
|
ca.set("xxxx", "zzzz")
|
21
|
-
redis.get("xxxx").
|
21
|
+
expect(redis.get("xxxx")).to eq("zzzz")
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -5,26 +5,26 @@ describe PulseMeter::CommandAggregator::UDP do
|
|
5
5
|
let(:port){33333}
|
6
6
|
let(:udp_sock){double(:socket)}
|
7
7
|
before do
|
8
|
-
UDPSocket.
|
9
|
-
udp_sock.
|
8
|
+
allow(UDPSocket).to receive(:new).and_return(udp_sock)
|
9
|
+
allow(udp_sock).to receive(:fcntl).and_return(nil)
|
10
10
|
@ca = described_class.new([[host, port]])
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "#multi" do
|
14
|
-
it "
|
14
|
+
it "accumulates redis commands and send them in a bulk" do
|
15
15
|
data = [
|
16
16
|
["set", "xxxx", "zzzz"],
|
17
17
|
["set", "yyyy", "zzzz"]
|
18
18
|
].to_json
|
19
|
-
udp_sock.
|
19
|
+
expect(udp_sock).to receive(:send).with(data, 0, host, port).and_return(0)
|
20
20
|
@ca.multi do
|
21
21
|
@ca.set("xxxx", "zzzz")
|
22
22
|
@ca.set("yyyy", "zzzz")
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
it "
|
27
|
-
udp_sock.
|
26
|
+
it "ignores standard exceptions" do
|
27
|
+
expect(udp_sock).to receive(:send).and_raise(StandardError)
|
28
28
|
@ca.multi do
|
29
29
|
@ca.set("xxxx", "zzzz")
|
30
30
|
end
|
@@ -32,11 +32,11 @@ describe PulseMeter::CommandAggregator::UDP do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
describe "any other redis instance method" do
|
35
|
-
it "
|
35
|
+
it "sends data imediately" do
|
36
36
|
data = [
|
37
37
|
["set", "xxxx", "zzzz"]
|
38
38
|
].to_json
|
39
|
-
udp_sock.
|
39
|
+
expect(udp_sock).to receive(:send).with(data, 0, host, port).and_return(0)
|
40
40
|
@ca.set("xxxx", "zzzz")
|
41
41
|
end
|
42
42
|
end
|
@@ -30,21 +30,21 @@ describe PulseMeter::Mixins::Dumper do
|
|
30
30
|
describe '#dump' do
|
31
31
|
context "when class violates dump contract" do
|
32
32
|
context "when it has no name attribute" do
|
33
|
-
it "
|
33
|
+
it "raises exception" do
|
34
34
|
def bad_obj.redis; PulseMeter.redis; end
|
35
35
|
expect{ bad_obj.dump! }.to raise_exception(PulseMeter::DumpError)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
context "when it has no redis attribute" do
|
40
|
-
it "
|
40
|
+
it "raises exception" do
|
41
41
|
def bad_obj.name; :foo; end
|
42
42
|
expect{ bad_obj.dump! }.to raise_exception(PulseMeter::DumpError)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
context "when redis is not avalable" do
|
47
|
-
it "
|
47
|
+
it "raises exception" do
|
48
48
|
def bad_obj.name; :foo; end
|
49
49
|
def bad_obj.redis; nil; end
|
50
50
|
expect{ bad_obj.dump! }.to raise_exception(PulseMeter::DumpError)
|
@@ -53,25 +53,25 @@ describe PulseMeter::Mixins::Dumper do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
context "when class follows dump contract" do
|
56
|
-
it "
|
56
|
+
it "does not raise dump exception" do
|
57
57
|
expect {good_obj.dump!}.not_to raise_exception
|
58
58
|
end
|
59
59
|
|
60
|
-
it "
|
60
|
+
it "saves dump to redis" do
|
61
61
|
expect {good_obj.dump!}.to change {redis.hlen(Good::DUMP_REDIS_KEY)}.by(1)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
context "when dump is safe" do
|
66
|
-
it "
|
66
|
+
it "does not overwrite stored objects of the same type" do
|
67
67
|
good_obj.some_value = 123
|
68
68
|
good_obj.dump!
|
69
69
|
good_obj.some_value = 321
|
70
70
|
good_obj.dump!
|
71
|
-
Base.restore(good_obj.name).some_value.
|
71
|
+
expect(Base.restore(good_obj.name).some_value).to eq(123)
|
72
72
|
end
|
73
73
|
|
74
|
-
it "
|
74
|
+
it "raises DumpConflictError exception if sensor with the same name but different type already exists" do
|
75
75
|
good_obj.name = "duplicate_name"
|
76
76
|
good_obj_of_another_type.name = "duplicate_name"
|
77
77
|
good_obj.dump!
|
@@ -82,7 +82,7 @@ describe PulseMeter::Mixins::Dumper do
|
|
82
82
|
|
83
83
|
describe ".restore" do
|
84
84
|
context "when object has never been dumped" do
|
85
|
-
it "
|
85
|
+
it "raises exception" do
|
86
86
|
expect{ Base.restore(:nonexistant) }.to raise_exception(PulseMeter::RestoreError)
|
87
87
|
end
|
88
88
|
end
|
@@ -92,20 +92,20 @@ describe PulseMeter::Mixins::Dumper do
|
|
92
92
|
good_obj.dump!
|
93
93
|
end
|
94
94
|
|
95
|
-
it "
|
96
|
-
Base.restore(good_obj.name).
|
95
|
+
it "keeps object class" do
|
96
|
+
expect(Base.restore(good_obj.name)).to be_instance_of(good_obj.class)
|
97
97
|
end
|
98
98
|
|
99
|
-
it "
|
99
|
+
it "restores object data" do
|
100
100
|
restored = Base.restore(good_obj.name)
|
101
|
-
restored.some_value.
|
101
|
+
expect(restored.some_value).to eq(good_obj.some_value)
|
102
102
|
end
|
103
103
|
|
104
|
-
it "
|
104
|
+
it "restores last dumped object" do
|
105
105
|
good_obj.some_value = :bar
|
106
106
|
good_obj.dump!(false)
|
107
107
|
restored = Base.restore(good_obj.name)
|
108
|
-
restored.some_value.
|
108
|
+
expect(restored.some_value).to eq(:bar)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
@@ -113,23 +113,23 @@ describe PulseMeter::Mixins::Dumper do
|
|
113
113
|
describe ".list_names" do
|
114
114
|
context "when redis is not available" do
|
115
115
|
before do
|
116
|
-
PulseMeter.
|
116
|
+
allow(PulseMeter).to receive(:redis).and_return(nil)
|
117
117
|
end
|
118
118
|
|
119
|
-
it "
|
119
|
+
it "raises exception" do
|
120
120
|
expect {Base.list_names}.to raise_exception(PulseMeter::RestoreError)
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
124
|
context "when redis if fine" do
|
125
|
-
it "
|
126
|
-
Base.list_names.
|
125
|
+
it "returns empty list if nothing is registered" do
|
126
|
+
expect(Base.list_names).to eq([])
|
127
127
|
end
|
128
128
|
|
129
|
-
it "
|
129
|
+
it "returns list of registered objects" do
|
130
130
|
good_obj.dump!(false)
|
131
131
|
another_good_obj.dump!(false)
|
132
|
-
Base.list_names.
|
132
|
+
expect(Base.list_names).to match_array([good_obj.name, another_good_obj.name])
|
133
133
|
end
|
134
134
|
end
|
135
135
|
end
|
@@ -140,20 +140,20 @@ describe PulseMeter::Mixins::Dumper do
|
|
140
140
|
another_good_obj.dump!
|
141
141
|
end
|
142
142
|
|
143
|
-
it "
|
143
|
+
it "returns restored objects" do
|
144
144
|
objects = Base.list_objects
|
145
|
-
objects.map(&:name).
|
145
|
+
expect(objects.map(&:name)).to match_array([good_obj.name, another_good_obj.name])
|
146
146
|
end
|
147
147
|
|
148
|
-
it "
|
149
|
-
Base.
|
148
|
+
it "skips unrestorable objects" do
|
149
|
+
allow(Base).to receive(:list_names).and_return([good_obj.name, "scoundrel", another_good_obj.name])
|
150
150
|
objects = Base.list_objects
|
151
|
-
objects.map(&:name).
|
151
|
+
expect(objects.map(&:name)).to match_array([good_obj.name, another_good_obj.name])
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
155
|
describe "#cleanup_dump" do
|
156
|
-
it "
|
156
|
+
it "removes data from redis" do
|
157
157
|
good_obj.dump!
|
158
158
|
another_good_obj.dump!
|
159
159
|
expect {good_obj.cleanup_dump}.to change{good_obj.class.list_names.count}.by(-1)
|
@@ -9,63 +9,63 @@ describe PulseMeter::Mixins::Utils do
|
|
9
9
|
|
10
10
|
describe '#constantize' do
|
11
11
|
context "when argument is a string with a valid class name" do
|
12
|
-
it "
|
13
|
-
dummy.constantize("PulseMeter::Mixins::Utils").
|
12
|
+
it "returns class" do
|
13
|
+
expect(dummy.constantize("PulseMeter::Mixins::Utils")).to eq(PulseMeter::Mixins::Utils)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
context "when argument is a string with invalid class name" do
|
17
|
-
it "
|
18
|
-
dummy.constantize("Pumpkin::Eater").
|
17
|
+
it "returns nil" do
|
18
|
+
expect(dummy.constantize("Pumpkin::Eater")).to be_nil
|
19
19
|
end
|
20
20
|
end
|
21
21
|
context "when argument is not a string" do
|
22
|
-
it "
|
23
|
-
dummy.constantize({}).
|
22
|
+
it "returns nil" do
|
23
|
+
expect(dummy.constantize({})).to be_nil
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "#assert_positive_integer!" do
|
29
|
-
it "
|
30
|
-
dummy.assert_positive_integer!({:val => 4}, :val).
|
29
|
+
it "extracts integer value from hash by passed key" do
|
30
|
+
expect(dummy.assert_positive_integer!({:val => 4}, :val)).to eq(4)
|
31
31
|
end
|
32
32
|
|
33
33
|
context "when no default value given" do
|
34
34
|
context "when the value by the passed key is not integer" do
|
35
|
-
it "
|
36
|
-
dummy.assert_positive_integer!({:val => 4.4}, :val).
|
35
|
+
it "converts non-integers to integers" do
|
36
|
+
expect(dummy.assert_positive_integer!({:val => 4.4}, :val)).to eq(4)
|
37
37
|
end
|
38
38
|
|
39
|
-
it "
|
39
|
+
it "changes the original value to the obtained integer" do
|
40
40
|
h = {:val => 4.4}
|
41
|
-
dummy.assert_positive_integer!(h, :val).
|
42
|
-
h[:val].
|
41
|
+
expect(dummy.assert_positive_integer!(h, :val)).to eq(4)
|
42
|
+
expect(h[:val]).to eq(4)
|
43
43
|
end
|
44
44
|
|
45
|
-
it "
|
45
|
+
it "raises exception if the original value cannot be converted to integer"do
|
46
46
|
expect{ dummy.assert_positive_integer!({:val => :bad_int}, :val) }.to raise_exception(ArgumentError)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
it "
|
50
|
+
it "raises exception if the value is not positive" do
|
51
51
|
expect{ dummy.assert_positive_integer!({:val => -1}, :val) }.to raise_exception(ArgumentError)
|
52
52
|
end
|
53
53
|
|
54
|
-
it "
|
54
|
+
it "raises exception if the value is not defined" do
|
55
55
|
expect{ dummy.assert_positive_integer!({}, :val) }.to raise_exception(ArgumentError)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
context "when default value given" do
|
60
|
-
it "
|
61
|
-
dummy.assert_positive_integer!({:val => 4}, :val, 22).
|
60
|
+
it "prefers value from options to default" do
|
61
|
+
expect(dummy.assert_positive_integer!({:val => 4}, :val, 22)).to eq(4)
|
62
62
|
end
|
63
63
|
|
64
|
-
it "
|
65
|
-
dummy.assert_positive_integer!({}, :val, 22).
|
64
|
+
it "uses default value when there is no one in options" do
|
65
|
+
expect(dummy.assert_positive_integer!({}, :val, 22)).to eq(22)
|
66
66
|
end
|
67
67
|
|
68
|
-
it "
|
68
|
+
it "checks default value if it is to be used" do
|
69
69
|
expect{dummy.assert_positive_integer!({}, :val, :bad)}.to raise_exception(ArgumentError)
|
70
70
|
expect{dummy.assert_positive_integer!({}, :val, -1)}.to raise_exception(ArgumentError)
|
71
71
|
end
|
@@ -73,30 +73,30 @@ describe PulseMeter::Mixins::Utils do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
describe "#assert_array!" do
|
76
|
-
it "
|
77
|
-
dummy.assert_array!({:val => [:foo]}, :val).
|
76
|
+
it "extracts value from hash by passed key" do
|
77
|
+
expect(dummy.assert_array!({:val => [:foo]}, :val)).to eq([:foo])
|
78
78
|
end
|
79
79
|
|
80
80
|
context "when no default value given" do
|
81
|
-
it "
|
81
|
+
it "raises exception if th value is not an Array" do
|
82
82
|
expect{ dummy.assert_array!({:val => :bad}, :val) }.to raise_exception(ArgumentError)
|
83
83
|
end
|
84
84
|
|
85
|
-
it "
|
85
|
+
it "raises exception if the value is not defined" do
|
86
86
|
expect{ dummy.assert_array!({}, :val) }.to raise_exception(ArgumentError)
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
context "when default value given" do
|
91
|
-
it "
|
92
|
-
dummy.assert_array!({:val => [:foo]}, :val, []).
|
91
|
+
it "prefers value from options to default" do
|
92
|
+
expect(dummy.assert_array!({:val => [:foo]}, :val, [])).to eq([:foo])
|
93
93
|
end
|
94
94
|
|
95
|
-
it "
|
96
|
-
dummy.assert_array!({}, :val, []).
|
95
|
+
it "uses default value when there is no one in options" do
|
96
|
+
expect(dummy.assert_array!({}, :val, [])).to eq([])
|
97
97
|
end
|
98
98
|
|
99
|
-
it "
|
99
|
+
it "checks default value if it is to be used" do
|
100
100
|
expect{dummy.assert_array!({}, :val, :bad)}.to raise_exception(ArgumentError)
|
101
101
|
end
|
102
102
|
end
|
@@ -104,81 +104,81 @@ describe PulseMeter::Mixins::Utils do
|
|
104
104
|
|
105
105
|
describe "#assert_ranged_float!" do
|
106
106
|
|
107
|
-
it "
|
108
|
-
dummy.assert_ranged_float!({:val => 4}, :val, 0, 100).
|
107
|
+
it "extracts float value from hash by passed key" do
|
108
|
+
expect(dummy.assert_ranged_float!({:val => 4}, :val, 0, 100)).to be_generally_equal(4)
|
109
109
|
end
|
110
110
|
|
111
111
|
context "when the value by the passed key is not float" do
|
112
|
-
it "
|
113
|
-
dummy.assert_ranged_float!({:val => "4.0000"}, :val, 0, 100).
|
112
|
+
it "converts non-floats to floats" do
|
113
|
+
expect(dummy.assert_ranged_float!({:val => "4.0000"}, :val, 0, 100)).to be_generally_equal(4)
|
114
114
|
end
|
115
115
|
|
116
|
-
it "
|
116
|
+
it "changes the original value to the obtained float" do
|
117
117
|
h = {:val => "4.000"}
|
118
|
-
dummy.assert_ranged_float!(h, :val, 0, 100).
|
119
|
-
h[:val].
|
118
|
+
expect(dummy.assert_ranged_float!(h, :val, 0, 100)).to be_generally_equal(4)
|
119
|
+
expect(h[:val]).to be_generally_equal(4)
|
120
120
|
end
|
121
121
|
|
122
|
-
it "
|
122
|
+
it "raises exception if the original value cannot be converted to float" do
|
123
123
|
expect{ dummy.assert_ranged_float!({:val => :bad_float}, :val, 0, 100) }.to raise_exception(ArgumentError)
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
-
it "
|
127
|
+
it "raises exception if the value is not within range" do
|
128
128
|
expect{ dummy.assert_ranged_float!({:val => -0.1}, :val, 0, 100) }.to raise_exception(ArgumentError)
|
129
129
|
expect{ dummy.assert_ranged_float!({:val => 100.1}, :val, 0, 100) }.to raise_exception(ArgumentError)
|
130
130
|
end
|
131
131
|
|
132
|
-
it "
|
132
|
+
it "raises exception if the value is not defined" do
|
133
133
|
expect{ dummy.assert_ranged_float!({}, :val) }.to raise_exception(ArgumentError)
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
137
|
describe "#uniqid" do
|
138
|
-
it "
|
138
|
+
it "returns uniq strings" do
|
139
139
|
uniq_values = (1..1000).map{|_| dummy.uniqid}
|
140
|
-
uniq_values.uniq.count.
|
140
|
+
expect(uniq_values.uniq.count).to eq(uniq_values.count)
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
144
|
describe "#titleize" do
|
145
|
-
it "
|
146
|
-
dummy.titleize("aaa_bbb").
|
147
|
-
dummy.titleize(:aaa_bbb).
|
148
|
-
dummy.titleize("aaa bbb").
|
145
|
+
it "converts identificator to title" do
|
146
|
+
expect(dummy.titleize("aaa_bbb")).to eq('Aaa Bbb')
|
147
|
+
expect(dummy.titleize(:aaa_bbb)).to eq('Aaa Bbb')
|
148
|
+
expect(dummy.titleize("aaa bbb")).to eq('Aaa Bbb')
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
152
|
describe "#camelize" do
|
153
|
-
it "
|
154
|
-
dummy.camelize("aa_bb_cc").
|
155
|
-
dummy.camelize("aa_bb_cc", true).
|
153
|
+
it "camelizes string" do
|
154
|
+
expect(dummy.camelize("aa_bb_cc")).to eq("aaBbCc")
|
155
|
+
expect(dummy.camelize("aa_bb_cc", true)).to eq("AaBbCc")
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
159
|
describe "#underscore" do
|
160
|
-
it "
|
161
|
-
dummy.underscore("aaBbCc").
|
162
|
-
dummy.underscore("AaBbCc").
|
163
|
-
dummy.underscore("aaBb::Cc").
|
160
|
+
it "underscores string" do
|
161
|
+
expect(dummy.underscore("aaBbCc")).to eq("aa_bb_cc")
|
162
|
+
expect(dummy.underscore("AaBbCc")).to eq("aa_bb_cc")
|
163
|
+
expect(dummy.underscore("aaBb::Cc")).to eq("aa_bb/cc")
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
167
|
describe "#camelize_keys" do
|
168
|
-
it "
|
169
|
-
dummy.camelize_keys({ :aa_bb_cc => [ { :dd_ee => 123 }, 456 ] }).
|
168
|
+
it "deeply camelizes keys in hashes" do
|
169
|
+
expect(dummy.camelize_keys({ :aa_bb_cc => [ { :dd_ee => 123 }, 456 ] })).to eq({ 'aaBbCc' => [ { 'ddEe' => 123 }, 456 ] })
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
173
173
|
describe "#symbolize_keys" do
|
174
|
-
it "
|
175
|
-
dummy.symbolize_keys({"a" => 5, 6 => 7}).
|
174
|
+
it "converts symbolizable keys to symbols" do
|
175
|
+
expect(dummy.symbolize_keys({"a" => 5, 6 => 7})).to eq({a: 5, 6 => 7})
|
176
176
|
end
|
177
177
|
end
|
178
178
|
|
179
179
|
describe "#subsets_of" do
|
180
180
|
it "returns all subsets of given array" do
|
181
|
-
dummy.subsets_of([1, 2]).sort.
|
181
|
+
expect(dummy.subsets_of([1, 2]).sort).to eq([[], [1], [2], [1, 2]].sort)
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
@@ -186,25 +186,25 @@ describe PulseMeter::Mixins::Utils do
|
|
186
186
|
it "iterates over each subset" do
|
187
187
|
subsets = []
|
188
188
|
dummy.each_subset([1, 2]) {|s| subsets << s}
|
189
|
-
subsets.sort.
|
189
|
+
expect(subsets.sort).to eq([[], [1], [2], [1, 2]].sort)
|
190
190
|
end
|
191
191
|
end
|
192
192
|
|
193
193
|
describe '#parse_time' do
|
194
194
|
context "when argument is a valid YYYYmmddHHMMSS string" do
|
195
|
-
it "
|
195
|
+
it "corrects Time object" do
|
196
196
|
t = dummy.parse_time("19700101000000")
|
197
|
-
t.
|
198
|
-
t.to_i.
|
197
|
+
expect(t).to be_kind_of(Time)
|
198
|
+
expect(t.to_i).to eq(0)
|
199
199
|
end
|
200
200
|
end
|
201
201
|
context "when argument is an invalid YYYYmmddHHMMSS string" do
|
202
|
-
it "
|
202
|
+
it "raises ArgumentError" do
|
203
203
|
expect{ dummy.parse_time("19709901000000") }.to raise_exception(ArgumentError)
|
204
204
|
end
|
205
205
|
end
|
206
206
|
context "when argument is not a YYYYmmddHHMMSS string" do
|
207
|
-
it "
|
207
|
+
it "raises ArgumentError" do
|
208
208
|
expect{ dummy.parse_time("197099010000000") }.to raise_exception(ArgumentError)
|
209
209
|
end
|
210
210
|
end
|