acts_as_dashboard 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +54 -0
- data/Rakefile +23 -0
- data/VERSION +1 -0
- data/acts_as_dashboard.gemspec +166 -0
- data/generators/dashboard/USAGE +23 -0
- data/generators/dashboard/dashboard_generator.rb +105 -0
- data/generators/dashboard/templates/controller.erb +39 -0
- data/generators/dashboard/templates/dashboard.css +66 -0
- data/generators/dashboard/templates/dashboard.js +305 -0
- data/generators/dashboard/templates/jqplot-0.9.7/jquery.jqplot.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.barRenderer.js +404 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.barRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisLabelRenderer.js +200 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisLabelRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisTickRenderer.js +232 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisTickRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasTextRenderer.js +408 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasTextRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.categoryAxisRenderer.js +238 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.categoryAxisRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.cursor.js +812 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.cursor.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.js +313 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dragable.js +203 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dragable.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.highlighter.js +359 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.highlighter.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.logAxisRenderer.js +434 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.logAxisRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoAxisRenderer.js +595 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoAxisRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoRenderer.js +308 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.ohlcRenderer.js +343 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.ohlcRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pieRenderer.js +333 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pieRenderer.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.js +307 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.js.orig +273 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.min.js +14 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.trendline.js +208 -0
- data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.trendline.min.js +14 -0
- data/generators/dashboard/templates/jquery.jqplot.min.css +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/CHANGELOG +269 -0
- data/generators/dashboard/templates/js.class-2.1.4/MIT-LICENSE +30 -0
- data/generators/dashboard/templates/js.class-2.1.4/README +30 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/command.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/comparable.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/constant_scope.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/core.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/decorator.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/enumerable.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/forwardable.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/hash.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/linked_list.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/loader.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/method_chain.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/observable.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/package.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/proxy.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/ruby.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/set.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/stack_trace.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/state.js +1 -0
- data/generators/dashboard/templates/js.class-2.1.4/min/stdlib.js +16 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/command.js +93 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/comparable.js +37 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/constant_scope.js +48 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/core.js +1060 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/decorator.js +50 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/enumerable.js +505 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/forwardable.js +22 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/hash.js +334 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/linked_list.js +114 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/loader.js +458 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/method_chain.js +172 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/observable.js +55 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/package.js +377 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/proxy.js +58 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/ruby.js +44 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/set.js +332 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/stack_trace.js +151 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/state.js +95 -0
- data/generators/dashboard/templates/js.class-2.1.4/src/stdlib.js +2517 -0
- data/generators/dashboard/templates/show.html.erb +67 -0
- data/lib/acts_as_dashboard/app/views/dashboards/show.html.erb +67 -0
- data/lib/acts_as_dashboard/class_methods.rb +58 -0
- data/lib/acts_as_dashboard/config.rb +25 -0
- data/lib/acts_as_dashboard/instance_methods.rb +32 -0
- data/lib/acts_as_dashboard/line_graph_widget.rb +68 -0
- data/lib/acts_as_dashboard/public/javascripts/dashboard.js +305 -0
- data/lib/acts_as_dashboard/public/stylesheets/dashboard.css +66 -0
- data/lib/acts_as_dashboard/short_messages_widget.rb +25 -0
- data/lib/acts_as_dashboard/widget.rb +55 -0
- data/lib/acts_as_dashboard.rb +17 -0
- data/spec/acts_as_dashboard/class_method_specs.rb +188 -0
- data/spec/acts_as_dashboard/config_spec.rb +57 -0
- data/spec/acts_as_dashboard/instance_methods_spec.rb +134 -0
- data/spec/acts_as_dashboard/line_graph_widget_spec.rb +165 -0
- data/spec/acts_as_dashboard/short_messages_widget_spec.rb +69 -0
- data/spec/acts_as_dashboard/widget_spec.rb +6 -0
- data/spec/acts_as_dashboard_spec.rb +15 -0
- data/spec/shared/widget_behaviours.rb +171 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/tasks/install.rake +8 -0
- data/tasks/install_javascript.rake +7 -0
- data/tasks/install_stylesheets.rake +7 -0
- metadata +209 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module ActsAsDashboard
|
2
|
+
class ShortMessagesWidget < ActsAsDashboard::Widget
|
3
|
+
@@default_max_data_items = 5
|
4
|
+
|
5
|
+
attr_reader :max_data_items
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
options.delete :type
|
9
|
+
|
10
|
+
self.type = :short_messages
|
11
|
+
self.max_data_items = options[:max_data_items] || @@default_max_data_items
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def max_data_items=(max_data_items)
|
17
|
+
raise ArgumentError, 'The "max_data_items" argument must be a Fixnum.' unless max_data_items.is_a? Fixnum
|
18
|
+
@max_data_items = max_data_items
|
19
|
+
end
|
20
|
+
|
21
|
+
def attributes
|
22
|
+
super.merge(:max_data_items => @max_data_items)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module ActsAsDashboard
|
2
|
+
class Widget
|
3
|
+
attr_reader :type
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :title
|
6
|
+
attr_reader :block
|
7
|
+
attr_reader :update_interval
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
self.type = options[:type] if options[:type]
|
11
|
+
self.name = options[:name] if options[:name]
|
12
|
+
self.title = options[:title] if options[:title]
|
13
|
+
self.block = options[:block] if options[:block]
|
14
|
+
self.update_interval = options[:update_interval] if options[:update_interval]
|
15
|
+
end
|
16
|
+
|
17
|
+
def type=(type)
|
18
|
+
raise ArgumentError, 'The "type" argument must be a Symbol.' unless type.is_a? Symbol
|
19
|
+
@type = type
|
20
|
+
end
|
21
|
+
|
22
|
+
def name=(name)
|
23
|
+
raise ArgumentError, 'The "name" argument must be a Symbol.' unless name.is_a? Symbol
|
24
|
+
@name = name
|
25
|
+
end
|
26
|
+
|
27
|
+
def title=(title)
|
28
|
+
raise ArgumentError, 'The "title" argument must be a String.' unless title.is_a? String
|
29
|
+
@title = title
|
30
|
+
end
|
31
|
+
|
32
|
+
def block=(block)
|
33
|
+
raise ArgumentError, 'The "block" argument must be a Proc.' unless block.is_a? Proc
|
34
|
+
@block = block
|
35
|
+
end
|
36
|
+
|
37
|
+
def data(&block)
|
38
|
+
self.block = block
|
39
|
+
end
|
40
|
+
|
41
|
+
def update_interval=(update_interval)
|
42
|
+
raise ArgumentError, 'The "update_interval" argument must be a Fixnum or String.' unless [Fixnum, String].include? update_interval.class
|
43
|
+
@update_interval = update_interval
|
44
|
+
end
|
45
|
+
|
46
|
+
def attributes
|
47
|
+
{
|
48
|
+
:type => @type,
|
49
|
+
:name => @name,
|
50
|
+
:title => @title,
|
51
|
+
:update_interval => @update_interval,
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class ActionController::Base
|
2
|
+
class << self
|
3
|
+
def inherited_with_acts_as_dashboard_include(child)
|
4
|
+
inherited_without_acts_as_dashboard_include child
|
5
|
+
|
6
|
+
child.send :include, ActsAsDashboard
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method_chain :inherited, :acts_as_dashboard_include
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ActsAsDashboard
|
14
|
+
def self.included(base)
|
15
|
+
base.extend ClassMethods
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require File.join File.dirname(__FILE__), '..', 'spec_helper'
|
2
|
+
|
3
|
+
describe ActsAsDashboard::ClassMethods do
|
4
|
+
it 'makes its "dashboard_config" instance variable readable' do
|
5
|
+
class DashboardsController < ApplicationController
|
6
|
+
acts_as_dashboard
|
7
|
+
end
|
8
|
+
|
9
|
+
DashboardsController.dashboard_config.should be_a ActsAsDashboard::Config
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#acts_as_dashboard' do # {{{
|
13
|
+
before :each do
|
14
|
+
@config = mock ActsAsDashboard::Config
|
15
|
+
ActsAsDashboard::Config.stub(:new).and_return @config
|
16
|
+
ActionController::Routing::Routes.stub :add_named_route
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'creates a Config object' do
|
20
|
+
ActsAsDashboard::Config.should_receive(:new).and_return @config
|
21
|
+
|
22
|
+
class DashboardsController < ApplicationController
|
23
|
+
acts_as_dashboard
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'includes ActsAsDashboard::InstanceMethods' do
|
28
|
+
class DashboardsController < ApplicationController
|
29
|
+
acts_as_dashboard
|
30
|
+
end
|
31
|
+
|
32
|
+
DashboardsController.included_modules.should include ActsAsDashboard::InstanceMethods
|
33
|
+
end
|
34
|
+
|
35
|
+
it %Q(adds a named route for the dashboard's "show" action) do
|
36
|
+
ActionController::Routing::Routes.should_receive(:add_named_route).with(
|
37
|
+
'dashboard',
|
38
|
+
'dashboard',
|
39
|
+
:controller => :dashboards,
|
40
|
+
:action => :show
|
41
|
+
)
|
42
|
+
|
43
|
+
class DashboardsController < ApplicationController
|
44
|
+
acts_as_dashboard
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it %Q(adds a named route for the dashboard's "widget_data" action) do
|
49
|
+
ActionController::Routing::Routes.should_receive :add_named_route
|
50
|
+
ActionController::Routing::Routes.should_receive(:add_named_route).with(
|
51
|
+
'dashboard_widgets',
|
52
|
+
'dashboard/widgets/*path',
|
53
|
+
:controller => :dashboards,
|
54
|
+
:action => :widget_data
|
55
|
+
)
|
56
|
+
|
57
|
+
class DashboardsController < ApplicationController
|
58
|
+
acts_as_dashboard
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end # }}}
|
62
|
+
|
63
|
+
describe '#dashboard_number' do # {{{
|
64
|
+
def call_dashboard_number
|
65
|
+
DashboardsController.instance_eval do
|
66
|
+
dashboard_number {}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
before :each do
|
71
|
+
class DashboardsController < ApplicationController
|
72
|
+
acts_as_dashboard
|
73
|
+
end
|
74
|
+
|
75
|
+
@widget = ActsAsDashboard::Widget.new :type => :number
|
76
|
+
|
77
|
+
@widget.stub(:instance_eval)
|
78
|
+
ActsAsDashboard::Widget.stub(:new).and_return @widget
|
79
|
+
end
|
80
|
+
|
81
|
+
it "raises an error if a Proc isn't provided" do
|
82
|
+
Proc.new {
|
83
|
+
class DashboardsController
|
84
|
+
dashboard_number
|
85
|
+
end
|
86
|
+
}.should raise_error ArgumentError, 'A Proc must be given.'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'creates a "number" Widget' do
|
90
|
+
ActsAsDashboard::Widget.should_receive(:new).with(:type => :number).and_return @widget
|
91
|
+
call_dashboard_number
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'evaluates the given Proc within the widget' do
|
95
|
+
@widget.should_receive :instance_eval
|
96
|
+
call_dashboard_number
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'adds the widget to its configuration' do
|
100
|
+
DashboardsController.dashboard_config.should_receive(:add_widget).with(@widget).and_return [@widget]
|
101
|
+
call_dashboard_number
|
102
|
+
end
|
103
|
+
end # }}}
|
104
|
+
|
105
|
+
describe '#dashboard_short_messages' do # {{{
|
106
|
+
def call_dashboard_short_messages
|
107
|
+
DashboardsController.instance_eval do
|
108
|
+
dashboard_short_messages {}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
before :each do
|
113
|
+
class DashboardsController < ApplicationController
|
114
|
+
acts_as_dashboard
|
115
|
+
end
|
116
|
+
|
117
|
+
@widget = ActsAsDashboard::ShortMessagesWidget.new
|
118
|
+
|
119
|
+
@widget.stub(:instance_eval)
|
120
|
+
ActsAsDashboard::ShortMessagesWidget.stub(:new).and_return @widget
|
121
|
+
end
|
122
|
+
|
123
|
+
it "raises an error if a Proc isn't provided" do
|
124
|
+
Proc.new {
|
125
|
+
class DashboardsController
|
126
|
+
dashboard_short_messages
|
127
|
+
end
|
128
|
+
}.should raise_error ArgumentError, 'A Proc must be given.'
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'creates a "short messages" Widget' do
|
132
|
+
ActsAsDashboard::ShortMessagesWidget.should_receive(:new).with(no_args).and_return @widget
|
133
|
+
call_dashboard_short_messages
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'evaluates the given Proc within the widget' do
|
137
|
+
@widget.should_receive :instance_eval
|
138
|
+
call_dashboard_short_messages
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'adds the widget to its configuration' do
|
142
|
+
DashboardsController.dashboard_config.should_receive(:add_widget).with(@widget).and_return [@widget]
|
143
|
+
call_dashboard_short_messages
|
144
|
+
end
|
145
|
+
end # }}}
|
146
|
+
|
147
|
+
describe '#dashboard_line_graph' do # {{{
|
148
|
+
def call_dashboard_line_graph
|
149
|
+
DashboardsController.instance_eval do
|
150
|
+
dashboard_line_graph {}
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
before :each do
|
155
|
+
class DashboardsController < ApplicationController
|
156
|
+
acts_as_dashboard
|
157
|
+
end
|
158
|
+
|
159
|
+
@widget = ActsAsDashboard::LineGraphWidget.new
|
160
|
+
|
161
|
+
@widget.stub(:instance_eval)
|
162
|
+
ActsAsDashboard::LineGraphWidget.stub(:new).and_return @widget
|
163
|
+
end
|
164
|
+
|
165
|
+
it "raises an error if a Proc isn't provided" do
|
166
|
+
Proc.new {
|
167
|
+
class DashboardsController
|
168
|
+
dashboard_line_graph
|
169
|
+
end
|
170
|
+
}.should raise_error ArgumentError, 'A Proc must be given.'
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'creates a Line Graph Widget' do
|
174
|
+
ActsAsDashboard::LineGraphWidget.should_receive(:new).with(no_args).and_return @widget
|
175
|
+
call_dashboard_line_graph
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'evaluates the given Proc within the widget' do
|
179
|
+
@widget.should_receive :instance_eval
|
180
|
+
call_dashboard_line_graph
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'adds the widget to its configuration' do
|
184
|
+
DashboardsController.dashboard_config.should_receive(:add_widget).with(@widget).and_return [@widget]
|
185
|
+
call_dashboard_line_graph
|
186
|
+
end
|
187
|
+
end # }}}
|
188
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.join File.dirname(__FILE__), '..', 'spec_helper'
|
2
|
+
|
3
|
+
describe ActsAsDashboard::Config do
|
4
|
+
describe 'initialization' do # {{{
|
5
|
+
it 'creates an array of widgets' do
|
6
|
+
config = ActsAsDashboard::Config.new
|
7
|
+
config.instance_variable_get(:@widgets).should == []
|
8
|
+
end
|
9
|
+
end # }}}
|
10
|
+
|
11
|
+
describe 'attributes' do # {{{
|
12
|
+
it 'returns the "widgets" attribute' do
|
13
|
+
config = ActsAsDashboard::Config.new
|
14
|
+
config.widgets.should equal config.instance_variable_get(:@widgets)
|
15
|
+
end
|
16
|
+
end # }}}
|
17
|
+
|
18
|
+
describe 'adding a widget' do # {{{
|
19
|
+
before :each do
|
20
|
+
@config = ActsAsDashboard::Config.new
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'raises an exception if given an invalid value' do
|
24
|
+
Proc.new {@config.add_widget nil}.should raise_error ArgumentError,
|
25
|
+
'The "widget" argument must be an ActsAsDashboard::Widget.'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'is successful when given an ActsAsDashboard::Widget' do
|
29
|
+
widget = ActsAsDashboard::Widget.new
|
30
|
+
|
31
|
+
@config.widgets.should == []
|
32
|
+
@config.add_widget widget
|
33
|
+
@config.widgets.should == [widget]
|
34
|
+
end
|
35
|
+
end # }}}
|
36
|
+
|
37
|
+
describe 'finding a widget' do # {{{
|
38
|
+
before :each do
|
39
|
+
@config = ActsAsDashboard::Config.new
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'raises an exception if given an invalid value' do
|
43
|
+
Proc.new {@config.find_widget nil}.should raise_error ArgumentError,
|
44
|
+
'The "name" argument must respond to #to_sym .'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'returns the widget with the given name' do
|
48
|
+
foo_widget = ActsAsDashboard::Widget.new :name => :foo
|
49
|
+
bar_widget = ActsAsDashboard::Widget.new :name => :bar
|
50
|
+
|
51
|
+
@config.add_widget foo_widget
|
52
|
+
@config.add_widget bar_widget
|
53
|
+
|
54
|
+
@config.find_widget(foo_widget.name).should equal foo_widget
|
55
|
+
end
|
56
|
+
end # }}}
|
57
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.join File.dirname(__FILE__), '..', 'spec_helper'
|
2
|
+
|
3
|
+
class DashboardsController < ApplicationController
|
4
|
+
acts_as_dashboard
|
5
|
+
end
|
6
|
+
|
7
|
+
describe ActsAsDashboard::InstanceMethods do
|
8
|
+
it 'creates the "show" action for the controller' do
|
9
|
+
DashboardsController.action_methods.should include 'show'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe DashboardsController, :type => :controller do
|
14
|
+
describe 'GET "show"' do # {{{
|
15
|
+
before :each do
|
16
|
+
@widget_attributes = {:name => :some_name, :title => 'Some Title', :update_interval => '10s', :type => :number}
|
17
|
+
@json = '[{"type":"number","title":"Some Title","name":"some_name","update_interval":"10s"}]'
|
18
|
+
@widget = mock ActsAsDashboard::Widget, :attributes => @widget_attributes
|
19
|
+
@config = mock ActsAsDashboard::Config, :widgets => [@widget]
|
20
|
+
|
21
|
+
controller.stub(:dashboard_config).and_return @config
|
22
|
+
controller.stub(:render)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'grabs the dashboard config' do
|
26
|
+
controller.should_receive(:dashboard_config).and_return @config
|
27
|
+
get :show
|
28
|
+
end
|
29
|
+
|
30
|
+
it "grabs each widget's attributes" do
|
31
|
+
@widget.should_receive(:attributes).and_return @widget_attributes
|
32
|
+
get :show
|
33
|
+
end
|
34
|
+
|
35
|
+
it "converts each widget's attributes to JSON" do
|
36
|
+
@widget_attributes.should_receive(:to_json).and_return @json
|
37
|
+
get :show
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'assigns @json_widgets as a String of widget attributes in JSON' do
|
41
|
+
get :show
|
42
|
+
assigns[:json_widgets].should == @json
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'assigns @dashboard_css_path as the path to the CSS script' do
|
46
|
+
get :show
|
47
|
+
|
48
|
+
assigns[:dashboard_css_path].should == File.expand_path(File.join(
|
49
|
+
File.dirname(__FILE__), '..', '..', 'lib', 'acts_as_dashboard', 'public', 'stylesheets', 'dashboard.css'
|
50
|
+
))
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'assigns @dashboard_css as the CSS for the dashboard' do
|
54
|
+
get :show
|
55
|
+
|
56
|
+
css_file = File.join File.dirname(__FILE__), '..', '..', 'lib', 'acts_as_dashboard', 'public', 'stylesheets', 'dashboard.css'
|
57
|
+
assigns[:dashboard_css].should == File.open(css_file).read
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'assigns @dashboard_js_path as the path to the JavaScript script' do
|
61
|
+
get :show
|
62
|
+
|
63
|
+
assigns[:dashboard_js_path].should == File.expand_path(File.join(
|
64
|
+
File.dirname(__FILE__), '..', '..', 'lib', 'acts_as_dashboard', 'public', 'javascripts', 'dashboard.js'
|
65
|
+
))
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'assigns @dashboard_js_path as the JavaScript for the dashboard' do
|
69
|
+
get :show
|
70
|
+
|
71
|
+
js_file = File.join File.dirname(__FILE__), '..', '..', 'lib', 'acts_as_dashboard', 'public', 'javascripts', 'dashboard.js'
|
72
|
+
assigns[:dashboard_js].should == File.open(js_file).read
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'renders the "show" view template within the gem' do
|
76
|
+
path_to_gem = File.expand_path File.dirname(__FILE__) + '/../../'
|
77
|
+
path_to_view = "#{path_to_gem}/lib/acts_as_dashboard/app/views/dashboards/show.html.erb"
|
78
|
+
|
79
|
+
controller.should_receive(:render).with(:file => path_to_view)
|
80
|
+
get :show
|
81
|
+
end
|
82
|
+
end # }}}
|
83
|
+
|
84
|
+
describe 'GET /widget/returns_ten' do # {{{
|
85
|
+
before :each do
|
86
|
+
@widget_name = 'returns_ten'
|
87
|
+
@block = Proc.new {10}
|
88
|
+
@widget = mock ActsAsDashboard::Widget, :block => @block
|
89
|
+
@config = mock ActsAsDashboard::Config, :find_widget => @widget
|
90
|
+
@params = {:path => [@widget_name]}
|
91
|
+
|
92
|
+
controller.stub(:dashboard_config).and_return @config
|
93
|
+
controller.stub(:render)
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'when the widget exists' do # {{{
|
97
|
+
it 'finds the requested widget' do
|
98
|
+
@config.should_receive(:find_widget).with(@widget_name.to_s).and_return @widget
|
99
|
+
get :widget_data, @params
|
100
|
+
end
|
101
|
+
|
102
|
+
it "calls the widget's block" do
|
103
|
+
@block.should_receive(:call).with(no_args).and_return 10
|
104
|
+
get :widget_data, @params
|
105
|
+
end
|
106
|
+
|
107
|
+
it "renders the output from the widget's block as text" do
|
108
|
+
controller.should_receive(:render).with(:text => 10)
|
109
|
+
get :widget_data, @params
|
110
|
+
end
|
111
|
+
end # }}}
|
112
|
+
|
113
|
+
describe "when the widget doesn't exist" do # {{{
|
114
|
+
before :each do
|
115
|
+
@config.stub(:find_widget).and_return nil
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'fails to find the widget' do
|
119
|
+
@config.should_receive(:find_widget).and_return nil
|
120
|
+
|
121
|
+
begin
|
122
|
+
get :widget_data, @params
|
123
|
+
rescue ActsAsDashboard::WidgetNotFound => e
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'raises an ActsAsDashboard::WidgetNotFound error' do
|
128
|
+
Proc.new {
|
129
|
+
get :widget_data, @params
|
130
|
+
}.should raise_error ActsAsDashboard::WidgetNotFound, 'No widget named "returns_ten" found.'
|
131
|
+
end
|
132
|
+
end # }}}
|
133
|
+
end # }}}
|
134
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require File.join File.dirname(__FILE__), '..', 'spec_helper'
|
2
|
+
require File.join File.dirname(__FILE__), '..', 'shared', 'widget_behaviours'
|
3
|
+
|
4
|
+
describe ActsAsDashboard::LineGraphWidget do
|
5
|
+
it_should_behave_like 'an ActsAsDashboard Widget'
|
6
|
+
|
7
|
+
describe 'initialization' do # {{{
|
8
|
+
before :each do
|
9
|
+
@options = {
|
10
|
+
:width => '400px',
|
11
|
+
:height => '200px',
|
12
|
+
:line_colours => %w(#4bb2c5 #c5b47f),
|
13
|
+
:x_axis => :dates,
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'removes the :type element from the given options' do
|
18
|
+
options = {:type => :something}
|
19
|
+
options.should_receive(:delete).with :type
|
20
|
+
|
21
|
+
widget = ActsAsDashboard::LineGraphWidget.new options
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'sets its type to :line_graph' do
|
25
|
+
widget = ActsAsDashboard::LineGraphWidget.new
|
26
|
+
widget.type.should equal :line_graph
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets its height to the given value' do
|
30
|
+
widget = ActsAsDashboard::LineGraphWidget.new :height => @options[:height]
|
31
|
+
widget.height.should == @options[:height]
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'sets its height to the default value if no value is given' do
|
35
|
+
widget = ActsAsDashboard::LineGraphWidget.new
|
36
|
+
widget.height.should == ActsAsDashboard::LineGraphWidget.send(:class_variable_get, :@@default_height)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'sets its width to the given value' do
|
40
|
+
widget = ActsAsDashboard::LineGraphWidget.new :width => @options[:width]
|
41
|
+
widget.width.should == @options[:width]
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'sets its width to the default value if no value is given' do
|
45
|
+
widget = ActsAsDashboard::LineGraphWidget.new
|
46
|
+
widget.width.should == ActsAsDashboard::LineGraphWidget.send(:class_variable_get, :@@default_width)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'sets its line colours to the given value' do
|
50
|
+
widget = ActsAsDashboard::LineGraphWidget.new :line_colours => @options[:line_colours]
|
51
|
+
widget.line_colours.should == @options[:line_colours]
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'when given the "line_colors" (American spelling) option' do # {{{
|
55
|
+
it 'copies the value to "line_colours"' do
|
56
|
+
options = {:line_colors => @options[:line_colours]}
|
57
|
+
widget = ActsAsDashboard::LineGraphWidget.new options
|
58
|
+
options[:line_colours].should equal @options[:line_colours]
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'deletes the "line_colors" option' do
|
62
|
+
options = {:line_colors => @options[:line_colours]}
|
63
|
+
widget = ActsAsDashboard::LineGraphWidget.new options
|
64
|
+
options.should_not have_key :line_colors
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'uses the value of "line_colors" as "line_colours"' do
|
68
|
+
widget = ActsAsDashboard::LineGraphWidget.new :line_colors => @options[:line_colours]
|
69
|
+
widget.line_colours.should == @options[:line_colours]
|
70
|
+
end
|
71
|
+
end # }}}
|
72
|
+
|
73
|
+
it 'sets its x-axis to the given value' do
|
74
|
+
widget = ActsAsDashboard::LineGraphWidget.new :x_axis => @options[:x_axis]
|
75
|
+
widget.x_axis.should == @options[:x_axis]
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'sets its x-axis to the default value if no value is given' do
|
79
|
+
widget = ActsAsDashboard::LineGraphWidget.new
|
80
|
+
widget.x_axis.should == ActsAsDashboard::LineGraphWidget.send(:class_variable_get, :@@default_x_axis)
|
81
|
+
end
|
82
|
+
end # }}}
|
83
|
+
|
84
|
+
describe 'setting its "x_axis" attribute' do # {{{
|
85
|
+
it 'raises an error when given an invalid value' do
|
86
|
+
Proc.new {ActsAsDashboard::LineGraphWidget.new :x_axis => 'asdf'}.should raise_error ArgumentError,
|
87
|
+
'The "x_axis" argument must be one of the following symbols: dates, numbers'
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'is successful when given :dates' do
|
91
|
+
widget = ActsAsDashboard::LineGraphWidget.new :x_axis => :dates
|
92
|
+
widget.x_axis.should equal :dates
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'is successful when given :numbers' do
|
96
|
+
widget = ActsAsDashboard::LineGraphWidget.new :x_axis => :numbers
|
97
|
+
widget.x_axis.should equal :numbers
|
98
|
+
end
|
99
|
+
end # }}}
|
100
|
+
|
101
|
+
describe 'setting its "line_colours" attribute' do # {{{
|
102
|
+
it 'raises an error when not given an Array' do
|
103
|
+
Proc.new {ActsAsDashboard::LineGraphWidget.new.line_colours = 'fail'}.should raise_error ArgumentError,
|
104
|
+
'The "line_colours" argument must be an Array of Strings.'
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'raises an error when not given an Array of Strings' do
|
108
|
+
Proc.new {ActsAsDashboard::LineGraphWidget.new.line_colours = [1]}.should raise_error ArgumentError,
|
109
|
+
'The "line_colours" argument must be an Array of Strings.'
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'is successful when given an Array of Strings' do
|
113
|
+
line_colours = %w(#4bb2c5 #c5b47f)
|
114
|
+
w = ActsAsDashboard::LineGraphWidget.new
|
115
|
+
w.line_colours = line_colours
|
116
|
+
|
117
|
+
w.instance_variable_get(:@line_colours).should == line_colours
|
118
|
+
end
|
119
|
+
end # }}}
|
120
|
+
|
121
|
+
describe 'attributes' do # {{{
|
122
|
+
before :each do
|
123
|
+
@options = {
|
124
|
+
:name => :some_counter,
|
125
|
+
:title => 'Some Counter',
|
126
|
+
:block => Proc.new {123},
|
127
|
+
:update_interval => '10s',
|
128
|
+
:height => '100px',
|
129
|
+
:width => '200px',
|
130
|
+
:line_colours => %w(#4bb2c5 #c5b47f),
|
131
|
+
:x_axis => :dates,
|
132
|
+
}
|
133
|
+
|
134
|
+
@widget = ActsAsDashboard::LineGraphWidget.new @options
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'are returned in a Hash' do
|
138
|
+
@options.delete :block # Remove the "block" key because AAD::Widget#attributes doesn't return it on purpose.
|
139
|
+
|
140
|
+
@widget.attributes.should == @options.merge(:type => :line_graph)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'returns the "height" attribute' do
|
144
|
+
@widget.height.should equal @options[:height]
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'returns the "width" attribute' do
|
148
|
+
@widget.width.should equal @options[:width]
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'returns the "line_colours" attribute' do
|
152
|
+
@widget.line_colours.should equal @options[:line_colours]
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'when given the "line_colors" (American spelling) option' do # {{{
|
156
|
+
it 'returns the "line_colours" attribute' do
|
157
|
+
@widget.line_colors.should equal @options[:line_colours]
|
158
|
+
end
|
159
|
+
end # }}}
|
160
|
+
|
161
|
+
it 'returns the "x_axis" attribute' do
|
162
|
+
@widget.x_axis.should equal @options[:x_axis]
|
163
|
+
end
|
164
|
+
end # }}}
|
165
|
+
end
|