pulse_meter_visualizer 0.4.11

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 (124) 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 +8 -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 +72 -0
  11. data/examples/basic.ru +145 -0
  12. data/examples/basic_sensor_data.rb +96 -0
  13. data/lib/pulse_meter/visualize/app.rb +78 -0
  14. data/lib/pulse_meter/visualize/base.rb +15 -0
  15. data/lib/pulse_meter/visualize/coffee/application.coffee +40 -0
  16. data/lib/pulse_meter/visualize/coffee/collections/page_info_list.coffee +17 -0
  17. data/lib/pulse_meter/visualize/coffee/collections/sensor_info_list.coffee +4 -0
  18. data/lib/pulse_meter/visualize/coffee/collections/widget_list.coffee +14 -0
  19. data/lib/pulse_meter/visualize/coffee/extensions.coffee +26 -0
  20. data/lib/pulse_meter/visualize/coffee/models/dinamic_widget.coffee +34 -0
  21. data/lib/pulse_meter/visualize/coffee/models/page_info.coffee +2 -0
  22. data/lib/pulse_meter/visualize/coffee/models/sensor_info.coffee +2 -0
  23. data/lib/pulse_meter/visualize/coffee/models/widget.coffee +54 -0
  24. data/lib/pulse_meter/visualize/coffee/presenters/area.coffee +2 -0
  25. data/lib/pulse_meter/visualize/coffee/presenters/gauge.coffee +11 -0
  26. data/lib/pulse_meter/visualize/coffee/presenters/line.coffee +2 -0
  27. data/lib/pulse_meter/visualize/coffee/presenters/pie.coffee +20 -0
  28. data/lib/pulse_meter/visualize/coffee/presenters/series.coffee +44 -0
  29. data/lib/pulse_meter/visualize/coffee/presenters/table.coffee +10 -0
  30. data/lib/pulse_meter/visualize/coffee/presenters/timeline.coffee +13 -0
  31. data/lib/pulse_meter/visualize/coffee/presenters/widget.coffee +65 -0
  32. data/lib/pulse_meter/visualize/coffee/router.coffee +21 -0
  33. data/lib/pulse_meter/visualize/coffee/views/dynamic_chart.coffee +91 -0
  34. data/lib/pulse_meter/visualize/coffee/views/dynamic_widget.coffee +58 -0
  35. data/lib/pulse_meter/visualize/coffee/views/page_title.coffee +17 -0
  36. data/lib/pulse_meter/visualize/coffee/views/page_titles.coffee +15 -0
  37. data/lib/pulse_meter/visualize/coffee/views/sensor_info_list.coffee +19 -0
  38. data/lib/pulse_meter/visualize/coffee/views/widget.coffee +99 -0
  39. data/lib/pulse_meter/visualize/coffee/views/widget_chart.coffee +13 -0
  40. data/lib/pulse_meter/visualize/coffee/views/widget_list.coffee +15 -0
  41. data/lib/pulse_meter/visualize/dsl/base.rb +131 -0
  42. data/lib/pulse_meter/visualize/dsl/errors.rb +40 -0
  43. data/lib/pulse_meter/visualize/dsl/layout.rb +27 -0
  44. data/lib/pulse_meter/visualize/dsl/page.rb +33 -0
  45. data/lib/pulse_meter/visualize/dsl/sensor.rb +20 -0
  46. data/lib/pulse_meter/visualize/dsl/widget.rb +37 -0
  47. data/lib/pulse_meter/visualize/dsl/widgets/area.rb +20 -0
  48. data/lib/pulse_meter/visualize/dsl/widgets/gauge.rb +12 -0
  49. data/lib/pulse_meter/visualize/dsl/widgets/line.rb +21 -0
  50. data/lib/pulse_meter/visualize/dsl/widgets/pie.rb +16 -0
  51. data/lib/pulse_meter/visualize/dsl/widgets/table.rb +19 -0
  52. data/lib/pulse_meter/visualize/layout.rb +79 -0
  53. data/lib/pulse_meter/visualize/page.rb +25 -0
  54. data/lib/pulse_meter/visualize/public/css/application.css +56 -0
  55. data/lib/pulse_meter/visualize/public/css/bootstrap.css +4883 -0
  56. data/lib/pulse_meter/visualize/public/css/bootstrap.min.css +729 -0
  57. data/lib/pulse_meter/visualize/public/css/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  58. data/lib/pulse_meter/visualize/public/css/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  59. data/lib/pulse_meter/visualize/public/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  60. data/lib/pulse_meter/visualize/public/css/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  61. data/lib/pulse_meter/visualize/public/css/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  62. data/lib/pulse_meter/visualize/public/css/images/ui-bg_glass_75_ffffff_1x400.png +0 -0
  63. data/lib/pulse_meter/visualize/public/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  64. data/lib/pulse_meter/visualize/public/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png +0 -0
  65. data/lib/pulse_meter/visualize/public/css/images/ui-icons_222222_256x240.png +0 -0
  66. data/lib/pulse_meter/visualize/public/css/images/ui-icons_2e83ff_256x240.png +0 -0
  67. data/lib/pulse_meter/visualize/public/css/images/ui-icons_454545_256x240.png +0 -0
  68. data/lib/pulse_meter/visualize/public/css/images/ui-icons_888888_256x240.png +0 -0
  69. data/lib/pulse_meter/visualize/public/css/images/ui-icons_cd0a0a_256x240.png +0 -0
  70. data/lib/pulse_meter/visualize/public/css/images/ui-icons_f6cf3b_256x240.png +0 -0
  71. data/lib/pulse_meter/visualize/public/css/jquery-ui-1.8.16.bootstrap.css +1320 -0
  72. data/lib/pulse_meter/visualize/public/favicon.ico +208 -0
  73. data/lib/pulse_meter/visualize/public/img/glyphicons-halflings-white.png +0 -0
  74. data/lib/pulse_meter/visualize/public/img/glyphicons-halflings.png +0 -0
  75. data/lib/pulse_meter/visualize/public/js/application.js +973 -0
  76. data/lib/pulse_meter/visualize/public/js/backbone-min.js +38 -0
  77. data/lib/pulse_meter/visualize/public/js/bootstrap.js +1835 -0
  78. data/lib/pulse_meter/visualize/public/js/jquery-1.7.2.min.js +4 -0
  79. data/lib/pulse_meter/visualize/public/js/jquery-ui-1.8.16.bootstrap.min.js +791 -0
  80. data/lib/pulse_meter/visualize/public/js/jquery-ui-1.8.23.custom.min.js +21 -0
  81. data/lib/pulse_meter/visualize/public/js/jquery-ui-timepicker-addon.js +1687 -0
  82. data/lib/pulse_meter/visualize/public/js/json2.js +487 -0
  83. data/lib/pulse_meter/visualize/public/js/underscore-min.js +32 -0
  84. data/lib/pulse_meter/visualize/sensor.rb +63 -0
  85. data/lib/pulse_meter/visualize/series_extractor.rb +107 -0
  86. data/lib/pulse_meter/visualize/views/main.haml +30 -0
  87. data/lib/pulse_meter/visualize/views/sensors.haml +76 -0
  88. data/lib/pulse_meter/visualize/views/widgets/area.haml +53 -0
  89. data/lib/pulse_meter/visualize/views/widgets/extend_options.haml +11 -0
  90. data/lib/pulse_meter/visualize/views/widgets/gauge.haml +13 -0
  91. data/lib/pulse_meter/visualize/views/widgets/line.haml +54 -0
  92. data/lib/pulse_meter/visualize/views/widgets/pie.haml +13 -0
  93. data/lib/pulse_meter/visualize/views/widgets/table.haml +45 -0
  94. data/lib/pulse_meter/visualize/widget.rb +38 -0
  95. data/lib/pulse_meter/visualize/widgets/gauge.rb +47 -0
  96. data/lib/pulse_meter/visualize/widgets/pie.rb +36 -0
  97. data/lib/pulse_meter/visualize/widgets/timeline.rb +114 -0
  98. data/lib/pulse_meter/visualizer.rb +38 -0
  99. data/lib/pulse_meter_visualizer.rb +2 -0
  100. data/pulse_meter_visualizer.gemspec +41 -0
  101. data/spec/pulse_meter/visualize/app_spec.rb +27 -0
  102. data/spec/pulse_meter/visualize/dsl/layout_spec.rb +64 -0
  103. data/spec/pulse_meter/visualize/dsl/page_spec.rb +62 -0
  104. data/spec/pulse_meter/visualize/dsl/sensor_spec.rb +30 -0
  105. data/spec/pulse_meter/visualize/dsl/widget_spec.rb +6 -0
  106. data/spec/pulse_meter/visualize/dsl/widgets/area_spec.rb +44 -0
  107. data/spec/pulse_meter/visualize/dsl/widgets/gauge_spec.rb +22 -0
  108. data/spec/pulse_meter/visualize/dsl/widgets/line_spec.rb +44 -0
  109. data/spec/pulse_meter/visualize/dsl/widgets/pie_spec.rb +35 -0
  110. data/spec/pulse_meter/visualize/dsl/widgets/table_spec.rb +36 -0
  111. data/spec/pulse_meter/visualize/layout_spec.rb +54 -0
  112. data/spec/pulse_meter/visualize/page_spec.rb +153 -0
  113. data/spec/pulse_meter/visualize/sensor_spec.rb +120 -0
  114. data/spec/pulse_meter/visualize/series_extractor_spec.rb +80 -0
  115. data/spec/pulse_meter/visualize/widgets/area_spec.rb +6 -0
  116. data/spec/pulse_meter/visualize/widgets/gauge_spec.rb +63 -0
  117. data/spec/pulse_meter/visualize/widgets/line_spec.rb +6 -0
  118. data/spec/pulse_meter/visualize/widgets/pie_spec.rb +73 -0
  119. data/spec/pulse_meter/visualize/widgets/table_spec.rb +6 -0
  120. data/spec/pulse_meter/visualizer_spec.rb +42 -0
  121. data/spec/shared_examples/dsl_widget.rb +106 -0
  122. data/spec/shared_examples/widget.rb +97 -0
  123. data/spec/spec_helper.rb +36 -0
  124. metadata +518 -0
@@ -0,0 +1,120 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::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::Visualize::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::Visualize::Sensor.new(name: :simple_sensor)}
17
+ let!(:hashed_sensor){PulseMeter::Visualize::Sensor.new(name: :hashed_sensor)}
18
+
19
+ describe "simple extractor" do
20
+
21
+ let(:extractor) {PulseMeter::Visualize.extractor(simple_sensor)}
22
+
23
+ it "should be created for simple sensors" do
24
+ extractor.should be_kind_of(PulseMeter::Visualize::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::Visualize.extractor(hashed_sensor)}
46
+
47
+ it "should be created for hash sensors" do
48
+ extractor.should be_kind_of(PulseMeter::Visualize::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
@@ -0,0 +1,6 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::Widgets::Area do
4
+ it_should_behave_like "widget"
5
+ end
6
+
@@ -0,0 +1,63 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::Widgets::Gauge do
4
+ let(:interval){ 100 }
5
+ let!(:a_sensor){PulseMeter::Sensor::Indicator.new(:a_sensor, annotation: 'A')}
6
+ let!(:b_sensor){PulseMeter::Sensor::Indicator.new(:b_sensor, annotation: 'B')}
7
+ let!(:c_sensor){PulseMeter::Sensor::HashedIndicator.new(:c_sensor, annotation: 'C')}
8
+
9
+
10
+ let(:widget_name){ "some_widget" }
11
+
12
+ let(:redraw_interval){5}
13
+ let(:width){6}
14
+
15
+ let(:interval_start){ Time.at((Time.now.to_i / interval) * interval) }
16
+
17
+ let(:widget) do
18
+ w = PulseMeter::Visualize::DSL::Widgets::Gauge.new(widget_name)
19
+ w.redraw_interval redraw_interval
20
+ w.width width
21
+ w.sensor :a_sensor
22
+ w.sensor :b_sensor
23
+ w.sensor :c_sensor
24
+ w.gchart_options a: 1
25
+ w.to_data
26
+ end
27
+
28
+ describe "#data" do
29
+ it "should contain type, title, redraw_interval, width, gchart_options attriutes" do
30
+ wdata = widget.data
31
+ wdata[:type].should == 'gauge'
32
+ wdata[:title].should == widget_name
33
+ wdata[:redraw_interval].should == redraw_interval
34
+ wdata[:width].should == width
35
+ wdata[:gchart_options].should == {a: 1}
36
+ end
37
+
38
+ describe "series attribute" do
39
+ before(:each) do
40
+ a_sensor.event(12)
41
+ b_sensor.event(33)
42
+ c_sensor.event(:a => 44)
43
+ c_sensor.event(:b => 55)
44
+ end
45
+
46
+ it "should contain valid gauge slices" do
47
+
48
+ widget.data[:series].sort.should == [
49
+ ['A', 12],
50
+ ['B', 33],
51
+ ["C: a", 44],
52
+ ["C: b", 55]
53
+ ].sort
54
+
55
+ end
56
+
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+
63
+
@@ -0,0 +1,6 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::Widgets::Line do
4
+ it_should_behave_like "widget"
5
+ end
6
+
@@ -0,0 +1,73 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::Widgets::Pie 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(:widget_name){ "some_widget" }
9
+
10
+ let(:redraw_interval){5}
11
+ let(:values_label){'xxxx'}
12
+ let(:width){6}
13
+ let(:a_color){'#FF0000'}
14
+ let(:b_color){'#FFFF00'}
15
+
16
+ let(:interval_start){ Time.at((Time.now.to_i / interval) * interval) }
17
+
18
+ let(:widget) do
19
+ w = PulseMeter::Visualize::DSL::Widgets::Pie.new(widget_name)
20
+ w.redraw_interval redraw_interval
21
+ w.width width
22
+ w.sensor :a_sensor, color: a_color
23
+ w.sensor :b_sensor, color: b_color
24
+ w.gchart_options a: 1
25
+ w.to_data
26
+ end
27
+
28
+ describe "#data" do
29
+ it "should contain type, title, redraw_interval, width, gchart_options attriutes" do
30
+ wdata = widget.data
31
+ wdata[:type].should == 'pie'
32
+ wdata[:title].should == widget_name
33
+ wdata[:redraw_interval].should == redraw_interval
34
+ wdata[:width].should == width
35
+ wdata[:gchart_options].should == {a: 1}
36
+ end
37
+
38
+ describe "series attribute" do
39
+ before(:each) do
40
+ Timecop.freeze(interval_start + 1) do
41
+ a_sensor.event(12)
42
+ b_sensor.event(33)
43
+ end
44
+ Timecop.freeze(interval_start + interval + 1) do
45
+ a_sensor.event(111)
46
+ end
47
+ @current_time = interval_start + 2 * interval - 1
48
+ end
49
+
50
+ it "should contain valid pie slices" do
51
+
52
+ Timecop.freeze(@current_time) do
53
+ widget.data[:series].should ==
54
+ {
55
+ data: [
56
+ [a_sensor.annotation, 12],
57
+ [b_sensor.annotation, 33]
58
+ ],
59
+ options: [
60
+ {color: a_color},
61
+ {color: b_color}
62
+ ]
63
+ }
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
70
+ end
71
+
72
+
73
+
@@ -0,0 +1,6 @@
1
+ require "spec_helper"
2
+
3
+ describe PulseMeter::Visualize::Widgets::Table do
4
+ it_should_behave_like "widget"
5
+ end
6
+
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::Visualizer do
4
+ describe "::draw" do
5
+ it "should generate correct layout with passed block" do
6
+ layout = described_class.draw do |l|
7
+
8
+ l.title "My Gauges"
9
+
10
+ l.page "Dashboard" do |p|
11
+ p.line :convertion do |c|
12
+ c.sensor :adv_clicks, color: :green
13
+ c.sensor :adv_shows, color: :red
14
+ end
15
+
16
+ p.pie :agents, title: 'User Agents' do |c|
17
+ c.sensor :agent_ie
18
+ c.sensor :agent_chrome
19
+ c.sensor :agent_ff
20
+ c.sensor :agent_other
21
+ end
22
+
23
+ end
24
+
25
+ l.page "Request stats" do |p|
26
+ p.line :rph_total, sensor: :rph_total
27
+ p.line :rph_main_page, sensor: :rph_main_page
28
+ p.line :request_time_p95_hour
29
+
30
+ p.pie :success_vs_fail_total_hourly do |w|
31
+ w.sensor :success_total_hourly
32
+ w.sensor :fail_total_hourly
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ layout.should be_kind_of(PulseMeter::Visualize::Layout)
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,106 @@
1
+ shared_examples_for "dsl widget" do
2
+
3
+ let(:interval){ 100 }
4
+ let(:name) { "some_sensor" }
5
+ let!(:sensor){ PulseMeter::Sensor::Timelined::Max.new(name, :ttl => 1000, :interval => interval) }
6
+
7
+ let(:widget_name){ "some_widget" }
8
+ let(:w){ described_class.new(widget_name) }
9
+
10
+ describe '.new' do
11
+ it "should set default value for width papram" do
12
+ wid = w.to_data
13
+ wid.width.should == PulseMeter::Visualize::DSL::Widget::MAX_WIDTH
14
+ end
15
+
16
+ it "should set title param from .new argument" do
17
+ wid = w.to_data
18
+ wid.title.should == widget_name
19
+ end
20
+ end
21
+
22
+ describe "#process_args" do
23
+ it "should set sensor by :sensor param" do
24
+ w.process_args :sensor => :sss
25
+ sensors = w.to_data.sensors
26
+ sensors.size.should == 1
27
+ sensors.first.name.to_s.should == 'sss'
28
+ end
29
+
30
+ it "should set title by :title param" do
31
+ w.process_args :title => 'Title XXX'
32
+ w.to_data.title.should == 'Title XXX'
33
+ end
34
+
35
+ it "should set width by :width param" do
36
+ w.process_args :width => 5
37
+ w.to_data.width.should == 5
38
+ end
39
+
40
+ end
41
+
42
+ describe "#sensor" do
43
+ it "should add sensor" do
44
+ w.sensor :s1
45
+ w.sensor :s2
46
+ sensors = w.to_data.sensors
47
+ sensors.size.should == 2
48
+ sensors.first.name.to_s.should == 's1'
49
+ sensors.last.name.to_s.should == 's2'
50
+ end
51
+ end
52
+
53
+ describe "#title" do
54
+ it "should set title" do
55
+ w.title 'Title XXX'
56
+ w.to_data.title.should == 'Title XXX'
57
+ w.title 'Title YYY'
58
+ w.to_data.title.should == 'Title YYY'
59
+ end
60
+ end
61
+
62
+ describe "#width" do
63
+ it "should set width" do
64
+ w.width 6
65
+ w.to_data.width.should == 6
66
+ end
67
+
68
+ it "should raise exception if width is invalid" do
69
+ expect { w.width -1 }.to raise_exception(PulseMeter::Visualize::DSL::BadWidgetWidth)
70
+ expect { w.width 11 }.to raise_exception(PulseMeter::Visualize::DSL::BadWidgetWidth)
71
+ end
72
+ end
73
+
74
+ describe "#redraw_interval" do
75
+ it "should set redraw_interval" do
76
+ w.redraw_interval 5
77
+ w.to_data.redraw_interval.should == 5
78
+ end
79
+ it "should raise exception if redraw_interval is negative" do
80
+ expect{ w.redraw_interval(-1) }.to raise_exception(PulseMeter::Visualize::DSL::BadWidgetRedrawInterval)
81
+ end
82
+
83
+ end
84
+
85
+ describe "#to_data" do
86
+ it "should convert dsl data to widget" do
87
+ w.to_data.should be_kind_of(PulseMeter::Visualize::Widget)
88
+ end
89
+ end
90
+
91
+ describe "#gchart_options" do
92
+ it "should add options to gchart_options hash" do
93
+ w.gchart_options a: 1
94
+ w.gchart_options b: 2
95
+ w.to_data.gchart_options.should == {a: 1, b: 2}
96
+ end
97
+ end
98
+
99
+ describe "any anknown method" do
100
+ it "should add options to gchart_options hash" do
101
+ w.foobar 123
102
+ w.to_data.gchart_options.should == {foobar: 123}
103
+ end
104
+ end
105
+ end
106
+