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.
Files changed (96) hide show
  1. data/.gitignore +19 -0
  2. data/.rbenv-version +1 -0
  3. data/.rspec +1 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +22 -0
  8. data/Procfile +3 -0
  9. data/README.md +440 -0
  10. data/Rakefile +53 -0
  11. data/bin/pulse +6 -0
  12. data/examples/basic.ru +109 -0
  13. data/examples/basic_sensor_data.rb +38 -0
  14. data/examples/full/Procfile +2 -0
  15. data/examples/full/client.rb +82 -0
  16. data/examples/full/server.ru +114 -0
  17. data/examples/minimal/Procfile +2 -0
  18. data/examples/minimal/client.rb +16 -0
  19. data/examples/minimal/server.ru +20 -0
  20. data/examples/readme_client_example.rb +52 -0
  21. data/lib/cmd.rb +150 -0
  22. data/lib/pulse-meter.rb +17 -0
  23. data/lib/pulse-meter/mixins/dumper.rb +72 -0
  24. data/lib/pulse-meter/mixins/utils.rb +91 -0
  25. data/lib/pulse-meter/sensor.rb +44 -0
  26. data/lib/pulse-meter/sensor/base.rb +75 -0
  27. data/lib/pulse-meter/sensor/counter.rb +36 -0
  28. data/lib/pulse-meter/sensor/hashed_counter.rb +31 -0
  29. data/lib/pulse-meter/sensor/indicator.rb +33 -0
  30. data/lib/pulse-meter/sensor/timeline.rb +180 -0
  31. data/lib/pulse-meter/sensor/timelined/average.rb +26 -0
  32. data/lib/pulse-meter/sensor/timelined/counter.rb +16 -0
  33. data/lib/pulse-meter/sensor/timelined/hashed_counter.rb +22 -0
  34. data/lib/pulse-meter/sensor/timelined/max.rb +25 -0
  35. data/lib/pulse-meter/sensor/timelined/median.rb +14 -0
  36. data/lib/pulse-meter/sensor/timelined/min.rb +25 -0
  37. data/lib/pulse-meter/sensor/timelined/percentile.rb +31 -0
  38. data/lib/pulse-meter/version.rb +3 -0
  39. data/lib/pulse-meter/visualize/app.rb +43 -0
  40. data/lib/pulse-meter/visualize/dsl.rb +0 -0
  41. data/lib/pulse-meter/visualize/dsl/errors.rb +46 -0
  42. data/lib/pulse-meter/visualize/dsl/layout.rb +55 -0
  43. data/lib/pulse-meter/visualize/dsl/page.rb +50 -0
  44. data/lib/pulse-meter/visualize/dsl/sensor.rb +21 -0
  45. data/lib/pulse-meter/visualize/dsl/widget.rb +84 -0
  46. data/lib/pulse-meter/visualize/layout.rb +54 -0
  47. data/lib/pulse-meter/visualize/page.rb +30 -0
  48. data/lib/pulse-meter/visualize/public/css/application.css +19 -0
  49. data/lib/pulse-meter/visualize/public/css/bootstrap.css +4883 -0
  50. data/lib/pulse-meter/visualize/public/css/bootstrap.min.css +729 -0
  51. data/lib/pulse-meter/visualize/public/favicon.ico +0 -0
  52. data/lib/pulse-meter/visualize/public/img/glyphicons-halflings-white.png +0 -0
  53. data/lib/pulse-meter/visualize/public/img/glyphicons-halflings.png +0 -0
  54. data/lib/pulse-meter/visualize/public/js/application.coffee +262 -0
  55. data/lib/pulse-meter/visualize/public/js/application.js +279 -0
  56. data/lib/pulse-meter/visualize/public/js/backbone-min.js +38 -0
  57. data/lib/pulse-meter/visualize/public/js/bootstrap.js +1835 -0
  58. data/lib/pulse-meter/visualize/public/js/highcharts.js +203 -0
  59. data/lib/pulse-meter/visualize/public/js/jquery-1.7.2.min.js +4 -0
  60. data/lib/pulse-meter/visualize/public/js/json2.js +487 -0
  61. data/lib/pulse-meter/visualize/public/js/underscore-min.js +32 -0
  62. data/lib/pulse-meter/visualize/sensor.rb +60 -0
  63. data/lib/pulse-meter/visualize/views/main.haml +40 -0
  64. data/lib/pulse-meter/visualize/widget.rb +68 -0
  65. data/lib/pulse-meter/visualizer.rb +30 -0
  66. data/lib/test_helpers/matchers.rb +36 -0
  67. data/pulse-meter.gemspec +39 -0
  68. data/spec/pulse_meter/mixins/dumper_spec.rb +158 -0
  69. data/spec/pulse_meter/mixins/utils_spec.rb +134 -0
  70. data/spec/pulse_meter/sensor/base_spec.rb +97 -0
  71. data/spec/pulse_meter/sensor/counter_spec.rb +54 -0
  72. data/spec/pulse_meter/sensor/hashed_counter_spec.rb +39 -0
  73. data/spec/pulse_meter/sensor/indicator_spec.rb +43 -0
  74. data/spec/pulse_meter/sensor/timeline_spec.rb +58 -0
  75. data/spec/pulse_meter/sensor/timelined/average_spec.rb +6 -0
  76. data/spec/pulse_meter/sensor/timelined/counter_spec.rb +6 -0
  77. data/spec/pulse_meter/sensor/timelined/hashed_counter_spec.rb +8 -0
  78. data/spec/pulse_meter/sensor/timelined/max_spec.rb +7 -0
  79. data/spec/pulse_meter/sensor/timelined/median_spec.rb +7 -0
  80. data/spec/pulse_meter/sensor/timelined/min_spec.rb +7 -0
  81. data/spec/pulse_meter/sensor/timelined/percentile_spec.rb +17 -0
  82. data/spec/pulse_meter/visualize/app_spec.rb +27 -0
  83. data/spec/pulse_meter/visualize/dsl/layout_spec.rb +64 -0
  84. data/spec/pulse_meter/visualize/dsl/page_spec.rb +75 -0
  85. data/spec/pulse_meter/visualize/dsl/sensor_spec.rb +30 -0
  86. data/spec/pulse_meter/visualize/dsl/widget_spec.rb +127 -0
  87. data/spec/pulse_meter/visualize/layout_spec.rb +55 -0
  88. data/spec/pulse_meter/visualize/page_spec.rb +150 -0
  89. data/spec/pulse_meter/visualize/sensor_spec.rb +120 -0
  90. data/spec/pulse_meter/visualize/widget_spec.rb +113 -0
  91. data/spec/pulse_meter/visualizer_spec.rb +42 -0
  92. data/spec/pulse_meter_spec.rb +16 -0
  93. data/spec/shared_examples/timeline_sensor.rb +279 -0
  94. data/spec/shared_examples/timelined_subclass.rb +23 -0
  95. data/spec/spec_helper.rb +29 -0
  96. metadata +435 -0
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Sensor::Timelined::HashedCounter do
4
+ it_should_behave_like "timeline sensor", {}, {:foo => 1}
5
+ it_should_behave_like "timelined subclass", [{:foo => 1}, {:foo => 2}], {:foo => 3}.to_json
6
+ it_should_behave_like "timelined subclass", [{:foo => 1}, {:foo => :bad_value}], {:foo => 1}.to_json
7
+ it_should_behave_like "timelined subclass", [{:foo => 1}, {:boo => 2}], {:foo => 1, :boo => 2}.to_json
8
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Sensor::Timelined::Max do
4
+ it_should_behave_like "timeline sensor"
5
+ it_should_behave_like "timelined subclass", [1, 2, -1, -1, 5, 0], 5
6
+ it_should_behave_like "timelined subclass", [1], 1
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Sensor::Timelined::Median do
4
+ it_should_behave_like "timeline sensor"
5
+ it_should_behave_like "timelined subclass", [5, 4, 3, 2, 1], 3
6
+ it_should_behave_like "timelined subclass", [1], 1
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Sensor::Timelined::Min do
4
+ it_should_behave_like "timeline sensor"
5
+ it_should_behave_like "timelined subclass", [1, 2, -1, -1, 5, 0], -1
6
+ it_should_behave_like "timelined subclass", [1], 1
7
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Sensor::Timelined::Percentile do
4
+ it_should_behave_like "timeline sensor", {:p => 0.8}
5
+ it_should_behave_like "timelined subclass", [5, 4, 2, 2, 2, 2, 2, 2, 2, 1], 2, {:p => 0.8}
6
+ it_should_behave_like "timelined subclass", [1], 1, {:p => 0.8}
7
+
8
+ let(:init_values) {{:ttl => 1, :raw_data_ttl => 1, :interval => 1, :reduce_delay => 1}}
9
+ let(:name) {"percentile"}
10
+
11
+ it "should raise exception when percentile is not between 0 and 1" do
12
+ expect {described_class.new(name, init_values.merge({:p => -1}))}.to raise_exception(ArgumentError)
13
+ expect {described_class.new(name, init_values.merge({:p => 1.1}))}.to raise_exception(ArgumentError)
14
+ expect {described_class.new(name, init_values.merge({:p => 0.1}))}.not_to raise_exception(ArgumentError)
15
+ end
16
+
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Visualize::App do
4
+ include Rack::Test::Methods
5
+ before(:each) do
6
+ @layout = PulseMeter::Visualizer.draw do |l|
7
+ l.title "Foo meters"
8
+ l.page "Foo page" do
9
+ end
10
+ end
11
+ end
12
+
13
+ def app
14
+ PulseMeter::Visualize::App.new(@layout)
15
+ end
16
+
17
+ it "responds to /" do
18
+ get '/'
19
+ last_response.should be_ok
20
+ last_response.body.should include("Foo meters")
21
+ end
22
+
23
+ it "responds to /application.js" do
24
+ get '/js/application.js'
25
+ last_response.should be_ok
26
+ end
27
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Visualize::DSL::Layout do
4
+ let(:interval){ 100 }
5
+ let(:sensor_name) { "some_sensor" }
6
+ let!(:sensor){ PulseMeter::Sensor::Timelined::Max.new(sensor_name, :ttl => 1000, :interval => interval) }
7
+ let(:layout){ described_class.new }
8
+
9
+ describe '.new' do
10
+ it "should initialize pages, title, use_utc, highchart_options" do
11
+ l = layout.to_layout
12
+ l.title.should == PulseMeter::Visualize::DSL::Layout::DEFAULT_TITLE
13
+ l.pages.should == []
14
+ l.use_utc.should be_true
15
+ l.highchart_options.should == {}
16
+ end
17
+ end
18
+
19
+ describe "#page" do
20
+ it "should add page constructed by block to pages" do
21
+ layout.page "My Foo Page" do |p|
22
+ p.pie "foo_widget", sensor: sensor_name
23
+ p.spline "bar_widget" do |w|
24
+ w.sensor(sensor_name)
25
+ end
26
+ end
27
+ l = layout.to_layout
28
+ l.pages.size.should == 1
29
+ p = l.pages.first
30
+ p.title.should == "My Foo Page"
31
+ p.widgets.size.should == 2
32
+ p.widgets.first.title.should == "foo_widget"
33
+ p.widgets.last.title.should == "bar_widget"
34
+ end
35
+ end
36
+
37
+ describe "#title" do
38
+ it "should set layout title" do
39
+ layout.title "Foo Title"
40
+ layout.to_layout.title.should == 'Foo Title'
41
+ end
42
+ end
43
+
44
+ describe "#use_utc" do
45
+ it "should set use_utc" do
46
+ layout.use_utc false
47
+ layout.to_layout.use_utc.should be_false
48
+ end
49
+ end
50
+
51
+ describe "#highchart_options" do
52
+ it "should set highchart_options" do
53
+ layout.highchart_options({b: 1})
54
+ layout.to_layout.highchart_options.should == {b: 1}
55
+ end
56
+ end
57
+
58
+ describe "#to_layout" do
59
+ it "should convert layout dsl data to Visualize::Layout" do
60
+ layout.to_layout.should be_kind_of(PulseMeter::Visualize::Layout)
61
+ end
62
+ end
63
+ end
64
+
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Visualize::DSL::Page do
4
+ let(:interval){ 100 }
5
+ let(:sensor_name) { "some_sensor" }
6
+ let!(:sensor){ PulseMeter::Sensor::Timelined::Max.new(sensor_name, :ttl => 1000, :interval => interval) }
7
+ let(:title) { "page title" }
8
+ let(:page){ PulseMeter::Visualize::DSL::Page.new(title) }
9
+
10
+ describe '.new' do
11
+ it "should initialize title and widgets" do
12
+ p = page.to_page
13
+ p.title.should == title
14
+ p.widgets.should == []
15
+ end
16
+ end
17
+
18
+ describe '#widget' do
19
+ it "should add widget initialized by args to widgets" do
20
+ page.widget(:some_widget_type, :some_widget_name, sensor: sensor_name, width: 7)
21
+ w = page.to_page.widgets.first
22
+ w.width.should == 7
23
+ w.type.should == :some_widget_type
24
+ w.title.should == "some_widget_name"
25
+ w.sensors.first.name.should == sensor_name
26
+ end
27
+
28
+ it "should add widget initialized by block" do
29
+ page.widget(:some_widget_type, :some_widget_name) do |w|
30
+ w.sensor(sensor_name)
31
+ w.sensor(sensor_name)
32
+ w.title "foo_widget"
33
+ w.width 7
34
+ end
35
+ w = page.to_page.widgets.first
36
+ w.type.should == :some_widget_type
37
+ w.width.should == 7
38
+ w.title.should == "foo_widget"
39
+ w.sensors.size.should == 2
40
+ w.sensors.first.name.should == sensor_name
41
+ w.sensors.last.name.should == sensor_name
42
+ end
43
+ end
44
+
45
+ describe "#pie" do
46
+ it "should create widget width type :pie" do
47
+ page.pie(:some_widget_name)
48
+ w = page.to_page.widgets.first
49
+ w.type.should == :pie
50
+ end
51
+ end
52
+
53
+ describe "#chart" do
54
+ it "should create widget width type :chart" do
55
+ page.spline(:some_widget_name)
56
+ w = page.to_page.widgets.first
57
+ w.type.should == :spline
58
+ end
59
+ end
60
+
61
+ describe "#title" do
62
+ it "should set page title" do
63
+ page.title "Foo Title"
64
+ page.to_page.title.should == 'Foo Title'
65
+ end
66
+ end
67
+
68
+ describe "#to_page" do
69
+ it "should convert DSL data to Visualize::Page" do
70
+ page.to_page.should be_kind_of(PulseMeter::Visualize::Page)
71
+ end
72
+ end
73
+
74
+ end
75
+
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Visualize::DSL::Sensor do
4
+ let(:interval){ 100 }
5
+ let(:name) { "some_sensor" }
6
+ let!(:sensor){ PulseMeter::Sensor::Timelined::Max.new(name, :ttl => 1000, :interval => interval) }
7
+
8
+ describe '.new' do
9
+ it "should save passed name and create Visualize::Sensor with it" do
10
+ described_class.new(name).to_sensor.name.to_s.should == name
11
+ end
12
+ end
13
+
14
+ describe '#process_args' do
15
+ it "should pass args transparently to Visualize::Sensor" do
16
+ s = described_class.new(name)
17
+ s.process_args :color => :red
18
+ s.to_sensor.color.to_s.should == 'red'
19
+ end
20
+ end
21
+
22
+ describe '#to_sensor' do
23
+ # actually tested above
24
+ it "should convert dsl data to sensor" do
25
+ described_class.new(name).to_sensor.should be_kind_of(PulseMeter::Visualize::Sensor)
26
+ end
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Visualize::DSL::Widget do
4
+ let(:interval){ 100 }
5
+ let(:name) { "some_sensor" }
6
+ let!(:sensor){ PulseMeter::Sensor::Timelined::Max.new(name, :ttl => 1000, :interval => interval) }
7
+
8
+ let(:type) { :some_type }
9
+ let(:widget_name){ "some_widget" }
10
+ let(:w){ described_class.new(type, widget_name) }
11
+
12
+ describe '.new' do
13
+ it "should raise exception if type arg is empty" do
14
+ lambda{ described_class.new('', widget_name) }.should raise_exception(PulseMeter::Visualize::DSL::BadWidgetType)
15
+ end
16
+
17
+ it "should set default values for name, title, width, values_label. redraw_interval, show_last_point paprams" do
18
+ wid = w.to_widget
19
+ wid.type.should == :some_type
20
+ wid.width.should == PulseMeter::Visualize::DSL::Widget::DEFAULT_WIDTH
21
+ wid.title.should == widget_name
22
+ wid.sensors.should == []
23
+ wid.values_label.should == ''
24
+ wid.redraw_interval.should be_nil
25
+ wid.show_last_point.should be_false
26
+ end
27
+ end
28
+
29
+ describe "#process_args" do
30
+ it "should set sensor by :sensor param" do
31
+ w.process_args :sensor => :sss
32
+ sensors = w.to_widget.sensors
33
+ sensors.size.should == 1
34
+ sensors.first.name.to_s.should == 'sss'
35
+ end
36
+
37
+ it "should set title by :title param" do
38
+ w.process_args :title => 'Title XXX'
39
+ w.to_widget.title.should == 'Title XXX'
40
+ end
41
+
42
+ it "should set width by :width param" do
43
+ w.process_args :width => 5
44
+ w.to_widget.width.should == 5
45
+ end
46
+
47
+ it "should set values_label by :values_label param" do
48
+ w.process_args :values_label => "some y-axis legend"
49
+ w.to_widget.values_label.should == "some y-axis legend"
50
+ end
51
+ end
52
+
53
+ describe "#sensor" do
54
+ it "should add sensor" do
55
+ w.sensor :s1
56
+ w.sensor :s2
57
+ sensors = w.to_widget.sensors
58
+ sensors.size.should == 2
59
+ sensors.first.name.to_s.should == 's1'
60
+ sensors.last.name.to_s.should == 's2'
61
+ end
62
+ end
63
+
64
+ describe "#title" do
65
+ it "should set title" do
66
+ w.title 'Title XXX'
67
+ w.to_widget.title.should == 'Title XXX'
68
+ w.title 'Title YYY'
69
+ w.to_widget.title.should == 'Title YYY'
70
+ end
71
+ end
72
+
73
+ describe "#width" do
74
+ it "should set width" do
75
+ w.width 6
76
+ w.to_widget.width.should == 6
77
+ end
78
+
79
+ it "should raise exception if width is invalid" do
80
+ expect { w.width -1 }.to raise_exception(PulseMeter::Visualize::DSL::BadWidgetWidth)
81
+ expect { w.width 11 }.to raise_exception(PulseMeter::Visualize::DSL::BadWidgetWidth)
82
+ end
83
+ end
84
+
85
+ describe "#values_label" do
86
+ it "should set values_label" do
87
+ w.values_label "some y-axis legend"
88
+ w.to_widget.values_label.should == "some y-axis legend"
89
+ end
90
+ end
91
+
92
+ describe "#show_last_point" do
93
+ it "should set show_last_point" do
94
+ w.show_last_point true
95
+ w.to_widget.show_last_point.should be_true
96
+ end
97
+ end
98
+
99
+ describe "#redraw_interval" do
100
+ it "should set redraw_interval" do
101
+ w.redraw_interval 5
102
+ w.to_widget.redraw_interval.should == 5
103
+ end
104
+ it "should raise exception if redraw_interval is negative" do
105
+ expect{ w.redraw_interval(-1) }.to raise_exception(PulseMeter::Visualize::DSL::BadWidgetRedrawInterval)
106
+ end
107
+
108
+ end
109
+
110
+ describe "#timespan" do
111
+ it "should set timespan" do
112
+ w.timespan 5
113
+ w.to_widget.timespan.should == 5
114
+ end
115
+ it "should raise exception if timespan is negative" do
116
+ expect{ w.timespan(-1) }.to raise_exception(PulseMeter::Visualize::DSL::BadWidgetTimeSpan)
117
+ end
118
+
119
+ end
120
+
121
+ describe "#to_widget" do
122
+ it "should convert dsl data to widget" do
123
+ w.to_widget.should be_kind_of(PulseMeter::Visualize::Widget)
124
+ end
125
+ end
126
+ end
127
+
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::Layout do
4
+ let(:layout) do
5
+ l = PulseMeter::Visualize::DSL::Layout.new
6
+ l.page "page1" do |p|
7
+ p.line "w1"
8
+ p.spline "w2"
9
+ p.highchart_options({a: 1})
10
+ end
11
+ l.page "page2" do |p|
12
+ p.line "w3"
13
+ p.spline "w4"
14
+ end
15
+ l.to_layout
16
+ end
17
+
18
+ describe "#page_infos" do
19
+ it "should return list of page infos with ids" do
20
+ layout.page_infos.should == [
21
+ {title: "page1", id: 1, highchart_options: {a: 1}},
22
+ {title: "page2", id: 2, highchart_options: {}}
23
+ ]
24
+ end
25
+ end
26
+
27
+ describe "#options" do
28
+ it "should return layout options" do
29
+ ldsl = PulseMeter::Visualize::DSL::Layout.new
30
+ ldsl.use_utc true
31
+ ldsl.outlier_color '#RED'
32
+ ldsl.highchart_options({a: 1})
33
+ l = ldsl.to_layout
34
+ l.options.should == {use_utc: true, outlier_color: '#RED', highchart_options: {a: 1}}
35
+ end
36
+ end
37
+
38
+ describe "#widget" do
39
+ it "should return data for correct widget" do
40
+ w = layout.widget(1, 0)
41
+ w.should include(id: 1, title: "w3")
42
+ w = layout.widget(0, 1)
43
+ w.should include(id: 2, title: "w2")
44
+ end
45
+ end
46
+
47
+ describe "#widgets" do
48
+ it "should return data for correct widgets of a page" do
49
+ datas = layout.widgets(1)
50
+ datas[0].should include(id: 1, title: "w3")
51
+ datas[1].should include(id: 2, title: "w4")
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,150 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::Page do
4
+ let(:interval){ 100 }
5
+ let!(:a_sensor){ PulseMeter::Sensor::Timelined::Counter.new(:a_sensor, :ttl => 1000, :interval => interval, annotation: 'A') }
6
+ let!(:b_sensor){ PulseMeter::Sensor::Timelined::Counter.new(:b_sensor, :ttl => 1000, :interval => interval, annotation: 'B') }
7
+
8
+ let(:type) { :some_type }
9
+ let(:widget_name){ "some_widget" }
10
+
11
+ let(:redraw_interval){5}
12
+ let(:values_label){'xxxx'}
13
+ let(:width){6}
14
+ let(:show_last_point){false}
15
+ let(:timespan){interval * 2}
16
+ let(:a_color){'#FF0000'}
17
+ let(:b_color){'#FFFF00'}
18
+
19
+ let(:interval_start){ Time.at((Time.now.to_i / interval) * interval) }
20
+ let(:page_title){"Dashboard"}
21
+
22
+
23
+ let(:page) do
24
+ p = PulseMeter::Visualize::DSL::Page.new(page_title)
25
+ p.pie(widget_name) do |w|
26
+ w.redraw_interval redraw_interval
27
+ w.values_label values_label
28
+ w.width width
29
+ w.show_last_point show_last_point
30
+ w.timespan timespan
31
+
32
+ w.sensor :a_sensor, color: a_color
33
+ w.sensor :b_sensor, color: b_color
34
+ end
35
+ p.line(widget_name) do |w|
36
+ w.redraw_interval redraw_interval
37
+ w.values_label values_label
38
+ w.width width
39
+ w.show_last_point show_last_point
40
+ w.timespan timespan
41
+
42
+ w.sensor :a_sensor, color: a_color
43
+ w.sensor :b_sensor, color: b_color
44
+ end
45
+ p.to_page
46
+ end
47
+
48
+ before(:each) do
49
+ Timecop.freeze(interval_start + 1) do
50
+ a_sensor.event(12)
51
+ b_sensor.event(33)
52
+ end
53
+ Timecop.freeze(interval_start + interval + 1) do
54
+ a_sensor.event(111)
55
+ end
56
+ end
57
+
58
+ describe "#widget_data" do
59
+
60
+ it "should generate correct data of single widget" do
61
+ Timecop.freeze(interval_start + 2 * interval - 1) do
62
+ page.widget_data(0)[:id].should == 1
63
+ page.widget_data(1)[:id].should == 2
64
+ end
65
+ end
66
+
67
+ it "should generate correct data of single widget" do
68
+ Timecop.freeze(interval_start + 2 * interval - 1) do
69
+ page.widget_data(0)[:series].should ==
70
+ [
71
+ {
72
+ type: :pie,
73
+ name: values_label,
74
+ data: [
75
+ {
76
+ name: a_sensor.annotation,
77
+ color: a_color,
78
+ y: 12
79
+ },
80
+ {
81
+ name: b_sensor.annotation,
82
+ color: b_color,
83
+ y: 33
84
+ }
85
+ ]
86
+
87
+ }
88
+ ]
89
+ page.widget_data(1)[:series].should ==
90
+ [{
91
+ name: a_sensor.annotation,
92
+ color: a_color,
93
+ data: [{x: interval_start.to_i * 1000, y: 12}]
94
+ }, {
95
+ name: b_sensor.annotation,
96
+ color: b_color,
97
+ data: [{x: interval_start.to_i * 1000, y: 33}]
98
+ }]
99
+ end
100
+
101
+
102
+ end
103
+ end
104
+
105
+ describe "#widget_datas" do
106
+ it "should generate correct ids for all widgets" do
107
+ Timecop.freeze(interval_start + 2 * interval - 1) do
108
+ page.widget_datas.map{|h| h[:id]}.should == [1,2]
109
+ end
110
+ end
111
+
112
+ it "should generate correct series data of all widgets" do
113
+ Timecop.freeze(interval_start + 2 * interval - 1) do
114
+
115
+ page.widget_datas.map{|h| h[:series]}.should == [
116
+ [
117
+ {
118
+ type: :pie,
119
+ name: values_label,
120
+ data: [
121
+ {
122
+ name: a_sensor.annotation,
123
+ color: a_color,
124
+ y: 12
125
+ },
126
+ {
127
+ name: b_sensor.annotation,
128
+ color: b_color,
129
+ y: 33
130
+ }
131
+ ]
132
+
133
+ }
134
+ ],
135
+ [{
136
+ name: a_sensor.annotation,
137
+ color: a_color,
138
+ data: [{x: interval_start.to_i * 1000, y: 12}]
139
+ }, {
140
+ name: b_sensor.annotation,
141
+ color: b_color,
142
+ data: [{x: interval_start.to_i * 1000, y: 33}]
143
+ }]
144
+ ]
145
+ end
146
+
147
+
148
+ end
149
+ end
150
+ end