pulse-meter 0.0.1

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