snogmetrics 0.1.9 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rubocop.yml +1 -0
  4. data/.rubocop_todo.yml +203 -0
  5. data/Gemfile.lock +128 -25
  6. data/README.mdown +11 -6
  7. data/Rakefile +5 -12
  8. data/lib/snogmetrics.rb +18 -130
  9. data/lib/snogmetrics/kissmetrics_api.rb +112 -0
  10. data/lib/snogmetrics/railtie.rb +0 -1
  11. data/snogmetrics.gemspec +18 -12
  12. metadata +100 -130
  13. data/example/snoggy/.gitignore +0 -1
  14. data/example/snoggy/README.mdown +0 -7
  15. data/example/snoggy/Rakefile +0 -10
  16. data/example/snoggy/app/controllers/application_controller.rb +0 -2
  17. data/example/snoggy/app/controllers/snogs_controller.rb +0 -9
  18. data/example/snoggy/app/views/layouts/application.html.erb +0 -12
  19. data/example/snoggy/app/views/snogs/new.html.erb +0 -11
  20. data/example/snoggy/app/views/snogs/thank_you.html.erb +0 -1
  21. data/example/snoggy/config/boot.rb +0 -110
  22. data/example/snoggy/config/environment.rb +0 -13
  23. data/example/snoggy/config/environments/development.rb +0 -6
  24. data/example/snoggy/config/environments/production.rb +0 -4
  25. data/example/snoggy/config/environments/test.rb +0 -6
  26. data/example/snoggy/config/initializers/snogmetrics.rb +0 -14
  27. data/example/snoggy/config/routes.rb +0 -4
  28. data/example/snoggy/script/about +0 -4
  29. data/example/snoggy/script/console +0 -3
  30. data/example/snoggy/script/dbconsole +0 -3
  31. data/example/snoggy/script/destroy +0 -3
  32. data/example/snoggy/script/generate +0 -3
  33. data/example/snoggy/script/performance/benchmarker +0 -3
  34. data/example/snoggy/script/performance/profiler +0 -3
  35. data/example/snoggy/script/plugin +0 -3
  36. data/example/snoggy/script/runner +0 -3
  37. data/example/snoggy/script/server +0 -3
  38. data/example/snoggy/vendor/plugins/snogmetrics/init.rb +0 -4
  39. data/rails/init.rb +0 -4
  40. data/spec/snogmetrics_spec.rb +0 -224
  41. data/spec/spec.opts +0 -2
  42. data/spec/spec_helper.rb +0 -15
@@ -1 +0,0 @@
1
- /log
@@ -1,7 +0,0 @@
1
- # SNOGmetrics example application
2
-
3
- This is a small Rails application that uses SNOGmetrics. Look in `app/controllers/snogs_controller.rb` to see how you interact with the API from a controller, and look at `app/views/layouts/application.html.erb` to see the snipplet you need to add to your layout file.
4
-
5
- Because it's easier for me when I code I've added SNOGmetrics as a plugin in the `vendor/plugins` directory (by way of symlinks), but in a real application you would add the gem in `config/environment.rb` (there's a out-commented line there if you want to see how it's done).
6
-
7
- To set the KISSmetrics API key you need to add an initializer, see `config/initializers/snogmetrics.rb` for an example.
@@ -1,10 +0,0 @@
1
- # Add your own tasks in files placed in lib/tasks ending in .rake,
2
- # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
-
4
- require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5
-
6
- require 'rake'
7
- require 'rake/testtask'
8
- require 'rake/rdoctask'
9
-
10
- require 'tasks/rails'
@@ -1,2 +0,0 @@
1
- class ApplicationController < ActionController::Base
2
- end
@@ -1,9 +0,0 @@
1
- class SnogsController < ApplicationController
2
-
3
- def create
4
- km.identify(params[:snog][:who])
5
- km.record('want_to_snog', :whom => params[:snog][:whom])
6
- redirect_to thank_you_snogs_path
7
- end
8
-
9
- end
@@ -1,12 +0,0 @@
1
- <!DOCTYPE html>
2
-
3
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
- <head>
5
- <title>SNOGmetrics</title>
6
- </head>
7
- <body>
8
- <%= yield %>
9
- </body>
10
-
11
- <%= km.js! %>
12
- </html>
@@ -1,11 +0,0 @@
1
- <% form_for :snog, :url => {:action => :create} do |f| -%>
2
- <p>
3
- <%= f.label :who, 'Who are you?' %><br/>
4
- <%= f.text_field :who %>
5
- </p>
6
- <p>
7
- <%= f.label :whom, 'Whom would you like to snog?' %><br/>
8
- <%= f.text_field :whom %>
9
- </p>
10
- <p><%= f.submit 'Fullfill my wish!' %></p>
11
- <% end -%>
@@ -1 +0,0 @@
1
- Thank you for participating!
@@ -1,110 +0,0 @@
1
- # Don't change this file!
2
- # Configure your app in config/environment.rb and config/environments/*.rb
3
-
4
- RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5
-
6
- module Rails
7
- class << self
8
- def boot!
9
- unless booted?
10
- preinitialize
11
- pick_boot.run
12
- end
13
- end
14
-
15
- def booted?
16
- defined? Rails::Initializer
17
- end
18
-
19
- def pick_boot
20
- (vendor_rails? ? VendorBoot : GemBoot).new
21
- end
22
-
23
- def vendor_rails?
24
- File.exist?("#{RAILS_ROOT}/vendor/rails")
25
- end
26
-
27
- def preinitialize
28
- load(preinitializer_path) if File.exist?(preinitializer_path)
29
- end
30
-
31
- def preinitializer_path
32
- "#{RAILS_ROOT}/config/preinitializer.rb"
33
- end
34
- end
35
-
36
- class Boot
37
- def run
38
- load_initializer
39
- Rails::Initializer.run(:set_load_path)
40
- end
41
- end
42
-
43
- class VendorBoot < Boot
44
- def load_initializer
45
- require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46
- Rails::Initializer.run(:install_gem_spec_stubs)
47
- Rails::GemDependency.add_frozen_gem_path
48
- end
49
- end
50
-
51
- class GemBoot < Boot
52
- def load_initializer
53
- self.class.load_rubygems
54
- load_rails_gem
55
- require 'initializer'
56
- end
57
-
58
- def load_rails_gem
59
- if version = self.class.gem_version
60
- gem 'rails', version
61
- else
62
- gem 'rails'
63
- end
64
- rescue Gem::LoadError => load_error
65
- $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
66
- exit 1
67
- end
68
-
69
- class << self
70
- def rubygems_version
71
- Gem::RubyGemsVersion rescue nil
72
- end
73
-
74
- def gem_version
75
- if defined? RAILS_GEM_VERSION
76
- RAILS_GEM_VERSION
77
- elsif ENV.include?('RAILS_GEM_VERSION')
78
- ENV['RAILS_GEM_VERSION']
79
- else
80
- parse_gem_version(read_environment_rb)
81
- end
82
- end
83
-
84
- def load_rubygems
85
- min_version = '1.3.2'
86
- require 'rubygems'
87
- unless rubygems_version >= min_version
88
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
89
- exit 1
90
- end
91
-
92
- rescue LoadError
93
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
94
- exit 1
95
- end
96
-
97
- def parse_gem_version(text)
98
- $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
99
- end
100
-
101
- private
102
- def read_environment_rb
103
- File.read("#{RAILS_ROOT}/config/environment.rb")
104
- end
105
- end
106
- end
107
- end
108
-
109
- # All that for this:
110
- Rails.boot!
@@ -1,13 +0,0 @@
1
- RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION
2
-
3
- require File.join(File.dirname(__FILE__), 'boot')
4
-
5
- Rails::Initializer.run do |config|
6
- # Usually you would add SNOGmetrics by adding the gem here, but in this
7
- # example app I have put the code as a plugin, because it's more convenient
8
- # when I code new features.
9
- #config.gem 'snogmetrics'
10
-
11
- config.frameworks -= [:active_record, :active_resource, :action_mailer]
12
- config.action_controller.session = {:key => '_snoggy_session', :secret => 'd08d2ef897ba8d7477bc3088dde396ac'}
13
- end
@@ -1,6 +0,0 @@
1
- config.cache_classes = false
2
- config.whiny_nils = true
3
- config.action_controller.consider_all_requests_local = true
4
- config.action_view.debug_rjs = true
5
- config.action_controller.perform_caching = false
6
- config.action_mailer.raise_delivery_errors = false
@@ -1,4 +0,0 @@
1
- config.cache_classes = true
2
- config.action_controller.consider_all_requests_local = false
3
- config.action_controller.perform_caching = true
4
- config.action_view.cache_template_loading = true
@@ -1,6 +0,0 @@
1
- config.cache_classes = true
2
- config.whiny_nils = true
3
- config.action_controller.consider_all_requests_local = true
4
- config.action_controller.perform_caching = false
5
- config.action_view.cache_template_loading = true
6
- config.action_controller.allow_forgery_protection = false
@@ -1,14 +0,0 @@
1
- # This is where you configure SNOGmetrics. Just override the #kissmetrics_api_key
2
- # method of the module to return the API key.
3
- module Snogmetrics
4
- def kissmetrics_api_key
5
- 'abc123'
6
- end
7
- end
8
-
9
- # If you need to load the API from a YAML file, you can do something like the
10
- # following. It loads the key and puts it in a local variable, then it overrides
11
- # the #kissmetrics_api_key method with a closure that has access to the local
12
- # variable 'key'.
13
- #key = YAML.load(ERB.new(File.read('path/to/file.yml')).result)[RAILS_ENV].symbolize_keys[:kissmetrics_api_key]
14
- #Snogmetrics.send(:define_method, :kissmetrics_api_key) { key }
@@ -1,4 +0,0 @@
1
- ActionController::Routing::Routes.draw do |map|
2
- map.resources :snogs, :only => %w(new create), :collection => {:thank_you => :get}
3
- map.root :controller => :snogs, :action => :new
4
- end
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- $LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info"
4
- require 'commands/about'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- require 'commands/console'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- require 'commands/dbconsole'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- require 'commands/destroy'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- require 'commands/generate'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../../config/boot', __FILE__)
3
- require 'commands/performance/benchmarker'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../../config/boot', __FILE__)
3
- require 'commands/performance/profiler'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- require 'commands/plugin'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- require 'commands/runner'
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require File.expand_path('../../config/boot', __FILE__)
3
- require 'commands/server'
@@ -1,4 +0,0 @@
1
- require 'snogmetrics'
2
-
3
- ActionController::Base.send(:include, Snogmetrics)
4
- ActionView::Base.send(:include, Snogmetrics)
@@ -1,4 +0,0 @@
1
- require 'snogmetrics'
2
-
3
- ActionController::Base.send(:include, Snogmetrics)
4
- ActionView::Base.send(:include, Snogmetrics)
@@ -1,224 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
-
4
- module Rails
5
- def self.env
6
- self
7
- end
8
-
9
- def self.production?
10
- false
11
- end
12
- end
13
-
14
-
15
- describe Snogmetrics do
16
-
17
- before do
18
- @session = {}
19
- @context = Object.new
20
- @context.extend(Snogmetrics)
21
- @context.stub!(:session).and_return(@session)
22
- @context.stub!(:kissmetrics_api_key).and_return('abc123')
23
- end
24
-
25
- describe '#record' do
26
- it 'will output code that pushes an event with the specified name and properties' do
27
- @context.km.record('hello world', :foo => 'bar')
28
- @context.km.js.should include('_kmq.push(["record","hello world",{"foo":"bar"}]);')
29
- end
30
-
31
- it 'will output code that pushes an event with name only' do
32
- @context.km.record('foo')
33
- @context.km.js.should include('_kmq.push(["record","foo"]);')
34
- end
35
-
36
- it 'will output code that pushes an event with properties only' do
37
- @context.km.record({:foo => 'bar', :plink => :plonk})
38
- @context.km.js.should match(%r#_kmq.push\(\["record",\{(?:"foo":"bar","plink":"plonk"|"plink":"plonk","foo":"bar")\}\]\)#)
39
- end
40
-
41
- it 'complains if called without arguments' do
42
- running { @context.km.record }.should raise_error
43
- end
44
-
45
- it 'complains if called with more than two arguments' do
46
- running { @context.km.record(1, 2, 3) }.should raise_error
47
- end
48
-
49
- it 'will output code that pushes events with the same name in the order they were recorded' do
50
- @context.km.record('An important event', :p => 3)
51
- @context.km.record('An important event', :p => 4)
52
- js = @context.km.js
53
- first = '_kmq.push(["record","An important event",{"p":3}]);'
54
- second = '_kmq.push(["record","An important event",{"p":4}]);'
55
- js.should include(first)
56
- js.should include(second)
57
- js.index(first).should < js.index(second)
58
- end
59
- end
60
-
61
- describe '#trackClick' do
62
- it 'will output code that pushes an event with the specified name and properties' do
63
- @context.km.trackClick('tagid', 'hello world', :foo => 'bar')
64
- @context.km.js.should include('_kmq.push(["trackClick","tagid","hello world",{"foo":"bar"}]);')
65
- end
66
-
67
- it 'will output code that pushes an event with name only' do
68
- @context.km.trackClick('tagid', 'foo')
69
- @context.km.js.should include('_kmq.push(["trackClick","tagid","foo"]);')
70
- end
71
-
72
- it 'will output code that pushes an event with properties only' do
73
- @context.km.trackClick('tagid', {:foo => 'bar', :plink => :plonk})
74
- @context.km.js.should match(%r#_kmq.push\(\["trackClick","tagid",\{(?:"foo":"bar","plink":"plonk"|"plink":"plonk","foo":"bar")\}\]\)#)
75
- end
76
-
77
- it 'complains if called without arguments' do
78
- running { @context.km.trackClick }.should raise_error
79
- end
80
-
81
- it 'complains if called with selector only' do
82
- running { @context.km.trackClick('tagid') }.should raise_error
83
- end
84
-
85
- it 'complains if called with more than three arguments' do
86
- running { @context.km.trackClick('tagid', 'hello world', {:foo => 'bar'}, '12') }.should raise_error
87
- end
88
- end
89
-
90
- describe '#identify' do
91
- it 'will output code that pushes an identify call with the provided identity' do
92
- @context.km.identify('Phil')
93
- @context.km.js.should include('_kmq.push(["identify","Phil"]);')
94
- end
95
-
96
- it 'will only output the last identity set' do
97
- @context.km.identify('Phil')
98
- @context.km.identify('Anne')
99
- @context.km.identify('Steve')
100
- @context.km.js.should_not include('Phil')
101
- @context.km.js.should_not include('Anne')
102
- @context.km.js.should include('Steve')
103
- end
104
- end
105
-
106
- describe '#set' do
107
- it 'will output code that pushes a set call with the provided experiment name and variant' do
108
- @context.km.set('My Awesome Experiment', 'variant_a')
109
- @context.km.js.should include('_kmq.push(["set",{"My Awesome Experiment":"variant_a"}])')
110
- end
111
- end
112
-
113
- describe '#js' do
114
- context 'in production' do
115
- before do
116
- Rails.stub!(:env).and_return(mock('env', :production? => true))
117
- end
118
-
119
- it 'outputs a JavaScript tag that loads the KISSmetrics API for the provided API key' do
120
- @context.stub!(:kissmetrics_api_key).and_return('cab1ebeef')
121
- @context.km.identify('Phil')
122
- @context.km.js.should include('scripts.kissmetrics.com/cab1ebeef.1.js')
123
- end
124
- end
125
-
126
- context 'overriding #use_fake_kissmetrics_api?' do
127
- it 'will do your bidding, and not be influenced by Rails.env' do
128
- Rails.stub!(:env).and_return(mock('env', :production? => true))
129
- @context.stub!(:use_fake_kissmetrics_api?).and_return(true)
130
- @context.km.identify('Joyce')
131
- @context.km.js.should_not include('scripts.kissmetrics.com')
132
- end
133
- end
134
-
135
- context 'overriding #output_strategy with :console_log' do
136
- it 'outputs calls to console.log' do
137
- Rails.stub!(:env).and_return(mock('env', :production? => true))
138
- @context.stub!(:output_strategy).and_return(:console_log)
139
- @context.km.identify('Joyce')
140
- @context.km.js.should_not include('scripts.kissmetrics.com')
141
- @context.km.js.should include('console.dir')
142
- end
143
- end
144
-
145
- context 'overriding #output_strategy with :array' do
146
- it 'just stores calls in the _kmq array' do
147
- Rails.stub!(:env).and_return(mock('env', :production? => true))
148
- @context.stub!(:output_strategy).and_return(:array)
149
- @context.km.identify('Joyce')
150
- @context.km.js.should_not include('scripts.kissmetrics.com')
151
- @context.km.js.should_not include('console.dir')
152
- end
153
- end
154
-
155
- context 'overriding #output_strategy with :live' do
156
- it 'sends calls to KISSmetrics' do
157
- Rails.stub!(:env).and_return(mock('env', :production? => true))
158
- @context.stub!(:output_strategy).and_return(:live)
159
- @context.km.identify('Joyce')
160
- @context.km.js.should include('scripts.kissmetrics.com')
161
- @context.km.js.should_not include('console.dir')
162
- end
163
- end
164
-
165
- context 'overriding #output_strategy with something else' do
166
- it 'raises' do
167
- @context.stub!(:output_strategy).and_return(:something_else)
168
- lambda {
169
- @context.km.js.should include('scripts.kissmetrics.com')
170
- }.should raise_error(RuntimeError, "Unknown KISSmetrics output strategy: something_else")
171
- end
172
- end
173
-
174
- it 'outputs javascript even if there are no events and no identity' do
175
- @context.km.js.should include('kmq')
176
- end
177
-
178
- it 'outputs code that conditionally sets the _kmq variable' do
179
- @context.km.identify('Phil')
180
- @context.km.js.should include('var _kmq = _kmq || [];')
181
- end
182
-
183
- it 'outputs code that pushes an event for every #record call' do
184
- @context.km.record('1')
185
- @context.km.record('2')
186
- @context.km.record('3')
187
- @context.km.js.scan(/_kmq.push\(\["record","\d"\]\)/).should have(3).items
188
- end
189
-
190
- it 'resets the session when passed :reset => true' do
191
- @context.km.record('hello world')
192
- @context.km.js(:reset => true)
193
- @context.km.js.should_not include('hello world')
194
- end
195
-
196
- it 'does not let HTML slip through' do
197
- @context.km.identify('</html>')
198
- @context.km.js.should_not include('</html>')
199
- end
200
- end
201
-
202
- describe '#js!' do
203
- it 'works like #js(:reset => true)' do
204
- @context.km.record('hello world')
205
- @context.km.js!
206
- @context.km.js!.should_not include('_kmq.push(["record"')
207
- end
208
-
209
- it 'does not push an identify call if the identity has already been sent once' do
210
- @context.km.identify('Steve')
211
- @context.km.js!
212
- @context.km.identify('Steve')
213
- @context.km.js!.should_not include('_kmq.push(["identify"')
214
- end
215
-
216
- it 'ouputs code that pushes an identify call if #identify is called with a new identity' do
217
- @context.km.identify('Steve')
218
- @context.km.js!
219
- @context.km.identify('Anne')
220
- @context.km.js!.should include('_kmq.push(["identify","Anne"])')
221
- end
222
- end
223
-
224
- end