fnordmetric 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.document +5 -0
  2. data/Gemfile +18 -0
  3. data/Gemfile.lock +69 -0
  4. data/Procfile +2 -0
  5. data/Rakefile +28 -0
  6. data/VERSION +1 -0
  7. data/doc/example_server.rb +56 -0
  8. data/fnordmetric.gemspec +145 -0
  9. data/haml/app.haml +48 -0
  10. data/haml/widget.haml +9 -0
  11. data/lib/fnordmetric.rb +21 -0
  12. data/lib/fnordmetric/app.rb +70 -0
  13. data/lib/fnordmetric/average_metric.rb +7 -0
  14. data/lib/fnordmetric/cache.rb +20 -0
  15. data/lib/fnordmetric/combine_metric.rb +7 -0
  16. data/lib/fnordmetric/core.rb +66 -0
  17. data/lib/fnordmetric/count_metric.rb +13 -0
  18. data/lib/fnordmetric/dashboard.rb +30 -0
  19. data/lib/fnordmetric/engine.rb +3 -0
  20. data/lib/fnordmetric/event.rb +28 -0
  21. data/lib/fnordmetric/funnel_widget.rb +2 -0
  22. data/lib/fnordmetric/metric.rb +80 -0
  23. data/lib/fnordmetric/metric_api.rb +37 -0
  24. data/lib/fnordmetric/numbers_widget.rb +18 -0
  25. data/lib/fnordmetric/report.rb +29 -0
  26. data/lib/fnordmetric/sum_metric.rb +13 -0
  27. data/lib/fnordmetric/timeline_widget.rb +17 -0
  28. data/lib/fnordmetric/widget.rb +75 -0
  29. data/pub/fnordmetric/fnordmetric.css +53 -0
  30. data/pub/fnordmetric/fnordmetric.js +44 -0
  31. data/pub/fnordmetric/widget_numbers.js +71 -0
  32. data/pub/fnordmetric/widget_timeline.css +0 -0
  33. data/pub/fnordmetric/widget_timeline.js +110 -0
  34. data/pub/highcharts/adapters/mootools-adapter.js +12 -0
  35. data/pub/highcharts/adapters/mootools-adapter.src.js +243 -0
  36. data/pub/highcharts/adapters/prototype-adapter.js +14 -0
  37. data/pub/highcharts/adapters/prototype-adapter.src.js +284 -0
  38. data/pub/highcharts/highcharts.js +170 -0
  39. data/pub/highcharts/highcharts.src.js +11103 -0
  40. data/pub/highcharts/modules/exporting.js +22 -0
  41. data/pub/highcharts/modules/exporting.src.js +703 -0
  42. data/pub/highcharts/themes/dark-blue.js +268 -0
  43. data/pub/highcharts/themes/dark-green.js +268 -0
  44. data/pub/highcharts/themes/gray.js +262 -0
  45. data/pub/highcharts/themes/grid.js +97 -0
  46. data/pub/jquery-1.6.1.min.js +18 -0
  47. data/pub/sprite.png +0 -0
  48. data/readme.rdoc +274 -0
  49. data/spec/app_spec.rb +178 -0
  50. data/spec/cache_spec.rb +53 -0
  51. data/spec/combine_metric_spec.rb +19 -0
  52. data/spec/core_spec.rb +50 -0
  53. data/spec/count_metric_spec.rb +32 -0
  54. data/spec/dashboard_spec.rb +67 -0
  55. data/spec/event_spec.rb +46 -0
  56. data/spec/metric_spec.rb +118 -0
  57. data/spec/report_spec.rb +87 -0
  58. data/spec/spec_helper.rb +13 -0
  59. data/spec/sum_metric_spec.rb +33 -0
  60. data/spec/widget_spec.rb +107 -0
  61. metadata +271 -0
@@ -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
@@ -0,0 +1,53 @@
1
+ require ::File.expand_path('../spec_helper.rb', __FILE__)
2
+
3
+ describe FnordMetric::Cache do
4
+
5
+ before(:each) do
6
+ FnordMetric::Cache.destroy_all
7
+ end
8
+
9
+ it "should store a cache item with a integer value" do
10
+ FnordMetric::Cache.store!('mykey', 123)
11
+ FnordMetric::Cache.last[:data].should be_a(Hash)
12
+ FnordMetric::Cache.last[:data].keys.should == ["value"]
13
+ FnordMetric::Cache.last[:data]["value"].to_i.should == 123
14
+ end
15
+
16
+ it "should store a cache item with a float value" do
17
+ FnordMetric::Cache.store!('mykey', 123.5)
18
+ FnordMetric::Cache.last[:data].should be_a(Hash)
19
+ FnordMetric::Cache.last[:data].keys.should == ["value"]
20
+ FnordMetric::Cache.last[:data]["value"].to_f.should == 123.5
21
+ end
22
+
23
+ it "should store a cache item with a hash value" do
24
+ FnordMetric::Cache.store!('mykey', :foobar => "fnord", :blubb => "asd")
25
+ FnordMetric::Cache.last[:data].should be_a(Hash)
26
+ FnordMetric::Cache.last[:data].keys.length.should == 2
27
+ FnordMetric::Cache.last[:data].keys.should include("foobar")
28
+ FnordMetric::Cache.last[:data].keys.should include("blubb")
29
+ FnordMetric::Cache.last[:data]["foobar"].should == "fnord"
30
+ FnordMetric::Cache.last[:data]["blubb"].should == "asd"
31
+ end
32
+
33
+ it "should get a cache item with a integer value" do
34
+ FnordMetric::Cache.store!('mykey', 123)
35
+ FnordMetric::Cache.get('mykey').should == 123
36
+ end
37
+
38
+ it "should store a cache item with a float value" do
39
+ FnordMetric::Cache.store!('mykey', 42.5)
40
+ FnordMetric::Cache.get('mykey').should == 42.5
41
+ end
42
+
43
+ it "should store a cache item with a hash value" do
44
+ FnordMetric::Cache.store!('mykey', :foobar => "fnord", :blubb => "asd")
45
+ FnordMetric::Cache.get('mykey').should be_a(Hash)
46
+ FnordMetric::Cache.get('mykey').keys.length.should == 2
47
+ FnordMetric::Cache.get('mykey').keys.should include("foobar")
48
+ FnordMetric::Cache.get('mykey').keys.should include("blubb")
49
+ FnordMetric::Cache.get('mykey')["foobar"].should == "fnord"
50
+ FnordMetric::Cache.get('mykey')["blubb"].should == "asd"
51
+ end
52
+
53
+ end
@@ -0,0 +1,19 @@
1
+ require ::File.expand_path('../spec_helper.rb', __FILE__)
2
+
3
+ describe FnordMetric::CombineMetric do
4
+
5
+ it "should return the block return" do
6
+ metric = FnordMetric.metric('my_event_count', :combine => lambda{ |time_or_range|
7
+ 2323
8
+ })
9
+ metric.current.should == 2323
10
+ end
11
+
12
+ it "should pass the time_or_range to the bloc" do
13
+ metric = FnordMetric.metric('my_event_count', :combine => lambda{ |time_or_range|
14
+ time_or_range.to_i
15
+ })
16
+ metric.current.should == Time.now.to_i
17
+ end
18
+
19
+ end
@@ -0,0 +1,50 @@
1
+ require ::File.expand_path('../spec_helper.rb', __FILE__)
2
+
3
+ describe FnordMetric do
4
+
5
+ before(:each) do
6
+ FnordMetric::Event.destroy_all
7
+ end
8
+
9
+ it "should define a new metric" do
10
+ FnordMetric.metric(:myfield_total, :sum => :myfield)
11
+ FnordMetric.metrics.keys.should include(:myfield_total)
12
+ FnordMetric.metrics[:myfield_total].should be_a(FnordMetric::Metric)
13
+ end
14
+
15
+ it "should define a new dashboard" do
16
+ FnordMetric.dashboard('My Dashboard'){ |dash| }
17
+ dashboard = FnordMetric.dashboards.last
18
+ dashboard.should be_a(FnordMetric::Dashboard)
19
+ dashboard.title.should == 'My Dashboard'
20
+ end
21
+
22
+ it "should define a new dashboard and call the config block" do
23
+ block_called = false
24
+ FnordMetric.dashboard 'My Dashboard' do |dash|
25
+ block_called = true
26
+ dash.should be_a(FnordMetric::Dashboard)
27
+ end
28
+ block_called.should be_true
29
+ end
30
+
31
+ it "should define a new widget" do
32
+ FnordMetric.metric(:my_metric, :sum => :my_field)
33
+ FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
34
+ FnordMetric.widgets[:my_widget].title.should == "My Widget"
35
+ end
36
+
37
+ it "should raise an error if no type option is provided" do
38
+ FnordMetric.metric(:my_metric, :sum => :my_field)
39
+ lambda{
40
+ FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget")
41
+ }.should raise_error(RuntimeError)
42
+ end
43
+
44
+ it "should raise an error if an unknown metric is added to a widget" do
45
+ lambda{
46
+ FnordMetric.widget(:my_widget, :metrics => :my_unknown_metric, :title => "My Widget", :type => :timeline)
47
+ }.should raise_error(RuntimeError)
48
+ end
49
+
50
+ end
@@ -0,0 +1,32 @@
1
+ require ::File.expand_path('../spec_helper.rb', __FILE__)
2
+
3
+ describe FnordMetric::CountMetric do
4
+
5
+ before(:each) do
6
+ FnordMetric::Event.destroy_all
7
+ FnordMetric.track('my_event_type', :time => 33.hours.ago)
8
+ FnordMetric.track('my_event_type', :time => 32.hours.ago)
9
+ FnordMetric.track('my_event_type', :time => 28.hours.ago)
10
+ FnordMetric.track('my_event_type', :time => 27.hours.ago)
11
+ FnordMetric.track('my_event_type', :time => 26.hours.ago)
12
+ FnordMetric.track('my_event_type', :time => 13.hours.ago)
13
+ FnordMetric.track('my_event_type', :time => 12.hours.ago)
14
+ FnordMetric.track('my_event_type', :time => 11.hours.ago)
15
+ end
16
+
17
+ it "should count events until now" do
18
+ metric = FnordMetric.metric('my_event_count', :count => true, :types => [:my_event_type])
19
+ metric.current.should == 8
20
+ end
21
+
22
+ it "should count events until 18 hours ago" do
23
+ metric = FnordMetric.metric('my_event_count', :count => true, :types => [:my_event_type])
24
+ metric.at(18.hours.ago).should == 5
25
+ end
26
+
27
+ it "should count events from 30 to 20 hours ago" do
28
+ metric = FnordMetric.metric('my_event_count', :count => true, :types => [:my_event_type])
29
+ metric.at(30.hours.ago..20.hours.ago).should == 3
30
+ end
31
+
32
+ end
@@ -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
@@ -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