fnordmetric 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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