pulse_meter_core 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|