pulse-meter 0.0.1
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.
- data/.gitignore +19 -0
- data/.rbenv-version +1 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/Procfile +3 -0
- data/README.md +440 -0
- data/Rakefile +53 -0
- data/bin/pulse +6 -0
- data/examples/basic.ru +109 -0
- data/examples/basic_sensor_data.rb +38 -0
- data/examples/full/Procfile +2 -0
- data/examples/full/client.rb +82 -0
- data/examples/full/server.ru +114 -0
- data/examples/minimal/Procfile +2 -0
- data/examples/minimal/client.rb +16 -0
- data/examples/minimal/server.ru +20 -0
- data/examples/readme_client_example.rb +52 -0
- data/lib/cmd.rb +150 -0
- data/lib/pulse-meter.rb +17 -0
- data/lib/pulse-meter/mixins/dumper.rb +72 -0
- data/lib/pulse-meter/mixins/utils.rb +91 -0
- data/lib/pulse-meter/sensor.rb +44 -0
- data/lib/pulse-meter/sensor/base.rb +75 -0
- data/lib/pulse-meter/sensor/counter.rb +36 -0
- data/lib/pulse-meter/sensor/hashed_counter.rb +31 -0
- data/lib/pulse-meter/sensor/indicator.rb +33 -0
- data/lib/pulse-meter/sensor/timeline.rb +180 -0
- data/lib/pulse-meter/sensor/timelined/average.rb +26 -0
- data/lib/pulse-meter/sensor/timelined/counter.rb +16 -0
- data/lib/pulse-meter/sensor/timelined/hashed_counter.rb +22 -0
- data/lib/pulse-meter/sensor/timelined/max.rb +25 -0
- data/lib/pulse-meter/sensor/timelined/median.rb +14 -0
- data/lib/pulse-meter/sensor/timelined/min.rb +25 -0
- data/lib/pulse-meter/sensor/timelined/percentile.rb +31 -0
- data/lib/pulse-meter/version.rb +3 -0
- data/lib/pulse-meter/visualize/app.rb +43 -0
- data/lib/pulse-meter/visualize/dsl.rb +0 -0
- data/lib/pulse-meter/visualize/dsl/errors.rb +46 -0
- data/lib/pulse-meter/visualize/dsl/layout.rb +55 -0
- data/lib/pulse-meter/visualize/dsl/page.rb +50 -0
- data/lib/pulse-meter/visualize/dsl/sensor.rb +21 -0
- data/lib/pulse-meter/visualize/dsl/widget.rb +84 -0
- data/lib/pulse-meter/visualize/layout.rb +54 -0
- data/lib/pulse-meter/visualize/page.rb +30 -0
- data/lib/pulse-meter/visualize/public/css/application.css +19 -0
- data/lib/pulse-meter/visualize/public/css/bootstrap.css +4883 -0
- data/lib/pulse-meter/visualize/public/css/bootstrap.min.css +729 -0
- data/lib/pulse-meter/visualize/public/favicon.ico +0 -0
- data/lib/pulse-meter/visualize/public/img/glyphicons-halflings-white.png +0 -0
- data/lib/pulse-meter/visualize/public/img/glyphicons-halflings.png +0 -0
- data/lib/pulse-meter/visualize/public/js/application.coffee +262 -0
- data/lib/pulse-meter/visualize/public/js/application.js +279 -0
- data/lib/pulse-meter/visualize/public/js/backbone-min.js +38 -0
- data/lib/pulse-meter/visualize/public/js/bootstrap.js +1835 -0
- data/lib/pulse-meter/visualize/public/js/highcharts.js +203 -0
- data/lib/pulse-meter/visualize/public/js/jquery-1.7.2.min.js +4 -0
- data/lib/pulse-meter/visualize/public/js/json2.js +487 -0
- data/lib/pulse-meter/visualize/public/js/underscore-min.js +32 -0
- data/lib/pulse-meter/visualize/sensor.rb +60 -0
- data/lib/pulse-meter/visualize/views/main.haml +40 -0
- data/lib/pulse-meter/visualize/widget.rb +68 -0
- data/lib/pulse-meter/visualizer.rb +30 -0
- data/lib/test_helpers/matchers.rb +36 -0
- data/pulse-meter.gemspec +39 -0
- data/spec/pulse_meter/mixins/dumper_spec.rb +158 -0
- data/spec/pulse_meter/mixins/utils_spec.rb +134 -0
- data/spec/pulse_meter/sensor/base_spec.rb +97 -0
- data/spec/pulse_meter/sensor/counter_spec.rb +54 -0
- data/spec/pulse_meter/sensor/hashed_counter_spec.rb +39 -0
- data/spec/pulse_meter/sensor/indicator_spec.rb +43 -0
- data/spec/pulse_meter/sensor/timeline_spec.rb +58 -0
- data/spec/pulse_meter/sensor/timelined/average_spec.rb +6 -0
- data/spec/pulse_meter/sensor/timelined/counter_spec.rb +6 -0
- data/spec/pulse_meter/sensor/timelined/hashed_counter_spec.rb +8 -0
- data/spec/pulse_meter/sensor/timelined/max_spec.rb +7 -0
- data/spec/pulse_meter/sensor/timelined/median_spec.rb +7 -0
- data/spec/pulse_meter/sensor/timelined/min_spec.rb +7 -0
- data/spec/pulse_meter/sensor/timelined/percentile_spec.rb +17 -0
- data/spec/pulse_meter/visualize/app_spec.rb +27 -0
- data/spec/pulse_meter/visualize/dsl/layout_spec.rb +64 -0
- data/spec/pulse_meter/visualize/dsl/page_spec.rb +75 -0
- data/spec/pulse_meter/visualize/dsl/sensor_spec.rb +30 -0
- data/spec/pulse_meter/visualize/dsl/widget_spec.rb +127 -0
- data/spec/pulse_meter/visualize/layout_spec.rb +55 -0
- data/spec/pulse_meter/visualize/page_spec.rb +150 -0
- data/spec/pulse_meter/visualize/sensor_spec.rb +120 -0
- data/spec/pulse_meter/visualize/widget_spec.rb +113 -0
- data/spec/pulse_meter/visualizer_spec.rb +42 -0
- data/spec/pulse_meter_spec.rb +16 -0
- data/spec/shared_examples/timeline_sensor.rb +279 -0
- data/spec/shared_examples/timelined_subclass.rb +23 -0
- data/spec/spec_helper.rb +29 -0
- metadata +435 -0
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PulseMeter::Mixins::Utils do
|
4
|
+
class Dummy
|
5
|
+
include PulseMeter::Mixins::Utils
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:dummy){ Dummy.new }
|
9
|
+
|
10
|
+
describe '#constantize' do
|
11
|
+
context "when argument is a string with a valid class name" do
|
12
|
+
it "should return class" do
|
13
|
+
dummy.constantize("PulseMeter::Mixins::Utils").should == PulseMeter::Mixins::Utils
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context "when argument is a string with invalid class name" do
|
17
|
+
it "should return nil" do
|
18
|
+
dummy.constantize("Pumpkin::Eater").should be_nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
context "when argument is not a string" do
|
22
|
+
it "should return nil" do
|
23
|
+
dummy.constantize({}).should be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#assert_positive_integer!" do
|
29
|
+
it "should extract integer value from hash by passed key" do
|
30
|
+
dummy.assert_positive_integer!({:val => 4}, :val).should == 4
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when no default value given" do
|
34
|
+
context "when the value by the passed key is not integer" do
|
35
|
+
it "should convert non-integers to integers" do
|
36
|
+
dummy.assert_positive_integer!({:val => 4.4}, :val).should == 4
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should change the original value to the obtained integer" do
|
40
|
+
h = {:val => 4.4}
|
41
|
+
dummy.assert_positive_integer!(h, :val).should == 4
|
42
|
+
h[:val].should == 4
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should raise exception if the original value cannot be converted to integer"do
|
46
|
+
expect{ dummy.assert_positive_integer!({:val => :bad_int}, :val) }.to raise_exception(ArgumentError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise exception if the value is not positive" do
|
51
|
+
expect{ dummy.assert_positive_integer!({:val => -1}, :val) }.to raise_exception(ArgumentError)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should raise exception if the value is not defined" do
|
55
|
+
expect{ dummy.assert_positive_integer!({}, :val) }.to raise_exception(ArgumentError)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when default value given" do
|
60
|
+
it "should prefer value from options to default" do
|
61
|
+
dummy.assert_positive_integer!({:val => 4}, :val, 22).should == 4
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should use default value when there is no one in options" do
|
65
|
+
dummy.assert_positive_integer!({}, :val, 22).should == 22
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should check default value if it is to be used" do
|
69
|
+
expect{dummy.assert_positive_integer!({}, :val, :bad)}.to raise_exception(ArgumentError)
|
70
|
+
expect{dummy.assert_positive_integer!({}, :val, -1)}.to raise_exception(ArgumentError)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#assert_ranged_float!" do
|
76
|
+
|
77
|
+
it "should extract float value from hash by passed key" do
|
78
|
+
dummy.assert_ranged_float!({:val => 4}, :val, 0, 100).should be_generally_equal(4)
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when the value by the passed key is not float" do
|
82
|
+
it "should convert non-floats to floats" do
|
83
|
+
dummy.assert_ranged_float!({:val => "4.0000"}, :val, 0, 100).should be_generally_equal(4)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should change the original value to the obtained float" do
|
87
|
+
h = {:val => "4.000"}
|
88
|
+
dummy.assert_ranged_float!(h, :val, 0, 100).should be_generally_equal(4)
|
89
|
+
h[:val].should be_generally_equal(4)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should raise exception if the original value cannot be converted to float" do
|
93
|
+
expect{ dummy.assert_ranged_float!({:val => :bad_float}, :val, 0, 100) }.to raise_exception(ArgumentError)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should raise exception if the value is not within range" do
|
98
|
+
expect{ dummy.assert_ranged_float!({:val => -0.1}, :val, 0, 100) }.to raise_exception(ArgumentError)
|
99
|
+
expect{ dummy.assert_ranged_float!({:val => 100.1}, :val, 0, 100) }.to raise_exception(ArgumentError)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should raise exception if the value is not defined" do
|
103
|
+
expect{ dummy.assert_ranged_float!({}, :val) }.to raise_exception(ArgumentError)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#uniqid" do
|
108
|
+
it "should return uniq strings" do
|
109
|
+
uniq_values = (1..1000).map{|_| dummy.uniqid}
|
110
|
+
uniq_values.uniq.count.should == uniq_values.count
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#titleize" do
|
115
|
+
it "should convert identificator to title" do
|
116
|
+
dummy.titleize("aaa_bbb").should == 'Aaa Bbb'
|
117
|
+
dummy.titleize(:aaa_bbb).should == 'Aaa Bbb'
|
118
|
+
dummy.titleize("aaa bbb").should == 'Aaa Bbb'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "#camelize" do
|
123
|
+
it "should camelize string" do
|
124
|
+
dummy.camelize("aa_bb_cc").should == "aaBbCc"
|
125
|
+
dummy.camelize("aa_bb_cc", true).should == "AaBbCc"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "#camelize_keys" do
|
130
|
+
it "should deeply camelize keys in hashes" do
|
131
|
+
dummy.camelize_keys({ :aa_bb_cc => [ { :dd_ee => 123 }, 456 ] }).should =={ 'aaBbCc' => [ { 'ddEe' => 123 }, 456 ] }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PulseMeter::Sensor::Base do
|
4
|
+
let(:name){ :some_sensor }
|
5
|
+
let(:description) {"Le awesome description"}
|
6
|
+
let!(:sensor){ described_class.new(name) }
|
7
|
+
let(:redis){ PulseMeter.redis }
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
context 'when PulseMeter.redis is not initialized' do
|
11
|
+
it "should raise RedisNotInitialized exception" do
|
12
|
+
PulseMeter.redis = nil
|
13
|
+
expect{ described_class.new(:foo) }.to raise_exception(PulseMeter::RedisNotInitialized)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when PulseMeter.redis is initialized' do
|
18
|
+
|
19
|
+
context 'when passed sensor name is bad' do
|
20
|
+
it "should raise BadSensorName exception" do
|
21
|
+
['name with whitespace', 'name|with|bad|characters'].each do |bad_name|
|
22
|
+
expect{ described_class.new(bad_name) }.to raise_exception(PulseMeter::BadSensorName)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when passed sensor name is valid' do
|
28
|
+
it "should successfully create object" do
|
29
|
+
described_class.new(:foo).should_not be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should initialize attributes #redis and #name" do
|
33
|
+
sensor = described_class.new(:foo)
|
34
|
+
sensor.name.should == 'foo'
|
35
|
+
sensor.redis.should == PulseMeter.redis
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should save dump to redis automatically to let the object be restored by name" do
|
39
|
+
described_class.restore(name).should be_instance_of(described_class)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should annotate object if annotation given" do
|
43
|
+
described_class.new(:foo, :annotation => "annotation")
|
44
|
+
sensor = described_class.restore(:foo)
|
45
|
+
sensor.annotation.should == "annotation"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#annotate' do
|
52
|
+
|
53
|
+
it "should store sensor annotation in redis" do
|
54
|
+
expect {sensor.annotate(description)}.to change{redis.keys('*').count}.by(1)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#annotation' do
|
60
|
+
context "when sensor was annotated" do
|
61
|
+
it "should return stored annotation" do
|
62
|
+
sensor.annotate(description)
|
63
|
+
sensor.annotation.should == description
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when sensor was not annotated" do
|
68
|
+
it "should return nil" do
|
69
|
+
sensor.annotation.should be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "after sensor data was cleaned" do
|
74
|
+
it "should return nil" do
|
75
|
+
sensor.annotate(description)
|
76
|
+
sensor.cleanup
|
77
|
+
sensor.annotation.should be_nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#cleanup" do
|
83
|
+
it "should remove from redis all sensor data" do
|
84
|
+
sensor.event(123)
|
85
|
+
sensor.annotate(description)
|
86
|
+
sensor.cleanup
|
87
|
+
redis.keys('*').should be_empty
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#event" do
|
92
|
+
it "should actually do nothing for base sensor" do
|
93
|
+
sensor.event(nil)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PulseMeter::Sensor::Counter do
|
4
|
+
let(:name){ :some_counter }
|
5
|
+
let(:sensor){ described_class.new(name) }
|
6
|
+
let(:redis){ PulseMeter.redis }
|
7
|
+
|
8
|
+
describe "#event" do
|
9
|
+
it "should increment sensor value by passed value" do
|
10
|
+
expect{ sensor.event(10) }.to change{ sensor.value }.from(0).to(10)
|
11
|
+
expect{ sensor.event(15) }.to change{ sensor.value }.from(10).to(25)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should truncate increment value" do
|
15
|
+
expect{ sensor.event(10.4) }.to change{ sensor.value }.from(0).to(10)
|
16
|
+
expect{ sensor.event(15.1) }.to change{ sensor.value }.from(10).to(25)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#value_key" do
|
21
|
+
it "should be composed of sensor name and pulse_meter:value: prefix" do
|
22
|
+
sensor.value_key.should == "pulse_meter:value:#{name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#value" do
|
27
|
+
it "should have initial value 0" do
|
28
|
+
sensor.value.should == 0
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should store stringified value by value_key" do
|
32
|
+
sensor.event(123)
|
33
|
+
sensor.value.should == 123
|
34
|
+
redis.get(sensor.value_key).should == '123'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#incr" do
|
39
|
+
it "should increment value by 1" do
|
40
|
+
expect{ sensor.incr }.to change{ sensor.value }.from(0).to(1)
|
41
|
+
expect{ sensor.incr }.to change{ sensor.value }.from(1).to(2)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#cleanup" do
|
46
|
+
it "should remove all sensor data" do
|
47
|
+
sensor.annotate("My Counter")
|
48
|
+
sensor.event(123)
|
49
|
+
sensor.cleanup
|
50
|
+
redis.keys('*').should be_empty
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PulseMeter::Sensor::HashedCounter do
|
4
|
+
let(:name){ :some_counter }
|
5
|
+
let(:sensor){ described_class.new(name) }
|
6
|
+
let(:redis){ PulseMeter.redis }
|
7
|
+
|
8
|
+
describe "#event" do
|
9
|
+
it "should increment sensor value by passed value" do
|
10
|
+
expect{ sensor.event({"foo" => 10}) }.to change{ sensor.value["foo"] }.from(0).to(10)
|
11
|
+
expect{ sensor.event({"foo" => 15}) }.to change{ sensor.value["foo"] }.from(10).to(25)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should truncate increment value" do
|
15
|
+
expect{ sensor.event({"foo" => 10.4}) }.to change{ sensor.value["foo"] }.from(0).to(10)
|
16
|
+
expect{ sensor.event({"foo" => 15.1}) }.to change{ sensor.value["foo"] }.from(10).to(25)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#value" do
|
21
|
+
it "should have initial value 0" do
|
22
|
+
sensor.value["foo"].should == 0
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should store redis hash by value_key" do
|
26
|
+
sensor.event({"foo" => 1})
|
27
|
+
sensor.value.should == {"foo" => 1}
|
28
|
+
redis.hgetall(sensor.value_key).should == {"foo" => "1"}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#incr" do
|
33
|
+
it "should increment key value by 1" do
|
34
|
+
expect{ sensor.incr("foo") }.to change{ sensor.value["foo"] }.from(0).to(1)
|
35
|
+
expect{ sensor.incr("foo") }.to change{ sensor.value["foo"] }.from(1).to(2)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PulseMeter::Sensor::Indicator do
|
4
|
+
let(:name){ :some_value }
|
5
|
+
let(:sensor){ described_class.new(name) }
|
6
|
+
let(:redis){ PulseMeter.redis }
|
7
|
+
|
8
|
+
describe "#event" do
|
9
|
+
it "should set sensor value to passed value" do
|
10
|
+
expect{ sensor.event(10.4) }.to change{ sensor.value }.from(0).to(10.4)
|
11
|
+
expect{ sensor.event(15.1) }.to change{ sensor.value }.from(10.4).to(15.1)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#value_key" do
|
16
|
+
it "should be composed of sensor name and pulse_meter:value: prefix" do
|
17
|
+
sensor.value_key.should == "pulse_meter:value:#{name}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#value" do
|
22
|
+
it "should have initial value 0" do
|
23
|
+
sensor.value.should == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should store stringified value by value_key" do
|
27
|
+
sensor.event(123)
|
28
|
+
sensor.value.should == 123
|
29
|
+
redis.get(sensor.value_key) == '123'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#cleanup" do
|
34
|
+
it "should remove all sensor data" do
|
35
|
+
sensor.annotate("My Indicator")
|
36
|
+
sensor.event(123)
|
37
|
+
sensor.cleanup
|
38
|
+
redis.keys('*').should be_empty
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PulseMeter::Sensor::Timeline do
|
4
|
+
let(:name){ :some_value_with_history }
|
5
|
+
let(:ttl){ 100 }
|
6
|
+
let(:raw_data_ttl){ 10 }
|
7
|
+
let(:interval){ 5 }
|
8
|
+
let(:reduce_delay){ 3 }
|
9
|
+
let(:good_init_values){ {:ttl => ttl, :raw_data_ttl => raw_data_ttl, :interval => interval, :reduce_delay => reduce_delay} }
|
10
|
+
let(:sensor){ described_class.new(name, good_init_values) }
|
11
|
+
let(:redis){ PulseMeter.redis }
|
12
|
+
|
13
|
+
it_should_behave_like "timeline sensor"
|
14
|
+
|
15
|
+
describe '#new' do
|
16
|
+
INIT_VALUE_NAMES = {
|
17
|
+
:with_defaults => [:raw_data_ttl, :reduce_delay],
|
18
|
+
:without_defaults => [:ttl, :interval]
|
19
|
+
}
|
20
|
+
|
21
|
+
shared_examples_for "error raiser" do |value_names, bad_values|
|
22
|
+
value_names.each do |value|
|
23
|
+
bad_values.each do |bad_value|
|
24
|
+
it "should raise exception if a bad value #{bad_value.inspect} passed for #{value.inspect}" do
|
25
|
+
expect{ described_class.new(name, good_init_values.merge(value => bad_value)) }.to raise_exception(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should initialize #ttl #raw_data_ttl #interval and #name attributes" do
|
32
|
+
sensor.name.should == name.to_s
|
33
|
+
|
34
|
+
sensor.ttl.should == ttl
|
35
|
+
sensor.raw_data_ttl.should == raw_data_ttl
|
36
|
+
sensor.interval.should == interval
|
37
|
+
end
|
38
|
+
|
39
|
+
it_should_behave_like "error raiser", INIT_VALUE_NAMES[:without_defaults], [:bad, -1, nil]
|
40
|
+
it_should_behave_like "error raiser", INIT_VALUE_NAMES[:with_defaults], [:bad, -1]
|
41
|
+
|
42
|
+
INIT_VALUE_NAMES[:with_defaults].each do |value|
|
43
|
+
it "should not raise exception if #{value.inspect} is not defined" do
|
44
|
+
values = good_init_values
|
45
|
+
values.delete(value)
|
46
|
+
expect {described_class.new(name, good_init_values)}.not_to raise_exception(ArgumentError)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should assign default value to #{value.inspect} if it is not defined" do
|
50
|
+
values = good_init_values
|
51
|
+
values.delete(value)
|
52
|
+
obj = described_class.new(name, good_init_values)
|
53
|
+
obj.send(value).should be_kind_of(Fixnum)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|