pulse_meter_visualizer 0.4.11

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