fnordmetric 0.3.2 → 0.5.0
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.
- data/Gemfile +6 -0
- data/Gemfile.lock +21 -0
- data/Procfile +1 -2
- data/VERSION +1 -1
- data/_spec/app_spec.rb +178 -0
- data/{spec → _spec}/cache_spec.rb +0 -0
- data/{spec → _spec}/combine_metric_spec.rb +0 -0
- data/{spec → _spec}/core_spec.rb +0 -0
- data/{spec → _spec}/count_metric_spec.rb +0 -0
- data/_spec/dashboard_spec.rb +67 -0
- data/_spec/event_spec.rb +46 -0
- data/{spec → _spec}/metric_spec.rb +0 -0
- data/{spec → _spec}/report_spec.rb +0 -0
- data/{spec → _spec}/sum_metric_spec.rb +0 -0
- data/_spec/widget_spec.rb +107 -0
- data/doc/import_dump.rb +26 -0
- data/em_runner.rb +33 -0
- data/fnordmetric.gemspec +59 -20
- data/haml/app.haml +26 -12
- data/lib/fnordmetric.rb +150 -15
- data/lib/fnordmetric/app.rb +70 -11
- data/lib/fnordmetric/cache.rb +4 -4
- data/lib/fnordmetric/context.rb +65 -0
- data/lib/fnordmetric/dashboard.rb +16 -12
- data/lib/fnordmetric/event.rb +65 -15
- data/lib/fnordmetric/gauge.rb +46 -0
- data/lib/fnordmetric/gauge_calculations.rb +43 -0
- data/lib/fnordmetric/gauge_modifiers.rb +43 -0
- data/lib/fnordmetric/inbound_stream.rb +66 -0
- data/lib/fnordmetric/logger.rb +38 -0
- data/lib/fnordmetric/namespace.rb +120 -0
- data/lib/fnordmetric/numbers_widget.rb +29 -11
- data/lib/fnordmetric/session.rb +131 -0
- data/lib/fnordmetric/standalone.rb +31 -0
- data/lib/fnordmetric/timeline_widget.rb +29 -9
- data/lib/fnordmetric/widget.rb +50 -45
- data/lib/fnordmetric/worker.rb +80 -0
- data/pub/fnordmetric/fnordmetric.css +76 -9
- data/pub/fnordmetric/fnordmetric.js +541 -42
- data/pub/raphael-min.js +8 -0
- data/pub/raphael-utils.js +221 -0
- data/readme.rdoc +172 -27
- data/server.rb +22 -0
- data/spec/app_spec.rb +359 -117
- data/spec/context_spec.rb +42 -0
- data/spec/dashboard_spec.rb +7 -47
- data/spec/event_spec.rb +114 -33
- data/spec/gauge_modifiers_spec.rb +276 -0
- data/spec/gauge_spec.rb +128 -0
- data/spec/namespace_spec.rb +104 -0
- data/spec/session_spec.rb +231 -0
- data/spec/spec_helper.rb +27 -4
- data/spec/widget_spec.rb +81 -75
- data/spec/worker_spec.rb +37 -0
- data/test_stream.sh +187 -0
- data/ulm_stats.rb +198 -0
- metadata +114 -35
- data/lib/fnordmetric/core.rb +0 -66
- data/lib/fnordmetric/engine.rb +0 -3
data/Gemfile
CHANGED
@@ -4,10 +4,16 @@ gem "mongoid", "~> 2.2.0"
|
|
4
4
|
gem "mongo", "~> 1.4.0"
|
5
5
|
gem "bson_ext", "~> 1.4.0"
|
6
6
|
gem "sinatra", "~> 1.2.6"
|
7
|
+
gem "redis", "~> 2.2.2"
|
8
|
+
gem "eventmachine"
|
9
|
+
gem "em-hiredis"
|
7
10
|
gem "json"
|
8
11
|
gem "haml"
|
9
12
|
gem "rack"
|
10
13
|
gem "rack-test"
|
14
|
+
gem "yajl-ruby", :git => "git://github.com/brianmario/yajl-ruby.git"
|
15
|
+
gem "thin"
|
16
|
+
|
11
17
|
|
12
18
|
group :development do
|
13
19
|
gem "delorean", ">= 0"
|
data/Gemfile.lock
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/brianmario/yajl-ruby.git
|
3
|
+
revision: eef5c48be81b6404af66da3f185ec9301e5214d8
|
4
|
+
specs:
|
5
|
+
yajl-ruby (1.1.0)
|
6
|
+
|
1
7
|
GEM
|
2
8
|
remote: http://rubygems.org/
|
3
9
|
specs:
|
@@ -13,11 +19,16 @@ GEM
|
|
13
19
|
bson_ext (1.4.0)
|
14
20
|
builder (3.0.0)
|
15
21
|
chronic (0.6.4)
|
22
|
+
daemons (1.1.4)
|
16
23
|
delorean (1.1.0)
|
17
24
|
chronic
|
18
25
|
diff-lcs (1.1.3)
|
26
|
+
em-hiredis (0.1.0)
|
27
|
+
hiredis (~> 0.3.0)
|
28
|
+
eventmachine (0.12.10)
|
19
29
|
git (1.2.5)
|
20
30
|
haml (3.1.2)
|
31
|
+
hiredis (0.3.2)
|
21
32
|
i18n (0.6.0)
|
22
33
|
jeweler (1.5.2)
|
23
34
|
bundler (~> 1.0.0)
|
@@ -35,6 +46,7 @@ GEM
|
|
35
46
|
rack-test (0.6.0)
|
36
47
|
rack (>= 1.0)
|
37
48
|
rake (0.9.2)
|
49
|
+
redis (2.2.2)
|
38
50
|
rspec (2.6.0)
|
39
51
|
rspec-core (~> 2.6.0)
|
40
52
|
rspec-expectations (~> 2.6.0)
|
@@ -47,6 +59,10 @@ GEM
|
|
47
59
|
sinatra (1.2.6)
|
48
60
|
rack (~> 1.1)
|
49
61
|
tilt (>= 1.2.2, < 2.0)
|
62
|
+
thin (1.2.11)
|
63
|
+
daemons (>= 1.0.9)
|
64
|
+
eventmachine (>= 0.12.6)
|
65
|
+
rack (>= 1.0.0)
|
50
66
|
tilt (1.3.2)
|
51
67
|
tzinfo (0.3.29)
|
52
68
|
|
@@ -57,6 +73,8 @@ DEPENDENCIES
|
|
57
73
|
bson_ext (~> 1.4.0)
|
58
74
|
bundler (~> 1.0.0)
|
59
75
|
delorean
|
76
|
+
em-hiredis
|
77
|
+
eventmachine
|
60
78
|
haml
|
61
79
|
jeweler (~> 1.5.2)
|
62
80
|
json
|
@@ -64,6 +82,9 @@ DEPENDENCIES
|
|
64
82
|
mongoid (~> 2.2.0)
|
65
83
|
rack
|
66
84
|
rack-test
|
85
|
+
redis (~> 2.2.2)
|
67
86
|
rspec (~> 2.6.0)
|
68
87
|
shoulda
|
69
88
|
sinatra (~> 1.2.6)
|
89
|
+
thin
|
90
|
+
yajl-ruby!
|
data/Procfile
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
switchboard: bundle exec ruby zoe_switchboard.rb
|
1
|
+
server: bundle exec ruby server.rb
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/_spec/app_spec.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
include Rack::Test::Methods
|
4
|
+
|
5
|
+
describe "app" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
FnordMetric::Event.destroy_all
|
9
|
+
end
|
10
|
+
|
11
|
+
def app
|
12
|
+
@app ||= FnordMetric::App
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should redirect to the default dashboard" do
|
16
|
+
get "/"
|
17
|
+
last_response.status.should == 302
|
18
|
+
last_response.location.should == "http://example.org/dashboard/default"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should render the dashboard" do
|
22
|
+
FnordMetric.dashboard("Deine Mama"){|dash|}
|
23
|
+
get "/dashboard/default"
|
24
|
+
last_response.status.should == 200
|
25
|
+
last_response.body.should include("Deine Mama")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should render the right dashboard" do
|
29
|
+
FnordMetric.dashboard("Deine Mama"){|dash|}
|
30
|
+
FnordMetric.dashboard("My Dashboard"){|dash|}
|
31
|
+
get "/dashboard/DeineMama"
|
32
|
+
last_response.status.should == 200
|
33
|
+
last_response.body.should include("Deine Mama")
|
34
|
+
get "/dashboard/MyDashboard"
|
35
|
+
last_response.status.should == 200
|
36
|
+
last_response.body.should include("My Dashboard")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should track an event without auth" do
|
40
|
+
post "/events", :type => "myevent", :fnord => "foobar"
|
41
|
+
last_response.status.should == 200
|
42
|
+
FnordMetric::Event.last.type.should == "myevent"
|
43
|
+
FnordMetric::Event.last.fnord.should == "foobar"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return 400 if no type is provided" do
|
47
|
+
post "/events", :fnord => "foobar"
|
48
|
+
last_response.status.should == 400
|
49
|
+
last_response.body.should == "please specify the event_type"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should track an event in the past" do
|
53
|
+
my_time = (Time.now-3.years).to_i
|
54
|
+
post "/events", :type => "myevent", :time => my_time
|
55
|
+
last_response.status.should == 200
|
56
|
+
FnordMetric::Event.last.type.should == "myevent"
|
57
|
+
FnordMetric::Event.last.time.should == my_time
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should track an event with integer data" do
|
61
|
+
post "/events", :type => "myevent", :blubb => "123"
|
62
|
+
last_response.status.should == 200
|
63
|
+
FnordMetric::Event.last.type.should == "myevent"
|
64
|
+
FnordMetric::Event.last.blubb.should == 123
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should track an event with float data" do
|
68
|
+
post "/events", :type => "myevent", :blubb => "42.23"
|
69
|
+
last_response.status.should == 200
|
70
|
+
FnordMetric::Event.last.type.should == "myevent"
|
71
|
+
FnordMetric::Event.last.blubb.should == 42.23
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
describe "metrics api" do
|
76
|
+
|
77
|
+
before(:each) do
|
78
|
+
FnordMetric::Event.destroy_all
|
79
|
+
FnordMetric.metric('my_event_count', :count => true, :types => [:my_event_type])
|
80
|
+
FnordMetric.track('my_event_type', :time => 33.hours.ago)
|
81
|
+
FnordMetric.track('my_event_type', :time => 32.hours.ago)
|
82
|
+
FnordMetric.track('my_event_type', :time => 29.hours.ago)
|
83
|
+
FnordMetric.track('my_event_type', :time => 27.hours.ago)
|
84
|
+
FnordMetric.track('my_event_type', :time => 26.hours.ago)
|
85
|
+
FnordMetric.track('my_event_type', :time => 13.hours.ago)
|
86
|
+
FnordMetric.track('my_event_type', :time => 12.hours.ago)
|
87
|
+
FnordMetric.track('my_event_type', :time => 2.hours.ago)
|
88
|
+
FnordMetric.track('my_event_type', :time => 3.hours.ago)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return the right answer for: /metric/:name" do
|
92
|
+
get "/metric/my_event_count"
|
93
|
+
JSON.parse(last_response.body)["value"].to_i.should == 9
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return the right answer for: /metric/:name?at=timestamp" do
|
97
|
+
get "/metric/my_event_count", :at => 18.hours.ago.to_i.to_s
|
98
|
+
JSON.parse(last_response.body)["value"].to_i.should == 5
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp" do
|
102
|
+
get "/metric/my_event_count", :at => "#{30.hours.ago.to_i}-#{20.hours.ago.to_i}"
|
103
|
+
JSON.parse(last_response.body)["value"].to_i.should == 3
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
107
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i, :delta => true
|
108
|
+
JSON.parse(last_response.body)["values"].length.should == 6
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
112
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i, :delta => true
|
113
|
+
JSON.parse(last_response.body)["values"][0].first.should == 34.hours.ago.to_i
|
114
|
+
JSON.parse(last_response.body)["values"][0].last.should == 3
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
118
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i, :delta => true
|
119
|
+
JSON.parse(last_response.body)["values"][1].first.should == 28.hours.ago.to_i
|
120
|
+
JSON.parse(last_response.body)["values"][1].last.should == 2
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
124
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i, :delta => true
|
125
|
+
JSON.parse(last_response.body)["values"][2].first.should == 22.hours.ago.to_i
|
126
|
+
JSON.parse(last_response.body)["values"][2].last.should == 0
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
130
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i, :delta => true
|
131
|
+
JSON.parse(last_response.body)["values"][3].first.should == 16.hours.ago.to_i
|
132
|
+
JSON.parse(last_response.body)["values"][3].last.should == 2
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
136
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i, :delta => true
|
137
|
+
JSON.parse(last_response.body)["values"][5].first.should == 4.hours.ago.to_i
|
138
|
+
JSON.parse(last_response.body)["values"][5].last.should == 2
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
142
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i
|
143
|
+
JSON.parse(last_response.body)["values"].length.should == 6
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
147
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i
|
148
|
+
JSON.parse(last_response.body)["values"][0].first.should == 34.hours.ago.to_i
|
149
|
+
JSON.parse(last_response.body)["values"][0].last.should == 0
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
153
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i
|
154
|
+
JSON.parse(last_response.body)["values"][1].first.should == 28.hours.ago.to_i
|
155
|
+
JSON.parse(last_response.body)["values"][1].last.should == 3
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
159
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i
|
160
|
+
JSON.parse(last_response.body)["values"][2].first.should == 22.hours.ago.to_i
|
161
|
+
JSON.parse(last_response.body)["values"][2].last.should == 5
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
165
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i
|
166
|
+
JSON.parse(last_response.body)["values"][3].first.should == 16.hours.ago.to_i
|
167
|
+
JSON.parse(last_response.body)["values"][3].last.should == 5
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should return the right answer for: /metric/:name?at=timestamp-timstamp&tick=seconds" do
|
171
|
+
get "/metric/my_event_count", :at => "#{34.hours.ago.to_i}-#{1.hour.ago.to_i}", :tick => 6.hours.to_i
|
172
|
+
JSON.parse(last_response.body)["values"][5].first.should == 4.hours.ago.to_i
|
173
|
+
JSON.parse(last_response.body)["values"][5].last.should == 7
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
File without changes
|
File without changes
|
data/{spec → _spec}/core_spec.rb
RENAMED
File without changes
|
File without changes
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe FnordMetric::Dashboard do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
FnordMetric::Event.destroy_all
|
7
|
+
FnordMetric.reset_metrics
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should remember it's title" do
|
11
|
+
dashboard = FnordMetric::Dashboard.new(:title => 'My Foobar Dashboard'){ |dash| }
|
12
|
+
dashboard.title.should == 'My Foobar Dashboard'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should build a token" do
|
16
|
+
dashboard = FnordMetric::Dashboard.new(:title => 'My!F00bar-.Dash_board'){ |dash| }
|
17
|
+
dashboard.token.should == 'MyF00barDash_board'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should add a widget" do
|
21
|
+
dashboard = FnordMetric::Dashboard.new(:title => 'My!F00bar-.Dash_board'){ |dash| }
|
22
|
+
FnordMetric.metric(:my_metric, :sum => :my_field)
|
23
|
+
widget = FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
|
24
|
+
dashboard.add_widget(widget)
|
25
|
+
dashboard.widgets.first.should == widget
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should add a widget by name" do
|
29
|
+
dashboard = FnordMetric::Dashboard.new(:title => 'My!F00bar-.Dash_board'){ |dash| }
|
30
|
+
FnordMetric.metric(:my_metric, :sum => :my_field)
|
31
|
+
widget = FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
|
32
|
+
dashboard.add_widget(:my_widget)
|
33
|
+
dashboard.widgets.first.should == widget
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should add the report on init (and to all widgets)" do
|
37
|
+
FnordMetric.metric(:my_metric, :sum => :my_field)
|
38
|
+
report = FnordMetric.report(:range => (4.days.ago..Time.now))
|
39
|
+
dashboard = FnordMetric::Dashboard.new(:title => 'My Foobar Dashboard', :report => report){ |dash|
|
40
|
+
dash.add_widget FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
|
41
|
+
}
|
42
|
+
dashboard.report.should == report
|
43
|
+
dashboard.widgets.last.report.should == report
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should add the report after init (and to all widgets)" do
|
47
|
+
FnordMetric.metric(:my_metric, :sum => :my_field)
|
48
|
+
report = FnordMetric.report(:range => (4.days.ago..Time.now))
|
49
|
+
dashboard = FnordMetric::Dashboard.new(:title => 'My Foobar Dashboard'){ |dash|
|
50
|
+
dash.add_widget FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
|
51
|
+
}
|
52
|
+
dashboard.report.should == nil
|
53
|
+
dashboard.add_report(report)
|
54
|
+
dashboard.report.should == report
|
55
|
+
dashboard.widgets.last.report.should == report
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should call the config block" do
|
59
|
+
block_called = false
|
60
|
+
FnordMetric::Dashboard.new(:title => 'My Dashboard') do |dash|
|
61
|
+
block_called = true
|
62
|
+
dash.should be_a(FnordMetric::Dashboard)
|
63
|
+
end
|
64
|
+
block_called.should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/_spec/event_spec.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
include FnordMetric
|
4
|
+
|
5
|
+
describe "event" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Event.destroy_all
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should track an event" do
|
12
|
+
event = Event.track!('_referral', :foobar => "fnord")
|
13
|
+
Event.last[:type].should == "_referral"
|
14
|
+
Event.last[:foobar].should == "fnord"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should track an event via the proxy method" do
|
18
|
+
FnordMetric.track('blubb', :foo => "bar")
|
19
|
+
FnordMetric::Event.last.foo.should == "bar"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should access info like a 'ostruct' object" do
|
23
|
+
event = Event.track!('_referral', :foobar => "fnord")
|
24
|
+
Event.last.type.should == "_referral"
|
25
|
+
Event.last.foobar.should == "fnord"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should insert a data point in the past" do
|
29
|
+
my_time = 23.minutes.ago
|
30
|
+
event = Event.track!('_referral', :foobar => "fnord", :time => my_time)
|
31
|
+
Event.last[:type].should == "_referral"
|
32
|
+
Event.last[:foobar].should == "fnord"
|
33
|
+
Event.last[:time].should == my_time.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should save integer data" do
|
37
|
+
event = Event.track!('_test', :num => 23)
|
38
|
+
Event.last.num.should == 23
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should save float data" do
|
42
|
+
event = Event.track!('_test', :num => 42.5)
|
43
|
+
Event.last.num.should == 42.5
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe FnordMetric::Widget do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
FnordMetric::Event.destroy_all
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should remembe it's own title" do
|
10
|
+
widget = FnordMetric::Widget.new(:title => "My Widget")
|
11
|
+
widget.title.should == "My Widget"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should add the report on init" do
|
15
|
+
FnordMetric.metric(:my_metric, :sum => :my_field)
|
16
|
+
report = FnordMetric.report(:range => (4.days.ago..Time.now))
|
17
|
+
widget = FnordMetric::Widget.new(:report => report)
|
18
|
+
widget.report.should == report
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should add the report after init" do
|
22
|
+
FnordMetric.metric(:my_metric, :sum => :my_field)
|
23
|
+
report = FnordMetric.report(:range => (4.days.ago..Time.now))
|
24
|
+
widget = FnordMetric::Widget.new
|
25
|
+
widget.report.should be_nil
|
26
|
+
widget.add_report(report)
|
27
|
+
widget.report.should == report
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should define a new widget when given two metric-token" do
|
31
|
+
FnordMetric.metric(:first_metric, :count => :true)
|
32
|
+
FnordMetric.metric(:second_metric, :count => :true)
|
33
|
+
widget = FnordMetric::Widget.new(:metrics => [:first_metric, :second_metric], :title => "My Widget", :type => :timeline)
|
34
|
+
widget.metrics.length.should == 2
|
35
|
+
widget.metrics.first.should be_a(FnordMetric::CountMetric)
|
36
|
+
widget.metrics.first.token.should == :first_metric
|
37
|
+
widget.metrics.last.should be_a(FnordMetric::CountMetric)
|
38
|
+
widget.metrics.last.token.should == :second_metric
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should define a new widget when given two metrics" do
|
42
|
+
my_metrics = [
|
43
|
+
FnordMetric.metric(:first_metric, :count => :true),
|
44
|
+
FnordMetric.metric(:second_metric, :count => :true)
|
45
|
+
]
|
46
|
+
widget = FnordMetric::Widget.new(:metrics => my_metrics, :title => "My Widget", :type => :timeline)
|
47
|
+
widget.metrics.length.should == 2
|
48
|
+
widget.metrics.first.should be_a(FnordMetric::CountMetric)
|
49
|
+
widget.metrics.first.token.should == :first_metric
|
50
|
+
widget.metrics.last.should be_a(FnordMetric::CountMetric)
|
51
|
+
widget.metrics.last.token.should == :second_metric
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return the right ticks for 1h intervals" do
|
55
|
+
t = Time.now
|
56
|
+
widget = FnordMetric::Widget.new(:range => (t-2.days)..t, :tick => 1.hour)
|
57
|
+
widget.ticks.length.should == 49
|
58
|
+
ranges_should_match! widget.ticks.first, ((t-48.hours)..(t-47.hours))
|
59
|
+
ranges_should_match! widget.ticks.last, (t..(t+1.hour))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should generate a default range for daily graphs" do
|
63
|
+
widget = FnordMetric::Widget.new(:tick => 1.day)
|
64
|
+
Delorean.time_travel_to(Time.utc(1992,01,13,18,23,23)) do
|
65
|
+
widget.default_range.first.should == Time.utc(1991,12,15,00,00,00)
|
66
|
+
widget.default_range.last.should == Time.utc(1992,1,13,23,59,59)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should generate ticks with default range for daily graphs" do
|
71
|
+
widget = FnordMetric::Widget.new(:tick => 1.day)
|
72
|
+
Delorean.time_travel_to(Time.utc(1992,01,13,18,23,23)) do
|
73
|
+
widget.ticks.length.should == 30
|
74
|
+
widget.ticks.first.first.utc.should == Time.utc(1991,12,15,00,00,00)
|
75
|
+
widget.ticks.first.last.utc.should == Time.utc(1991,12,16,00,00,00)
|
76
|
+
widget.ticks.last.first.utc.should == Time.utc(1992,1,13,0,0,0)
|
77
|
+
widget.ticks.last.last.utc.should == Time.utc(1992,1,14,0,0,0)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should generate a default range for hourly graphs" do
|
82
|
+
widget = FnordMetric::Widget.new(:tick => 1.hour)
|
83
|
+
Delorean.time_travel_to(Time.utc(1992,01,13,18,23,23)) do
|
84
|
+
widget.default_range.first.should == Time.utc(1992,1,12,19,00,00)
|
85
|
+
widget.default_range.last.should == Time.utc(1992,1,13,18,59,59)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should generate a default range for hourly graphs" do
|
90
|
+
widget = FnordMetric::Widget.new(:tick => 1.hour)
|
91
|
+
Delorean.time_travel_to(Time.utc(1992,01,13,18,23,23)) do
|
92
|
+
widget.ticks.length.should == 24
|
93
|
+
widget.ticks.first.first.utc.should == Time.utc(1992,1,12,19,00,00)
|
94
|
+
widget.ticks.first.last.utc.should == Time.utc(1992,1,12,20,00,00)
|
95
|
+
widget.ticks.last.first.utc.should == Time.utc(1992,1,13,18,0,0)
|
96
|
+
widget.ticks.last.last.utc.should == Time.utc(1992,1,13,19,00,00)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def ranges_should_match!(a, b)
|
103
|
+
(a.first.to_i - b.first.to_i).should == 0
|
104
|
+
(a.last.to_i - b.last.to_i).should == 0
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|