analytical 1.9.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -63,6 +63,21 @@ By default, Analytical will be disabled in development mode... and it will enabl
63
63
 
64
64
  New modules should be fairly easy to add. Follow the structure that I've used in the Clicky, Google, and KISSMetrics modules... and you should be fine. All modules should include the Analytical::Base::Api module, so that they have some default behavior for methods that they don't support or need.
65
65
 
66
+ == Session-based command queues
67
+
68
+ By default, any Analytical commands that are queued in a controller that subsequently redirects won't be emitted to the client. This is because the redirect triggers a new request, and everything is cleared out at the beginning of each request.
69
+
70
+ However, if you would like to be able to queue commands between requests... there's a new option that supports this behavior:
71
+
72
+ analytical :modules=>[:console, :google], :use_session_store=>true
73
+
74
+ This will store the queued commands in the user session, clearing them out when they are emitted to the client, but allowing you to make calls like:
75
+
76
+ Analytical.track 'something'
77
+
78
+ ... in your controller. After a redirect, the corresponding track() call will be emitted in the next request made by the client.
79
+ NOTE: This is new and somewhat experimental, and could cause problems if you store large amounts of data in the session. (there is a 4k limit to session data)
80
+
66
81
 
67
82
  == Note on Patches/Pull Requests
68
83
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.0
1
+ 2.0.0
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{analytical}
8
- s.version = "1.9.0"
8
+ s.version = "2.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joshua Krall", "Nathan Phelps", "Adam Anderson"]
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "analytical.gemspec",
27
27
  "example/.gitignore",
28
28
  "example/Gemfile",
29
+ "example/Gemfile.lock",
29
30
  "example/README",
30
31
  "example/Rakefile",
31
32
  "example/app/controllers/application_controller.rb",
@@ -77,6 +78,7 @@ Gem::Specification.new do |s|
77
78
  "lib/analytical.rb",
78
79
  "lib/analytical/api.rb",
79
80
  "lib/analytical/bot_detector.rb",
81
+ "lib/analytical/command_store.rb",
80
82
  "lib/analytical/modules/adwords.rb",
81
83
  "lib/analytical/modules/base.rb",
82
84
  "lib/analytical/modules/chartbeat.rb",
@@ -88,9 +90,11 @@ Gem::Specification.new do |s|
88
90
  "lib/analytical/modules/hubspot.rb",
89
91
  "lib/analytical/modules/kiss_metrics.rb",
90
92
  "lib/analytical/modules/optimizely.rb",
93
+ "lib/analytical/session_command_store.rb",
91
94
  "rails/init.rb",
92
95
  "spec/analytical/api_spec.rb",
93
96
  "spec/analytical/bot_detector_spec.rb",
97
+ "spec/analytical/command_store_spec.rb",
94
98
  "spec/analytical/modules/base_spec.rb",
95
99
  "spec/analytical/modules/chartbeat_spec.rb",
96
100
  "spec/analytical/modules/clicky_spec.rb",
@@ -98,6 +102,7 @@ Gem::Specification.new do |s|
98
102
  "spec/analytical/modules/google_spec.rb",
99
103
  "spec/analytical/modules/kiss_metrics_spec.rb",
100
104
  "spec/analytical/modules/optimizely_spec.rb",
105
+ "spec/analytical/session_command_store_spec.rb",
101
106
  "spec/analytical_spec.rb",
102
107
  "spec/config/analytical.yml",
103
108
  "spec/spec.opts",
@@ -111,6 +116,7 @@ Gem::Specification.new do |s|
111
116
  s.test_files = [
112
117
  "spec/analytical/api_spec.rb",
113
118
  "spec/analytical/bot_detector_spec.rb",
119
+ "spec/analytical/command_store_spec.rb",
114
120
  "spec/analytical/modules/base_spec.rb",
115
121
  "spec/analytical/modules/chartbeat_spec.rb",
116
122
  "spec/analytical/modules/clicky_spec.rb",
@@ -118,6 +124,7 @@ Gem::Specification.new do |s|
118
124
  "spec/analytical/modules/google_spec.rb",
119
125
  "spec/analytical/modules/kiss_metrics_spec.rb",
120
126
  "spec/analytical/modules/optimizely_spec.rb",
127
+ "spec/analytical/session_command_store_spec.rb",
121
128
  "spec/analytical_spec.rb",
122
129
  "spec/spec_helper.rb"
123
130
  ]
@@ -1,6 +1,6 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'rails', '3.0.0.beta3'
3
+ gem 'rails'
4
4
 
5
5
  # Bundle edge Rails instead:
6
6
  # gem 'rails', :git => 'git://github.com/rails/rails.git'
@@ -0,0 +1,82 @@
1
+ PATH
2
+ remote: /Users/krall/Programming/analytical
3
+ specs:
4
+ analytical (1.8.0)
5
+ activesupport
6
+ json
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ abstract (1.0.0)
12
+ actionmailer (3.0.0)
13
+ actionpack (= 3.0.0)
14
+ mail (~> 2.2.5)
15
+ actionpack (3.0.0)
16
+ activemodel (= 3.0.0)
17
+ activesupport (= 3.0.0)
18
+ builder (~> 2.1.2)
19
+ erubis (~> 2.6.6)
20
+ i18n (~> 0.4.1)
21
+ rack (~> 1.2.1)
22
+ rack-mount (~> 0.6.12)
23
+ rack-test (~> 0.5.4)
24
+ tzinfo (~> 0.3.23)
25
+ activemodel (3.0.0)
26
+ activesupport (= 3.0.0)
27
+ builder (~> 2.1.2)
28
+ i18n (~> 0.4.1)
29
+ activerecord (3.0.0)
30
+ activemodel (= 3.0.0)
31
+ activesupport (= 3.0.0)
32
+ arel (~> 1.0.0)
33
+ tzinfo (~> 0.3.23)
34
+ activeresource (3.0.0)
35
+ activemodel (= 3.0.0)
36
+ activesupport (= 3.0.0)
37
+ activesupport (3.0.0)
38
+ arel (1.0.1)
39
+ activesupport (~> 3.0.0)
40
+ builder (2.1.2)
41
+ erubis (2.6.6)
42
+ abstract (>= 1.0.0)
43
+ i18n (0.4.1)
44
+ json (1.4.6)
45
+ mail (2.2.5)
46
+ activesupport (>= 2.3.6)
47
+ mime-types
48
+ treetop (>= 1.4.5)
49
+ mime-types (1.16)
50
+ polyglot (0.3.1)
51
+ rack (1.2.1)
52
+ rack-mount (0.6.13)
53
+ rack (>= 1.0.0)
54
+ rack-test (0.5.4)
55
+ rack (>= 1.0)
56
+ rails (3.0.0)
57
+ actionmailer (= 3.0.0)
58
+ actionpack (= 3.0.0)
59
+ activerecord (= 3.0.0)
60
+ activeresource (= 3.0.0)
61
+ activesupport (= 3.0.0)
62
+ bundler (~> 1.0.0)
63
+ railties (= 3.0.0)
64
+ railties (3.0.0)
65
+ actionpack (= 3.0.0)
66
+ activesupport (= 3.0.0)
67
+ rake (>= 0.8.4)
68
+ thor (~> 0.14.0)
69
+ rake (0.8.7)
70
+ sqlite3-ruby (1.3.1)
71
+ thor (0.14.0)
72
+ treetop (1.4.8)
73
+ polyglot (>= 0.3.1)
74
+ tzinfo (0.3.23)
75
+
76
+ PLATFORMS
77
+ ruby
78
+
79
+ DEPENDENCIES
80
+ analytical!
81
+ rails
82
+ sqlite3-ruby
@@ -2,5 +2,5 @@ class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
3
  layout 'application'
4
4
 
5
- analytical :modules=>[:console, :google, :clicky], :disable_if=>lambda{false}
5
+ analytical :modules=>[:console, :google, :clicky], :disable_if=>lambda{false}, :use_session_store=>true
6
6
  end
@@ -6,6 +6,13 @@ class PageController < ApplicationController
6
6
  end
7
7
 
8
8
  def test_b
9
+ analytical.clicky.track('track link in A')
9
10
  analytical.track 'track in controller'
10
11
  end
12
+
13
+ def test_c
14
+ analytical.track 'track in controller that redirects'
15
+ redirect_to root_path
16
+ end
17
+
11
18
  end
@@ -2,4 +2,5 @@
2
2
  <p>
3
3
  <%= link_to 'A', '/page/test_a' %><br />
4
4
  <%= link_to 'B', '/page/test_b' %><br />
5
+ <%= link_to 'C', '/page/test_c' %><br />
5
6
  </p>
@@ -3,6 +3,7 @@
3
3
  <h1>Page#test_a</h1>
4
4
  <p>
5
5
  <%= link_to 'B', '/page/test_b' %><br />
6
+ <%= link_to 'C', '/page/test_c' %><br />
6
7
  <%= link_to 'index', '/' %><br />
7
8
  <a href='#' onclick="<%= analytical.now.track('track link in A') %>; return false;">click me to track all modules</a><br />
8
9
  </p>
@@ -1,6 +1,7 @@
1
1
  <h1>Page#test_b</h1>
2
2
  <p>
3
3
  <%= link_to 'A', '/page/test_a' %><br />
4
+ <%= link_to 'C', '/page/test_c' %><br />
4
5
  <%= link_to 'index', '/' %><br />
5
- <a href='#' onclick="<%= analytical.clicky.track('track link in A') %>; return false;">track clicky only</a><br />
6
+ <a href='#' onclick="<%= analytical.console.track('track link in A') %>; return false;">track console only</a><br />
6
7
  </p>
@@ -3,3 +3,5 @@ require File.expand_path('../application', __FILE__)
3
3
 
4
4
  # Initialize the rails application
5
5
  Example::Application.initialize!
6
+
7
+ # Rails.backtrace_cleaner.remove_silencers!
@@ -16,4 +16,6 @@ Example::Application.configure do
16
16
 
17
17
  # Don't care if the mailer can't send
18
18
  config.action_mailer.raise_delivery_errors = false
19
+
20
+ config.active_support.deprecation = :log
19
21
  end
@@ -2,8 +2,7 @@ Example::Application.routes.draw do |map|
2
2
  get "page/index"
3
3
  get "page/test_a"
4
4
  get "page/test_b"
5
- get "index/test_a"
6
- get "index/test_b"
5
+ get "page/test_c"
7
6
 
8
7
  # You can have the root of your site routed with "root"
9
8
  # just remember to delete public/index.html.
@@ -40,6 +40,7 @@ module Analytical
40
40
  if options[:disable_if].call(self)
41
41
  options[:modules] = options[:development_modules]
42
42
  end
43
+ options[:session] = session if options[:use_session_store]
43
44
  if analytical_is_robot?(request.user_agent)
44
45
  options[:modules] = []
45
46
  end
@@ -1,4 +1,10 @@
1
1
  module Analytical
2
+ module Modules
3
+ class DummyModule
4
+ include Analytical::Modules::Base
5
+ def method_missing(method, *args, &block); nil; end
6
+ end
7
+ end
2
8
 
3
9
  class Api
4
10
  attr_accessor :options, :modules
@@ -7,9 +13,12 @@ module Analytical
7
13
  @options = options
8
14
  @modules = @options[:modules].inject(ActiveSupport::OrderedHash.new) do |h, m|
9
15
  module_options = @options.merge(@options[m] || {})
16
+ module_options.delete(:modules)
17
+ module_options[:session_store] = Analytical::SessionCommandStore.new(@options[:session], m) if @options[:session]
10
18
  h[m] = "Analytical::Modules::#{m.to_s.camelize}".constantize.new(module_options)
11
19
  h
12
20
  end
21
+ @dummy_module = Analytical::Modules::DummyModule.new
13
22
  end
14
23
 
15
24
  #
@@ -18,10 +27,13 @@ module Analytical
18
27
  # analytical.console.go 'make', :some=>:cookies
19
28
  #
20
29
  def method_missing(method, *args, &block)
21
- if @modules.keys.include?(method.to_sym)
22
- @modules[method.to_sym]
30
+ method = method.to_sym
31
+ if @modules.keys.include?(method)
32
+ @modules[method]
33
+ elsif available_modules.include?(method)
34
+ @dummy_module
23
35
  else
24
- process_command method.to_sym, *args
36
+ process_command method, *args
25
37
  end
26
38
  end
27
39
 
@@ -93,6 +105,13 @@ module Analytical
93
105
  m.init_javascript(location)
94
106
  end.compact.join("\n")
95
107
  end
108
+
109
+ def available_modules
110
+ Dir.glob(File.dirname(__FILE__)+'/modules/*.rb').collect do |f|
111
+ File.basename(f).sub(/.rb/,'').to_sym
112
+ end - [:base]
113
+ end
114
+
96
115
  end
97
116
 
98
117
  end
@@ -0,0 +1,19 @@
1
+ module Analytical
2
+ class CommandStore
3
+ attr_accessor :commands
4
+
5
+ def initialize(initial_list=nil)
6
+ @commands = initial_list || []
7
+ end
8
+
9
+ def flush
10
+ @commands = []
11
+ end
12
+
13
+ # Pass any array methods on to the internal array
14
+ def method_missing(method, *args, &block)
15
+ @commands.send(method, *args, &block)
16
+ end
17
+
18
+ end
19
+ end
@@ -2,13 +2,13 @@ module Analytical
2
2
  module Modules
3
3
  module Base
4
4
  attr_reader :tracking_command_location, :options, :initialized
5
- attr_accessor :commands
5
+ attr_reader :command_store
6
6
 
7
7
  def initialize(_options={})
8
8
  @options = _options
9
9
  @tracking_command_location = :body_prepend
10
10
  @initialized = false
11
- @commands = []
11
+ @command_store = @options[:session_store] || Analytical::CommandStore.new
12
12
  end
13
13
 
14
14
  def protocol
@@ -43,16 +43,16 @@ module Analytical
43
43
 
44
44
  def queue(*args)
45
45
  if args.first==:identify
46
- @commands.unshift args
46
+ @command_store.unshift args
47
47
  else
48
- @commands << args
48
+ @command_store << args
49
49
  end
50
50
  end
51
51
  def process_queued_commands
52
- command_strings = @commands.collect do |c|
52
+ command_strings = @command_store.collect do |c|
53
53
  send(*c) if respond_to?(c.first)
54
54
  end.compact
55
- @commands = []
55
+ @command_store.flush
56
56
  command_strings
57
57
  end
58
58
 
@@ -18,13 +18,13 @@ module Analytical
18
18
  HTML
19
19
 
20
20
  identify_commands = []
21
- @commands.each do |c|
21
+ @command_store.commands.each do |c|
22
22
  if c[0] == :identify
23
23
  identify_commands << identify(*c[1..-1])
24
24
  end
25
25
  end
26
26
  js = identify_commands.join("\n") + "\n" + js
27
- @commands = @commands.delete_if {|c| c[0] == :identify }
27
+ @command_store.commands = @command_store.commands.delete_if {|c| c[0] == :identify }
28
28
 
29
29
  js
30
30
  end
@@ -0,0 +1,39 @@
1
+ module Analytical
2
+ class SessionCommandStore
3
+ attr_reader :session, :module_key
4
+
5
+ def initialize(session, module_key, initial_list=nil)
6
+ @session = session
7
+ @module_key = module_key
8
+ @session_key = ('analytical_'+module_key.to_s).to_sym
9
+ ensure_session_setup!(initial_list)
10
+ end
11
+
12
+ def assign(v)
13
+ self.commands = v
14
+ end
15
+
16
+ def commands
17
+ @session[@session_key]
18
+ end
19
+ def commands=(v)
20
+ @session[@session_key] = v
21
+ end
22
+
23
+ def flush
24
+ self.commands = []
25
+ end
26
+
27
+ # Pass any array methods on to the internal array
28
+ def method_missing(method, *args, &block)
29
+ commands.send(method, *args, &block)
30
+ end
31
+
32
+ private
33
+
34
+ def ensure_session_setup!(initial_list=nil)
35
+ self.commands ||= (initial_list || [])
36
+ end
37
+
38
+ end
39
+ end
@@ -16,6 +16,18 @@ describe "Analytical::Api" do
16
16
  Analytical::Modules::Console.should_receive(:new).with(hash_including(:ssl=>true)).and_return(@console = mock('console'))
17
17
  Analytical::Api.new :modules=>[:console], :ssl=>true
18
18
  end
19
+ describe 'with a session option' do
20
+ before(:each) do
21
+ @session = {}
22
+ end
23
+ it 'should create a new SessionCommandStore for each module' do
24
+ Analytical::SessionCommandStore.should_receive(:new).with(@session, :console).and_return(@console_store = mock('console_store'))
25
+ Analytical::SessionCommandStore.should_receive(:new).with(@session, :google).and_return(@google_store = mock('google_store'))
26
+ Analytical::Modules::Console.should_receive(:new).with(:session_store=>@console_store, :session=>@session).and_return(mock('console'))
27
+ Analytical::Modules::Google.should_receive(:new).with(:session_store=>@google_store, :session=>@session).and_return(mock('google'))
28
+ Analytical::Api.new :modules=>[:console, :google], :session=>@session
29
+ end
30
+ end
19
31
  end
20
32
 
21
33
  describe 'with modules' do
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Analytical::CommandStore do
4
+
5
+ describe 'when behaving exactly like an array' do
6
+ it 'should add elements' do
7
+ @store = Analytical::CommandStore.new ['a']
8
+ @store << 'b'
9
+ @store.commands.should == ['a', 'b']
10
+ end
11
+ it 'should unshift elements' do
12
+ @store = Analytical::CommandStore.new ['b']
13
+ @store.unshift 'a'
14
+ @store.commands.should == ['a', 'b']
15
+ end
16
+ it 'should iterate over elements' do
17
+ @store = Analytical::CommandStore.new ['a', 'b']
18
+ @store.each do |elem|
19
+ ['a', 'b'].include?(elem).should be_true
20
+ end
21
+ end
22
+ it 'should have size' do
23
+ @store = Analytical::CommandStore.new ['a', 'b']
24
+ @store.size.should == 2
25
+ end
26
+ end
27
+
28
+ describe 'when flushing' do
29
+ it 'should empty the list' do
30
+ @store = Analytical::CommandStore.new ['a', 'b']
31
+ @store.flush
32
+ @store.size.should == 0
33
+ end
34
+ end
35
+
36
+ end
@@ -24,18 +24,18 @@ describe Analytical::Modules::Base do
24
24
  describe '#queue' do
25
25
  before(:each) do
26
26
  @api = BaseApiDummy.new(:parent=>mock('parent'))
27
- @api.commands = [:a, :b, :c]
27
+ @api.command_store.commands = [:a, :b, :c]
28
28
  end
29
29
  describe 'with an identify command' do
30
30
  it 'should store it at the head of the command list' do
31
31
  @api.queue :identify, 'someone', {:some=>:args}
32
- @api.commands.should == [[:identify, 'someone', {:some=>:args}], :a, :b, :c]
32
+ @api.command_store.commands.should == [[:identify, 'someone', {:some=>:args}], :a, :b, :c]
33
33
  end
34
34
  end
35
35
  describe 'with any other command' do
36
36
  it 'should store it at the end of the command list' do
37
37
  @api.queue :other, {:some=>:args}
38
- @api.commands.should == [:a, :b, :c, [:other, {:some=>:args}]]
38
+ @api.command_store.commands.should == [:a, :b, :c, [:other, {:some=>:args}]]
39
39
  end
40
40
  end
41
41
  end
@@ -43,7 +43,7 @@ describe Analytical::Modules::Base do
43
43
  describe '#process_queued_commands' do
44
44
  before(:each) do
45
45
  @api = BaseApiDummy.new(:parent=>mock('parent'))
46
- @api.commands = [[:a, 1, 2, 3], [:b, {:some=>:args}]]
46
+ @api.command_store.commands = [[:a, 1, 2, 3], [:b, {:some=>:args}]]
47
47
  @api.stub!(:a).and_return('a')
48
48
  @api.stub!(:b).and_return('b')
49
49
  end
@@ -57,10 +57,10 @@ describe Analytical::Modules::Base do
57
57
  end
58
58
  it 'should clear the commands list' do
59
59
  @api.process_queued_commands
60
- @api.commands == []
60
+ @api.command_store.commands == []
61
61
  end
62
62
  it "should not store an unrecognized command" do
63
- @api.commands << [:c, 1]
63
+ @api.command_store.commands << [:c, 1]
64
64
  @api.process_queued_commands.should == ['a','b']
65
65
  end
66
66
  end
@@ -84,7 +84,7 @@ describe Analytical::Modules::Base do
84
84
 
85
85
  describe '#init_location' do
86
86
  before(:each) do
87
- @api = BaseApiDummy.new(:parent=>mock('parent'))
87
+ @api = BaseApiDummy.new
88
88
  end
89
89
  it 'should check for the init_location' do
90
90
  @api.should_receive(:init_location?).with(:some_location).and_return(false)
@@ -112,4 +112,14 @@ describe Analytical::Modules::Base do
112
112
  end
113
113
  end
114
114
 
115
+ describe 'with a custom session_store' do
116
+ before(:each) do
117
+ @session = {}
118
+ @store = Analytical::SessionCommandStore.new @session, :some_module
119
+ end
120
+ it 'should use the session_store' do
121
+ @api = BaseApiDummy.new :session_store=>@store
122
+ @api.command_store.should == @store
123
+ end
124
+ end
115
125
  end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Analytical::SessionCommandStore do
4
+
5
+ describe 'with a session hash' do
6
+ before(:each) do
7
+ @session = {}
8
+ end
9
+
10
+ it 'should add elements' do
11
+ @store = Analytical::SessionCommandStore.new @session, :some_module, ['a']
12
+ @store << 'b'
13
+ @session[:analytical_some_module].should == ['a', 'b']
14
+ end
15
+ it 'should unshift elements' do
16
+ @store = Analytical::SessionCommandStore.new @session, :some_module, ['b']
17
+ @store.unshift 'a'
18
+ @session[:analytical_some_module].should == ['a', 'b']
19
+ end
20
+ it 'should iterate over elements' do
21
+ @store = Analytical::SessionCommandStore.new @session, :some_module, ['a', 'b']
22
+ @store.each do |elem|
23
+ ['a', 'b'].include?(elem).should be_true
24
+ end
25
+ end
26
+ it 'should have size' do
27
+ @store = Analytical::SessionCommandStore.new @session, :some_module, ['a', 'b']
28
+ @store.size.should == 2
29
+ end
30
+
31
+ it 'should set up the :analytical session hash' do
32
+ @store = Analytical::SessionCommandStore.new @session, :some_module, ['a', 'b']
33
+ @session[:analytical_some_module].should_not be_nil
34
+ end
35
+
36
+ describe 'when flushing' do
37
+ it 'should empty the list' do
38
+ @store = Analytical::SessionCommandStore.new @session, :some_module, ['a', 'b']
39
+ @store.flush
40
+ @store.size.should == 0
41
+ end
42
+ it 'should empty the session key' do
43
+ @store = Analytical::SessionCommandStore.new @session, :some_module, ['a', 'b']
44
+ @store.flush
45
+ @session[:analytical_some_module].should == []
46
+ end
47
+ end
48
+ end
49
+
50
+ end
metadata CHANGED
@@ -3,10 +3,10 @@ name: analytical
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 1
7
- - 9
6
+ - 2
8
7
  - 0
9
- version: 1.9.0
8
+ - 0
9
+ version: 2.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joshua Krall
@@ -64,6 +64,7 @@ files:
64
64
  - analytical.gemspec
65
65
  - example/.gitignore
66
66
  - example/Gemfile
67
+ - example/Gemfile.lock
67
68
  - example/README
68
69
  - example/Rakefile
69
70
  - example/app/controllers/application_controller.rb
@@ -115,6 +116,7 @@ files:
115
116
  - lib/analytical.rb
116
117
  - lib/analytical/api.rb
117
118
  - lib/analytical/bot_detector.rb
119
+ - lib/analytical/command_store.rb
118
120
  - lib/analytical/modules/adwords.rb
119
121
  - lib/analytical/modules/base.rb
120
122
  - lib/analytical/modules/chartbeat.rb
@@ -126,9 +128,11 @@ files:
126
128
  - lib/analytical/modules/hubspot.rb
127
129
  - lib/analytical/modules/kiss_metrics.rb
128
130
  - lib/analytical/modules/optimizely.rb
131
+ - lib/analytical/session_command_store.rb
129
132
  - rails/init.rb
130
133
  - spec/analytical/api_spec.rb
131
134
  - spec/analytical/bot_detector_spec.rb
135
+ - spec/analytical/command_store_spec.rb
132
136
  - spec/analytical/modules/base_spec.rb
133
137
  - spec/analytical/modules/chartbeat_spec.rb
134
138
  - spec/analytical/modules/clicky_spec.rb
@@ -136,6 +140,7 @@ files:
136
140
  - spec/analytical/modules/google_spec.rb
137
141
  - spec/analytical/modules/kiss_metrics_spec.rb
138
142
  - spec/analytical/modules/optimizely_spec.rb
143
+ - spec/analytical/session_command_store_spec.rb
139
144
  - spec/analytical_spec.rb
140
145
  - spec/config/analytical.yml
141
146
  - spec/spec.opts
@@ -173,6 +178,7 @@ summary: Gem for managing multiple analytics services in your rails app.
173
178
  test_files:
174
179
  - spec/analytical/api_spec.rb
175
180
  - spec/analytical/bot_detector_spec.rb
181
+ - spec/analytical/command_store_spec.rb
176
182
  - spec/analytical/modules/base_spec.rb
177
183
  - spec/analytical/modules/chartbeat_spec.rb
178
184
  - spec/analytical/modules/clicky_spec.rb
@@ -180,5 +186,6 @@ test_files:
180
186
  - spec/analytical/modules/google_spec.rb
181
187
  - spec/analytical/modules/kiss_metrics_spec.rb
182
188
  - spec/analytical/modules/optimizely_spec.rb
189
+ - spec/analytical/session_command_store_spec.rb
183
190
  - spec/analytical_spec.rb
184
191
  - spec/spec_helper.rb