sfanalytics 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/lib/sfanalytics.rb +58 -0
- data/sfanalytics.gemspec +62 -0
- data/templates/analytics.html.haml +14 -0
- data/templates/line_item.html.haml +8 -0
- data/templates/transaction.html.haml +10 -0
- data/test/sfanalytics_spec.rb +149 -0
- data/test/spec.opts +4 -0
- data/test/spec_helper.rb +5 -0
- metadata +88 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Graeme Lawton
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= sfanalytics
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Graeme Lawton. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "sfanalytics"
|
8
|
+
gem.summary = %Q{Google Analytics Gem}
|
9
|
+
gem.description = %Q{
|
10
|
+
SFanalytics provides Google Analytics for your app. Probably only really
|
11
|
+
useful for Ecommerce users of analytics, to provide the functionality to add
|
12
|
+
the order items to your transactions for tracking in Analytics.
|
13
|
+
}
|
14
|
+
gem.email = "graeme.lawton@setfiremedia.com"
|
15
|
+
gem.homepage = "http://github.com/graemel/sfanalytics"
|
16
|
+
gem.authors = ["Graeme Lawton"]
|
17
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
Rake::TestTask.new(:test) do |test|
|
26
|
+
test.libs << 'lib' << 'test'
|
27
|
+
test.pattern = 'test/**/test_*.rb'
|
28
|
+
test.verbose = true
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
require 'rcov/rcovtask'
|
33
|
+
Rcov::RcovTask.new do |test|
|
34
|
+
test.libs << 'test'
|
35
|
+
test.pattern = 'test/**/test_*.rb'
|
36
|
+
test.verbose = true
|
37
|
+
end
|
38
|
+
rescue LoadError
|
39
|
+
task :rcov do
|
40
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
task :test => :check_dependencies
|
45
|
+
|
46
|
+
task :default => :test
|
47
|
+
|
48
|
+
require 'rake/rdoctask'
|
49
|
+
Rake::RDocTask.new do |rdoc|
|
50
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
51
|
+
|
52
|
+
rdoc.rdoc_dir = 'rdoc'
|
53
|
+
rdoc.title = "sfanalytics #{version}"
|
54
|
+
rdoc.rdoc_files.include('README*')
|
55
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
56
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/sfanalytics.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'haml'
|
2
|
+
|
3
|
+
class SFanalytics
|
4
|
+
attr_reader :analytics_id, :transaction, :line_items, :transaction_id
|
5
|
+
|
6
|
+
def initialize(analytics_id)
|
7
|
+
raise ArgumentError.new if ! analytics_id.match(/UA-\d{0,8}-\d{0,3}/)
|
8
|
+
@analytics_id = analytics_id
|
9
|
+
@line_items = ''
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate
|
13
|
+
|
14
|
+
template = File.read(File.dirname(__FILE__) + '/../templates/analytics.html.haml')
|
15
|
+
|
16
|
+
obj = Object.new
|
17
|
+
Haml::Engine.new(template).def_method(obj, :render, :analytics_id, :analytics_transaction, :line_items)
|
18
|
+
return obj.render(
|
19
|
+
:analytics_id => @analytics_id,
|
20
|
+
:analytics_transaction => @transaction,
|
21
|
+
:line_items => @line_items
|
22
|
+
)
|
23
|
+
|
24
|
+
obj = Object.new
|
25
|
+
Haml::Engine.new(template).def_method(obj, :render, :analytics_id)
|
26
|
+
return obj.render(:analytics_id => "Hello!")
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_transaction(transaction)
|
30
|
+
|
31
|
+
template = File.read(File.dirname(__FILE__) + '/../templates/transaction.html.haml')
|
32
|
+
|
33
|
+
obj = Object.new
|
34
|
+
Haml::Engine.new(template).def_method(obj, :render, :analytics_id, :transaction)
|
35
|
+
@transaction = obj.render(
|
36
|
+
:analytics_id => @analytics_id,
|
37
|
+
:transaction => transaction
|
38
|
+
)
|
39
|
+
|
40
|
+
@transaction_id = transaction[:id]
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_line_item(item)
|
45
|
+
raise "No Transaction Defined" unless(@transaction)
|
46
|
+
|
47
|
+
template = File.read(File.dirname(__FILE__) + '/../templates/line_item.html.haml')
|
48
|
+
|
49
|
+
obj = Object.new
|
50
|
+
Haml::Engine.new(template).def_method(obj, :render, :transaction, :item)
|
51
|
+
@line_items << obj.render(
|
52
|
+
:transaction => @transaction_id,
|
53
|
+
:item => item
|
54
|
+
)
|
55
|
+
|
56
|
+
return true
|
57
|
+
end
|
58
|
+
end
|
data/sfanalytics.gemspec
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{sfanalytics}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Graeme Lawton"]
|
12
|
+
s.date = %q{2010-04-29}
|
13
|
+
s.description = %q{
|
14
|
+
SFanalytics provides Google Analytics for your app. Probably only really
|
15
|
+
useful for Ecommerce users of analytics, to provide the functionality to add
|
16
|
+
the order items to your transactions for tracking in Analytics.
|
17
|
+
}
|
18
|
+
s.email = %q{graeme.lawton@setfiremedia.com}
|
19
|
+
s.extra_rdoc_files = [
|
20
|
+
"LICENSE",
|
21
|
+
"README.rdoc"
|
22
|
+
]
|
23
|
+
s.files = [
|
24
|
+
".document",
|
25
|
+
".gitignore",
|
26
|
+
"LICENSE",
|
27
|
+
"README.rdoc",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"lib/sfanalytics.rb",
|
31
|
+
"sfanalytics.gemspec",
|
32
|
+
"templates/analytics.html.haml",
|
33
|
+
"templates/line_item.html.haml",
|
34
|
+
"templates/transaction.html.haml",
|
35
|
+
"test/sfanalytics_spec.rb",
|
36
|
+
"test/spec.opts",
|
37
|
+
"test/spec_helper.rb"
|
38
|
+
]
|
39
|
+
s.homepage = %q{http://github.com/graemel/sfanalytics}
|
40
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.rubygems_version = %q{1.3.6}
|
43
|
+
s.summary = %q{Google Analytics Gem}
|
44
|
+
s.test_files = [
|
45
|
+
"test/sfanalytics_spec.rb",
|
46
|
+
"test/spec_helper.rb"
|
47
|
+
]
|
48
|
+
|
49
|
+
if s.respond_to? :specification_version then
|
50
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
51
|
+
s.specification_version = 3
|
52
|
+
|
53
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
54
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
57
|
+
end
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%script{:type => "text/javascript"}
|
2
|
+
var _gaq = _gaq || [];
|
3
|
+
|
4
|
+
= "_gaq.push(['_setAccount', '#{analytics_id}']);"
|
5
|
+
_gaq.push(['_trackPageview']);
|
6
|
+
|
7
|
+
= "#{analytics_transaction}"
|
8
|
+
= "#{line_items}"
|
9
|
+
|
10
|
+
(function() {
|
11
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
12
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
13
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
|
14
|
+
})();
|
@@ -0,0 +1,10 @@
|
|
1
|
+
= "_gaq.push(['_addTrans',"
|
2
|
+
= "'#{transaction[:id]}'," #Order ID
|
3
|
+
= "'#{transaction[:store_name]}'," #Store Name
|
4
|
+
= "'#{transaction[:total]}'," #Total Value
|
5
|
+
= "'#{transaction[:vat]}'," #VAT
|
6
|
+
= "'#{transaction[:postage]}'," #Postage
|
7
|
+
= "'#{transaction[:city]}'," #City
|
8
|
+
= "'#{transaction[:county]}'," #State
|
9
|
+
= "'#{transaction[:country]}', " #Country
|
10
|
+
= "]);"
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe SFanalytics, "initialize" do
|
4
|
+
|
5
|
+
it "should be instantiated with a valid looking analytics id" do
|
6
|
+
lambda { SFanalytics.new( "UA-1234567-1" ) }.should_not raise_error
|
7
|
+
lambda { SFanalytics.new() }.should raise_error(ArgumentError)
|
8
|
+
lambda { SFanalytics.new( "foobar" ) }.should raise_error(ArgumentError)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
describe SFanalytics, "generate" do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@sfanalytics = SFanalytics.new('UA-1234567-1')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to generate output code" do
|
20
|
+
@sfanalytics.should respond_to(:generate)
|
21
|
+
@sfanalytics.generate.class.should == String
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should generate the correct basic tracking code" do
|
25
|
+
@sfanalytics.generate.should == <<-EOS
|
26
|
+
<script type='text/javascript'>
|
27
|
+
var _gaq = _gaq || [];
|
28
|
+
_gaq.push(['_setAccount', 'UA-1234567-1']);
|
29
|
+
_gaq.push(['_trackPageview']);
|
30
|
+
|
31
|
+
|
32
|
+
(function() {
|
33
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
34
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
35
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
|
36
|
+
})();
|
37
|
+
</script>
|
38
|
+
EOS
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe SFanalytics, "generate_transaction" do
|
44
|
+
before(:each) do
|
45
|
+
@sfanalytics = SFanalytics.new('UA-1234567-1')
|
46
|
+
@trx_data = {
|
47
|
+
:id => 'A01',
|
48
|
+
:store_name => 'TEST STORE',
|
49
|
+
:total => '3.54',
|
50
|
+
:vat => '0.34',
|
51
|
+
:postage => '2.20',
|
52
|
+
:city => 'Test City',
|
53
|
+
:county => 'Test County',
|
54
|
+
:country => 'Test Kingdom'
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should allow a transaction to be added" do
|
59
|
+
@sfanalytics.should respond_to(:add_transaction)
|
60
|
+
lambda {@sfanalytics.add_transaction}.should raise_error(ArgumentError)
|
61
|
+
@sfanalytics.add_transaction(@trx_data).should == true
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should generate the correct code with a transaction" do
|
65
|
+
@sfanalytics.add_transaction(@trx_data).should
|
66
|
+
@sfanalytics.generate().should == <<-EOS
|
67
|
+
<script type='text/javascript'>
|
68
|
+
var _gaq = _gaq || [];
|
69
|
+
_gaq.push(['_setAccount', 'UA-1234567-1']);
|
70
|
+
_gaq.push(['_trackPageview']);
|
71
|
+
_gaq.push(['_addTrans',
|
72
|
+
'A01',
|
73
|
+
'TEST STORE',
|
74
|
+
'3.54',
|
75
|
+
'0.34',
|
76
|
+
'2.20',
|
77
|
+
'Test City',
|
78
|
+
'Test County',
|
79
|
+
'Test Kingdom',
|
80
|
+
]);
|
81
|
+
|
82
|
+
(function() {
|
83
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
84
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
85
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
|
86
|
+
})();
|
87
|
+
</script>
|
88
|
+
EOS
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe SFanalytics, "Add order items" do
|
93
|
+
|
94
|
+
before(:each) do
|
95
|
+
@sfanalytics = SFanalytics.new('UA-1234567-1')
|
96
|
+
@sfanalytics.add_transaction({
|
97
|
+
:id => 'A01',
|
98
|
+
:store_name => 'TEST STORE',
|
99
|
+
:total => '3.54',
|
100
|
+
:vat => '0.34',
|
101
|
+
:postage => '2.20',
|
102
|
+
:city => 'Test City',
|
103
|
+
:county => 'Test County',
|
104
|
+
:country => 'Test Kingdom'
|
105
|
+
})
|
106
|
+
@line_item = {
|
107
|
+
:sku => 'TEST123',
|
108
|
+
:name => 'Test Item',
|
109
|
+
:category => 'Test Categoru',
|
110
|
+
:price => '1.99',
|
111
|
+
:quantity => '2'
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should allow a line_item to be added" do
|
116
|
+
@sfanalytics.should respond_to(:add_line_item)
|
117
|
+
lambda {@sfanalytics.add_line_item}.should raise_error(ArgumentError)
|
118
|
+
@sfanalytics.add_line_item(@line_item).should == true
|
119
|
+
@sfanalytics.generate.should match /_addItem/
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should allow multiple line_items to be added" do
|
123
|
+
@sfanalytics.add_line_item(@line_item)
|
124
|
+
@sfanalytics.add_line_item(@line_item)
|
125
|
+
#Check there are two instances of _addItem
|
126
|
+
@sfanalytics.generate.split(/_addItem/).count.should == 3
|
127
|
+
|
128
|
+
@sfanalytics.generate.split(/TEST123/).count.should == 3
|
129
|
+
@sfanalytics.generate.split(/A01/).count.should == 4
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
describe SFanalytics, "Error Handling" do
|
135
|
+
before (:each) do
|
136
|
+
@line_item = {
|
137
|
+
:sku => 'TEST123',
|
138
|
+
:name => 'Test Item',
|
139
|
+
:category => 'Test Categoru',
|
140
|
+
:price => '1.99',
|
141
|
+
:quantity => '2'
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should fail if you try to add items with no transaction" do
|
146
|
+
sfanalytics = SFanalytics.new('UA-1234567-1')
|
147
|
+
lambda{sfanalytics.add_line_item(@line_item)}.should raise_error
|
148
|
+
end
|
149
|
+
end
|
data/test/spec.opts
ADDED
data/test/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sfanalytics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Graeme Lawton
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-29 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: thoughtbot-shoulda
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
description: "\n SFanalytics provides Google Analytics for your app. Probably only really\n useful for Ecommerce users of analytics, to provide the functionality to add\n the order items to your transactions for tracking in Analytics.\n "
|
33
|
+
email: graeme.lawton@setfiremedia.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- LICENSE
|
40
|
+
- README.rdoc
|
41
|
+
files:
|
42
|
+
- .document
|
43
|
+
- .gitignore
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
- Rakefile
|
47
|
+
- VERSION
|
48
|
+
- lib/sfanalytics.rb
|
49
|
+
- sfanalytics.gemspec
|
50
|
+
- templates/analytics.html.haml
|
51
|
+
- templates/line_item.html.haml
|
52
|
+
- templates/transaction.html.haml
|
53
|
+
- test/sfanalytics_spec.rb
|
54
|
+
- test/spec.opts
|
55
|
+
- test/spec_helper.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/graemel/sfanalytics
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.6
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: Google Analytics Gem
|
86
|
+
test_files:
|
87
|
+
- test/sfanalytics_spec.rb
|
88
|
+
- test/spec_helper.rb
|