pulse_meter-dygraphs_visualizer 0.4.15

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 (109) 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 +9 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +22 -0
  8. data/Procfile +3 -0
  9. data/README.md +40 -0
  10. data/Rakefile +54 -0
  11. data/examples/basic.ru +125 -0
  12. data/examples/basic_sensor_data.rb +97 -0
  13. data/lib/pulse_meter/dygraphs_visualize/app.rb +78 -0
  14. data/lib/pulse_meter/dygraphs_visualize/base.rb +15 -0
  15. data/lib/pulse_meter/dygraphs_visualize/coffee/application.coffee +37 -0
  16. data/lib/pulse_meter/dygraphs_visualize/coffee/collections/page_info_list.coffee +17 -0
  17. data/lib/pulse_meter/dygraphs_visualize/coffee/collections/sensor_info_list.coffee +4 -0
  18. data/lib/pulse_meter/dygraphs_visualize/coffee/collections/widget_list.coffee +14 -0
  19. data/lib/pulse_meter/dygraphs_visualize/coffee/extensions.coffee +26 -0
  20. data/lib/pulse_meter/dygraphs_visualize/coffee/models/dinamic_widget.coffee +34 -0
  21. data/lib/pulse_meter/dygraphs_visualize/coffee/models/page_info.coffee +2 -0
  22. data/lib/pulse_meter/dygraphs_visualize/coffee/models/sensor_info.coffee +2 -0
  23. data/lib/pulse_meter/dygraphs_visualize/coffee/models/widget.coffee +63 -0
  24. data/lib/pulse_meter/dygraphs_visualize/coffee/presenters/line.coffee +1 -0
  25. data/lib/pulse_meter/dygraphs_visualize/coffee/presenters/series.coffee +26 -0
  26. data/lib/pulse_meter/dygraphs_visualize/coffee/presenters/stack.coffee +1 -0
  27. data/lib/pulse_meter/dygraphs_visualize/coffee/presenters/timeline.coffee +13 -0
  28. data/lib/pulse_meter/dygraphs_visualize/coffee/presenters/widget.coffee +48 -0
  29. data/lib/pulse_meter/dygraphs_visualize/coffee/router.coffee +21 -0
  30. data/lib/pulse_meter/dygraphs_visualize/coffee/views/dynamic_chart.coffee +92 -0
  31. data/lib/pulse_meter/dygraphs_visualize/coffee/views/dynamic_widget.coffee +58 -0
  32. data/lib/pulse_meter/dygraphs_visualize/coffee/views/page_title.coffee +17 -0
  33. data/lib/pulse_meter/dygraphs_visualize/coffee/views/page_titles.coffee +15 -0
  34. data/lib/pulse_meter/dygraphs_visualize/coffee/views/sensor_info_list.coffee +19 -0
  35. data/lib/pulse_meter/dygraphs_visualize/coffee/views/widget.coffee +91 -0
  36. data/lib/pulse_meter/dygraphs_visualize/coffee/views/widget_chart.coffee +15 -0
  37. data/lib/pulse_meter/dygraphs_visualize/coffee/views/widget_list.coffee +15 -0
  38. data/lib/pulse_meter/dygraphs_visualize/dsl/base.rb +131 -0
  39. data/lib/pulse_meter/dygraphs_visualize/dsl/errors.rb +40 -0
  40. data/lib/pulse_meter/dygraphs_visualize/dsl/layout.rb +27 -0
  41. data/lib/pulse_meter/dygraphs_visualize/dsl/page.rb +26 -0
  42. data/lib/pulse_meter/dygraphs_visualize/dsl/sensor.rb +20 -0
  43. data/lib/pulse_meter/dygraphs_visualize/dsl/widget.rb +37 -0
  44. data/lib/pulse_meter/dygraphs_visualize/dsl/widgets/line.rb +22 -0
  45. data/lib/pulse_meter/dygraphs_visualize/dsl/widgets/stack.rb +29 -0
  46. data/lib/pulse_meter/dygraphs_visualize/layout.rb +79 -0
  47. data/lib/pulse_meter/dygraphs_visualize/page.rb +25 -0
  48. data/lib/pulse_meter/dygraphs_visualize/public/css/application.css +61 -0
  49. data/lib/pulse_meter/dygraphs_visualize/public/css/bootstrap.css +4883 -0
  50. data/lib/pulse_meter/dygraphs_visualize/public/css/bootstrap.min.css +729 -0
  51. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  52. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  53. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  54. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  55. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  56. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_glass_75_ffffff_1x400.png +0 -0
  57. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  58. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png +0 -0
  59. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-icons_222222_256x240.png +0 -0
  60. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-icons_2e83ff_256x240.png +0 -0
  61. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-icons_454545_256x240.png +0 -0
  62. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-icons_888888_256x240.png +0 -0
  63. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-icons_cd0a0a_256x240.png +0 -0
  64. data/lib/pulse_meter/dygraphs_visualize/public/css/images/ui-icons_f6cf3b_256x240.png +0 -0
  65. data/lib/pulse_meter/dygraphs_visualize/public/css/jquery-ui-1.8.16.bootstrap.css +1320 -0
  66. data/lib/pulse_meter/dygraphs_visualize/public/favicon.ico +208 -0
  67. data/lib/pulse_meter/dygraphs_visualize/public/img/glyphicons-halflings-white.png +0 -0
  68. data/lib/pulse_meter/dygraphs_visualize/public/img/glyphicons-halflings.png +0 -0
  69. data/lib/pulse_meter/dygraphs_visualize/public/js/application.js +833 -0
  70. data/lib/pulse_meter/dygraphs_visualize/public/js/backbone-min.js +38 -0
  71. data/lib/pulse_meter/dygraphs_visualize/public/js/bootstrap.js +1835 -0
  72. data/lib/pulse_meter/dygraphs_visualize/public/js/dygraph-combined.js +2 -0
  73. data/lib/pulse_meter/dygraphs_visualize/public/js/jquery-1.7.2.min.js +4 -0
  74. data/lib/pulse_meter/dygraphs_visualize/public/js/jquery-ui-1.8.16.bootstrap.min.js +791 -0
  75. data/lib/pulse_meter/dygraphs_visualize/public/js/jquery-ui-1.8.23.custom.min.js +21 -0
  76. data/lib/pulse_meter/dygraphs_visualize/public/js/jquery-ui-timepicker-addon.js +1687 -0
  77. data/lib/pulse_meter/dygraphs_visualize/public/js/json2.js +487 -0
  78. data/lib/pulse_meter/dygraphs_visualize/public/js/underscore-min.js +32 -0
  79. data/lib/pulse_meter/dygraphs_visualize/sensor.rb +63 -0
  80. data/lib/pulse_meter/dygraphs_visualize/series_color.rb +39 -0
  81. data/lib/pulse_meter/dygraphs_visualize/series_extractor.rb +107 -0
  82. data/lib/pulse_meter/dygraphs_visualize/views/main.haml +30 -0
  83. data/lib/pulse_meter/dygraphs_visualize/views/sensors.haml +75 -0
  84. data/lib/pulse_meter/dygraphs_visualize/views/widgets/extend_options.haml +11 -0
  85. data/lib/pulse_meter/dygraphs_visualize/views/widgets/line.haml +43 -0
  86. data/lib/pulse_meter/dygraphs_visualize/views/widgets/stack.haml +43 -0
  87. data/lib/pulse_meter/dygraphs_visualize/widget.rb +38 -0
  88. data/lib/pulse_meter/dygraphs_visualize/widgets/timeline.rb +107 -0
  89. data/lib/pulse_meter/dygraphs_visualizer.rb +34 -0
  90. data/lib/pulse_meter_dygraphs_visualizer.rb +2 -0
  91. data/pulse_meter-dygraphs_visualizer.gemspec +41 -0
  92. data/spec/pulse_meter/dygraphs_visualize/app_spec.rb +27 -0
  93. data/spec/pulse_meter/dygraphs_visualize/dsl/layout_spec.rb +64 -0
  94. data/spec/pulse_meter/dygraphs_visualize/dsl/page_spec.rb +62 -0
  95. data/spec/pulse_meter/dygraphs_visualize/dsl/sensor_spec.rb +30 -0
  96. data/spec/pulse_meter/dygraphs_visualize/dsl/widget_spec.rb +6 -0
  97. data/spec/pulse_meter/dygraphs_visualize/dsl/widgets/line_spec.rb +44 -0
  98. data/spec/pulse_meter/dygraphs_visualize/dsl/widgets/stack_spec.rb +55 -0
  99. data/spec/pulse_meter/dygraphs_visualize/layout_spec.rb +54 -0
  100. data/spec/pulse_meter/dygraphs_visualize/page_spec.rb +145 -0
  101. data/spec/pulse_meter/dygraphs_visualize/sensor_spec.rb +120 -0
  102. data/spec/pulse_meter/dygraphs_visualize/series_extractor_spec.rb +80 -0
  103. data/spec/pulse_meter/dygraphs_visualize/widgets/line_spec.rb +6 -0
  104. data/spec/pulse_meter/dygraphs_visualize/widgets/stack_spec.rb +6 -0
  105. data/spec/pulse_meter/dygraphs_visualizer_spec.rb +42 -0
  106. data/spec/shared_examples/dsl_widget.rb +106 -0
  107. data/spec/shared_examples/widget.rb +97 -0
  108. data/spec/spec_helper.rb +36 -0
  109. metadata +497 -0
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::DygraphsVisualize::DSL::Widgets::Stack do
4
+ it_should_behave_like "dsl widget"
5
+
6
+ let(:interval){ 100 }
7
+ let(:name) { "some_sensor" }
8
+ let!(:sensor){ PulseMeter::Sensor::Timelined::Max.new(name, :ttl => 1000, :interval => interval) }
9
+
10
+ let(:widget_name){ "some_widget" }
11
+ let(:w){ described_class.new(widget_name) }
12
+
13
+ describe "#to_data" do
14
+ let(:data){ w.to_data }
15
+
16
+ it "should produce PulseMeter::DygraphsVisualize::Widgets::Stack class" do
17
+ data.should be_kind_of(PulseMeter::DygraphsVisualize::Widgets::Stack)
18
+ end
19
+
20
+ describe "dygraphs_options" do
21
+ let(:dygraphs_options){ data.dygraphs_options }
22
+
23
+ it "should set stack Dygraphs options" do
24
+ dygraphs_options[:stacked_graph].should be_true
25
+ dygraphs_options[:stacked_graph_na_n_fill].should == 'inside'
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "#values_label" do
31
+ it "should set values_label" do
32
+ w.values_label "some y-axis legend"
33
+ w.to_data.values_label.should == "some y-axis legend"
34
+ end
35
+ end
36
+
37
+ describe "#show_last_point" do
38
+ it "should set show_last_point" do
39
+ w.show_last_point true
40
+ w.to_data.show_last_point.should be_true
41
+ end
42
+ end
43
+
44
+ describe "#timespan" do
45
+ it "should set timespan" do
46
+ w.timespan 5
47
+ w.to_data.timespan.should == 5
48
+ end
49
+ it "should raise exception if timespan is negative" do
50
+ expect{ w.timespan(-1) }.to raise_exception(PulseMeter::DygraphsVisualize::DSL::BadWidgetTimeSpan)
51
+ end
52
+ end
53
+
54
+ end
55
+
@@ -0,0 +1,54 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::DygraphsVisualize::Layout do
4
+ let(:layout) do
5
+ l = PulseMeter::DygraphsVisualize::DSL::Layout.new
6
+ l.page "page1" do |p|
7
+ p.line "w1"
8
+ p.line "w2"
9
+ p.dygraphs_options({a: 1})
10
+ end
11
+ l.page "page2" do |p|
12
+ p.line "w3"
13
+ p.line "w4"
14
+ end
15
+ l.to_data
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, dygraphs_options: {a: 1}},
22
+ {title: "page2", id: 2, dygraphs_options: {}}
23
+ ]
24
+ end
25
+ end
26
+
27
+ describe "#options" do
28
+ it "should return layout options" do
29
+ ldsl = PulseMeter::DygraphsVisualize::DSL::Layout.new
30
+ ldsl.use_utc true
31
+ ldsl.dygraphs_options({a: 1})
32
+ l = ldsl.to_data
33
+ l.options.should == {use_utc: true, dygraphs_options: {a: 1}}
34
+ end
35
+ end
36
+
37
+ describe "#widget" do
38
+ it "should return data for correct widget" do
39
+ w = layout.widget(1, 0)
40
+ w.should include(id: 1, title: "w3")
41
+ w = layout.widget(0, 1, timespan: 123)
42
+ w.should include(id: 2, title: "w2")
43
+ end
44
+ end
45
+
46
+ describe "#widgets" do
47
+ it "should return data for correct widgets of a page" do
48
+ datas = layout.widgets(1)
49
+ datas[0].should include(id: 1, title: "w3")
50
+ datas[1].should include(id: 2, title: "w4")
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,145 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::DygraphsVisualize::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::DygraphsVisualize::DSL::Page.new(page_title)
25
+ p.line(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_data
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
+ titles: [a_sensor.annotation, b_sensor.annotation],
72
+ rows: [[interval_start.to_i * 1000, 12, 33]],
73
+ options: [
74
+ {color: a_color},
75
+ {color: b_color}
76
+ ]
77
+ }
78
+ page.widget_data(1)[:series].should ==
79
+ {
80
+ titles: [a_sensor.annotation, b_sensor.annotation],
81
+ rows: [[interval_start.to_i * 1000, 12, 33]],
82
+ options: [
83
+ {color: a_color},
84
+ {color: b_color}
85
+ ]
86
+ }
87
+ end
88
+
89
+ Timecop.freeze(interval_start + 2 * interval - 1) do
90
+ page.widget_data(0, timespan: 0)[:series].should ==
91
+ {
92
+ titles: [a_sensor.annotation, b_sensor.annotation],
93
+ rows: [],
94
+ options: [
95
+ {color: a_color},
96
+ {color: b_color}
97
+ ]
98
+ }
99
+ page.widget_data(1, timespan: 1)[:series].should ==
100
+ {
101
+ titles: [a_sensor.annotation, b_sensor.annotation],
102
+ rows: [],
103
+ options: [
104
+ {color: a_color},
105
+ {color: b_color}
106
+ ]
107
+ }
108
+
109
+ end
110
+ end
111
+ end
112
+
113
+ describe "#widget_datas" do
114
+ it "should generate correct ids for all widgets" do
115
+ Timecop.freeze(interval_start + 2 * interval - 1) do
116
+ page.widget_datas.map{|h| h[:id]}.should == [1,2]
117
+ end
118
+ end
119
+
120
+ it "should generate correct series data of all widgets" do
121
+ Timecop.freeze(interval_start + 2 * interval - 1) do
122
+
123
+ page.widget_datas.map{|h| h[:series]}.should == [
124
+ {
125
+ titles: [a_sensor.annotation, b_sensor.annotation],
126
+ rows: [[interval_start.to_i * 1000, 12, 33]],
127
+ options: [
128
+ {color: a_color},
129
+ {color: b_color}
130
+ ]
131
+ },
132
+ {
133
+ titles: [a_sensor.annotation, b_sensor.annotation],
134
+ rows: [[interval_start.to_i * 1000, 12, 33]],
135
+ options: [
136
+ {color: a_color},
137
+ {color: b_color}
138
+ ]
139
+ }
140
+ ]
141
+ end
142
+
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,120 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::DygraphsVisualize::Sensor do
4
+ let(:interval){ 100 }
5
+ let(:name) { "some_sensor" }
6
+ let(:annotation) { 'sensor descr' }
7
+ let!(:real_sensor){ PulseMeter::Sensor::Timelined::Counter.new(name, ttl: 1000, interval: interval, annotation: annotation) }
8
+ let(:sensor) { described_class.new(name: name) }
9
+
10
+ let(:color){ '#ABCDEF' }
11
+ let(:sensor_with_color) { described_class.new(name: name, color: color) }
12
+
13
+ let(:bad_sensor) { described_class.new(name: "bad_sensor_name") }
14
+ let(:interval_start){ Time.at((Time.now.to_i / interval) * interval) }
15
+
16
+ describe '#last_value' do
17
+ context "when sensor does not exist" do
18
+ it "should raise RestoreError" do
19
+ expect{ bad_sensor.last_value(Time.now) }.to raise_exception(PulseMeter::RestoreError)
20
+ end
21
+ end
22
+
23
+
24
+ context "when sensor has no data" do
25
+ it "should return nil" do
26
+ sensor.last_value(Time.now).should be_nil
27
+ end
28
+ end
29
+
30
+ context "when sensor has data" do
31
+ context "when need_incomplete arg is true" do
32
+ it "should return last value" do
33
+ Timecop.freeze(interval_start) do
34
+ real_sensor.event(101)
35
+ end
36
+ Timecop.freeze(interval_start+1) do
37
+ sensor.last_value(Time.now, true).should == 101
38
+ end
39
+ end
40
+ end
41
+
42
+ context "when need_incomplete arg is false" do
43
+ it "should return last complete value" do
44
+ Timecop.freeze(interval_start) do
45
+ real_sensor.event(101)
46
+ end
47
+ Timecop.freeze(interval_start + 1) do
48
+ sensor.last_value(Time.now).should be_nil
49
+ end
50
+ Timecop.freeze(interval_start + interval + 1) do
51
+ sensor.last_value(Time.now).should == 101
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+
59
+ describe "#last_point_data" do
60
+
61
+ context "when sensor does not exist" do
62
+ it "should raise RestoreError" do
63
+ expect{ bad_sensor.last_point_data(Time.now) }.to raise_exception(PulseMeter::RestoreError)
64
+ end
65
+ end
66
+
67
+ it "should return last value with annotation (and color)" do
68
+ Timecop.freeze(interval_start) do
69
+ real_sensor.event(101)
70
+ end
71
+ Timecop.freeze(interval_start + 1) do
72
+ sensor.last_point_data(Time.now, true).should == [{name: annotation, y: 101}]
73
+ sensor.last_point_data(Time.now).should == [{name: annotation, y: nil}]
74
+ sensor_with_color.last_point_data(Time.now, true).should == [{name: annotation, y: 101, color: color}]
75
+ sensor_with_color.last_point_data(Time.now).should == [{name: annotation, y: nil, color: color}]
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "#timeline_data" do
81
+ before(:each) do
82
+ Timecop.freeze(interval_start) do
83
+ real_sensor.event(101)
84
+ end
85
+ Timecop.freeze(interval_start + interval) do
86
+ real_sensor.event(55)
87
+ end
88
+ end
89
+
90
+ context "when sensor does not exist" do
91
+ it "should raise RestoreError" do
92
+ expect{ bad_sensor.timeline_data(Time.now - interval, Time.now) }.to raise_exception(PulseMeter::RestoreError)
93
+ end
94
+ end
95
+
96
+
97
+ describe "returned value" do
98
+ it "should contain sensor annotation" do
99
+ Timecop.freeze(interval_start + interval + 1) do
100
+ sensor.timeline_data(Time.now - interval, Time.now).first[:name].should == annotation
101
+ end
102
+ end
103
+ it "should contain sensor color" do
104
+ Timecop.freeze(interval_start + interval + 1) do
105
+ sensor_with_color.timeline_data(Time.now - interval, Time.now).first[:color].should == color
106
+ end
107
+ end
108
+
109
+ it "should contain [interval_start, value] pairs for each interval" do
110
+ Timecop.freeze(interval_start + interval + 1) do
111
+ data = sensor.timeline_data(Time.now - interval * 2, Time.now)
112
+ data.first[:data].should == [{x: interval_start.to_i * 1000, y: 101}]
113
+ data = sensor.timeline_data(Time.now - interval * 2, Time.now, true)
114
+ data.first[:data].should == [{x: interval_start.to_i * 1000, y: 101}, {x: (interval_start + interval).to_i * 1000, y: 55}]
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,80 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::DygraphsVisualize::SeriesExtractor do
4
+ let(:interval){ 100 }
5
+ let!(:real_simple_sensor){ PulseMeter::Sensor::Timelined::Counter.new(:simple_sensor,
6
+ ttl: 1000,
7
+ interval: interval,
8
+ annotation: 'simple sensor'
9
+ ) }
10
+ let!(:real_hashed_sensor){ PulseMeter::Sensor::Timelined::HashedCounter.new(:hashed_sensor,
11
+ ttl: 1000,
12
+ interval: interval,
13
+ annotation: 'hashed sensor'
14
+ ) }
15
+
16
+ let!(:simple_sensor){PulseMeter::DygraphsVisualize::Sensor.new(name: :simple_sensor)}
17
+ let!(:hashed_sensor){PulseMeter::DygraphsVisualize::Sensor.new(name: :hashed_sensor)}
18
+
19
+ describe "simple extractor" do
20
+
21
+ let(:extractor) {PulseMeter::DygraphsVisualize.extractor(simple_sensor)}
22
+
23
+ it "should be created for simple sensors" do
24
+ extractor.should be_kind_of(PulseMeter::DygraphsVisualize::SeriesExtractor::Simple)
25
+ end
26
+
27
+ it "should create point data correctly" do
28
+ extractor.point_data(123).should == [{y: 123, name: 'simple sensor'}]
29
+ end
30
+
31
+ it "should create timeline data correctly" do
32
+ tl_data = [
33
+ PulseMeter::SensorData.new(Time.at(1), 11),
34
+ PulseMeter::SensorData.new(Time.at(2), "22")
35
+ ]
36
+ extractor.series_data(tl_data).should == [{
37
+ name: 'simple sensor',
38
+ data: [{x: 1000, y: 11}, {x: 2000, y: 22}]
39
+ }]
40
+ end
41
+
42
+ end
43
+
44
+ describe "hash extractor" do
45
+ let(:extractor) {PulseMeter::DygraphsVisualize.extractor(hashed_sensor)}
46
+
47
+ it "should be created for hash sensors" do
48
+ extractor.should be_kind_of(PulseMeter::DygraphsVisualize::SeriesExtractor::Hashed)
49
+ end
50
+
51
+ it "should create point data correctly" do
52
+ extractor.point_data('{"x": 123, "y": 321}').should == [
53
+ {y: 123, name: 'hashed sensor: x'},
54
+ {y: 321, name: 'hashed sensor: y'}
55
+ ]
56
+ end
57
+
58
+ it "should create timeline data correctly" do
59
+ tl_data = [
60
+ PulseMeter::SensorData.new(Time.at(1), {"a" => 5, "b" => 6}),
61
+ PulseMeter::SensorData.new(Time.at(2), '{"c": 7, "b": 6}')
62
+ ]
63
+ extractor.series_data(tl_data).should == [
64
+ {
65
+ name: 'hashed sensor: a',
66
+ data: [{x: 1000, y: 5}, {x: 2000, y: nil}]
67
+ },
68
+ {
69
+ name: 'hashed sensor: b',
70
+ data: [{x: 1000, y: 6}, {x: 2000, y: 6}]
71
+ },
72
+ {
73
+ name: 'hashed sensor: c',
74
+ data: [{x: 1000, y: nil}, {x: 2000, y: 7}]
75
+ }
76
+ ]
77
+ end
78
+ end
79
+
80
+ end