garb 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- require 'rubygems'
2
1
  require 'rake/gempackagetask'
3
2
  require 'rake/testtask'
4
3
 
5
- require 'lib/garb/version'
4
+ $:.unshift File.expand_path('../lib', __FILE__)
5
+ require 'garb'
6
6
 
7
7
  task :default => :test
8
8
 
@@ -41,11 +41,12 @@ end
41
41
 
42
42
  begin
43
43
  require 'rcov/rcovtask'
44
-
44
+
45
45
  desc "Generate RCov coverage report"
46
46
  Rcov::RcovTask.new(:rcov) do |t|
47
+ t.libs << "test"
47
48
  t.test_files = FileList['test/**/*_test.rb']
48
- t.rcov_opts << "-x lib/garb.rb -x lib/garb/version.rb"
49
+ t.rcov_opts << "-x \"test/*,gems/*,/Library/Ruby/*,config/*\" -x lib/garb.rb -x lib/garb/version.rb --rails"
49
50
  end
50
51
  rescue LoadError
51
52
  nil
@@ -1,5 +1,3 @@
1
- $:.unshift File.expand_path(File.dirname(__FILE__))
2
-
3
1
  require 'net/http'
4
2
  require 'net/https'
5
3
 
@@ -11,8 +9,12 @@ require 'active_support'
11
9
  require 'garb/version'
12
10
  require 'garb/authentication_request'
13
11
  require 'garb/data_request'
12
+ require 'garb/account_feed_request'
14
13
  require 'garb/session'
15
14
  require 'garb/profile_reports'
15
+ require 'garb/step'
16
+ require 'garb/destination'
17
+ require 'garb/goal'
16
18
  require 'garb/profile'
17
19
  require 'garb/account'
18
20
  require 'garb/filter_parameters'
@@ -9,21 +9,13 @@ module Garb
9
9
  end
10
10
 
11
11
  def self.all(session = Session)
12
- # Profile.all.group_to_array{|p| p.account_id}.map{|profiles| new(profiles)}
12
+ profiles = {}
13
13
 
14
- profile_groups = Profile.all(session).inject({}) do |hash, profile|
15
- key = profile.account_id
16
-
17
- if hash.has_key?(key)
18
- hash[key] << profile
19
- else
20
- hash[key] = [profile]
21
- end
22
-
23
- hash
14
+ Profile.all(session).each do |profile|
15
+ (profiles[profile.account_id] ||= []) << profile
24
16
  end
25
17
 
26
- profile_groups.map {|k,v| v}.map {|profiles| new(profiles)}
18
+ profiles.map {|k,v| v}.map {|profiles| new(profiles)}
27
19
  end
28
20
  end
29
21
  end
@@ -0,0 +1,25 @@
1
+ module Garb
2
+ class AccountFeedRequest
3
+ URL = "https://www.google.com/analytics/feeds/accounts/default"
4
+
5
+ def initialize(session = Session)
6
+ @request = DataRequest.new(session, URL)
7
+ end
8
+
9
+ def response
10
+ @response ||= @request.send_request
11
+ end
12
+
13
+ def parsed_response
14
+ @parsed_response ||= Crack::XML.parse(response.body)
15
+ end
16
+
17
+ def entries
18
+ parsed_response ? [parsed_response['feed']['entry']].flatten : []
19
+ end
20
+
21
+ def segments
22
+ parsed_response ? [parsed_response['feed']['dxp:segment']].flatten : []
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ module Garb
2
+ class Destination
3
+ attr_reader :match_type, :expression, :steps
4
+
5
+ def initialize(attributes)
6
+ return unless attributes.is_a?(Hash)
7
+
8
+ @match_type = attributes['matchType']
9
+ @expression = attributes['expression']
10
+ @case_sensitive = (attributes['caseSensitive'] == 'true')
11
+
12
+ step_attributes = attributes[Garb.to_ga('step')]
13
+ @steps = Array(step_attributes.is_a?(Hash) ? [step_attributes] : step_attributes).map {|s| Step.new(s)}
14
+ end
15
+
16
+ def case_sensitive?
17
+ @case_sensitive
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Garb
2
+ class Goal
3
+ attr_reader :name, :number, :value, :destination
4
+
5
+ def initialize(attributes={})
6
+ return unless attributes.is_a?(Hash)
7
+
8
+ @name = attributes['name']
9
+ @number = attributes['number'].to_i
10
+ @value = attributes['value'].to_f
11
+ @active = (attributes['active'] == 'true')
12
+
13
+ @destination = Destination.new(attributes[Garb.to_ga('destination')])
14
+ end
15
+
16
+ def active?
17
+ @active
18
+ end
19
+ end
20
+ end
@@ -3,12 +3,13 @@ module Garb
3
3
 
4
4
  include ProfileReports
5
5
 
6
- attr_reader :session, :table_id, :title, :account_name, :account_id, :web_property_id
6
+ attr_reader :session, :table_id, :title, :account_name, :account_id, :web_property_id, :goals
7
7
 
8
8
  def initialize(entry, session)
9
9
  @session = session
10
10
  @title = entry['title']
11
11
  @table_id = entry['dxp:tableId']
12
+ @goals = (entry[Garb.to_ga('goal')] || []).map {|g| Goal.new(g)}
12
13
 
13
14
  entry['dxp:property'].each do |p|
14
15
  instance_variable_set :"@#{Garb.from_ga(p['name'])}", p['value']
@@ -20,18 +21,11 @@ module Garb
20
21
  end
21
22
 
22
23
  def self.all(session = Session)
23
- url = "https://www.google.com/analytics/feeds/accounts/default"
24
- response = DataRequest.new(session, url).send_request
25
- parse(response.body).map {|entry| new(entry, session)}
24
+ AccountFeedRequest.new(session).entries.map {|entry| new(entry, session)}
26
25
  end
27
26
 
28
27
  def self.first(id, session = Session)
29
28
  all(session).detect {|profile| profile.id == id || profile.web_property_id == id }
30
29
  end
31
-
32
- def self.parse(response_body)
33
- entry_hash = Crack::XML.parse(response_body)
34
- entry_hash ? [entry_hash['feed']['entry']].flatten : []
35
- end
36
30
  end
37
31
  end
@@ -2,8 +2,9 @@ module Garb
2
2
  class ReportResponse
3
3
  KEYS = ['dxp:metric', 'dxp:dimension']
4
4
 
5
- def initialize(response_body)
5
+ def initialize(response_body, instance_klass = OpenStruct)
6
6
  @xml = response_body
7
+ @instance_klass = instance_klass
7
8
  end
8
9
 
9
10
  def results
@@ -17,7 +18,7 @@ module Garb
17
18
  h.merge(Garb.from_ga(v['name']) => v['value'])
18
19
  end
19
20
 
20
- OpenStruct.new(hash)
21
+ @instance_klass.new(hash)
21
22
  end
22
23
  end
23
24
 
@@ -0,0 +1,13 @@
1
+ module Garb
2
+ class Step
3
+ attr_reader :name, :number, :path
4
+
5
+ def initialize(attributes)
6
+ return unless attributes.is_a?(Hash)
7
+
8
+ @name = attributes['name']
9
+ @number = attributes['number'].to_i
10
+ @path = attributes['path']
11
+ end
12
+ end
13
+ end
@@ -3,7 +3,7 @@ module Garb
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 7
6
- TINY = 5
6
+ TINY = 6
7
7
 
8
8
  def self.to_s # :nodoc:
9
9
  [MAJOR, MINOR, TINY].join('.')
@@ -1,19 +1,45 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <feed xmlns="http://www.w3.org/2005/Atom" xmlns:dxp="http://schemas.google.com/analytics/2009" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <feed xmlns='http://www.w3.org/2005/Atom' xmlns:dxp='http://schemas.google.com/analytics/2009' xmlns:ga='http://schemas.google.com/ga/2009' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;A0UASX45cCp7I2A9WxFQEUQ.&quot;' gd:kind='analytics#accounts'>
3
3
  <id>http://www.google.com/analytics/feeds/accounts/tpitale@gmail.com</id>
4
- <updated>2009-10-02T07:47:35.000-07:00</updated>
5
- <title type="text">Profile list for tpitale@gmail.com</title>
6
- <link rel="self" type="application/atom+xml" href="http://www.google.com/analytics/feeds/accounts/default"/>
4
+ <updated>2010-05-06T19:27:28.028-07:00</updated>
5
+ <title>Profile list for tpitale@gmail.com</title>
6
+ <link rel='self' type='application/atom+xml' href='https://www.google.com/analytics/feeds/accounts/default'/>
7
7
  <author><name>Google Analytics</name></author>
8
- <generator version="1.0">Google Analytics</generator>
8
+ <generator version='1.0'>Google Analytics</generator>
9
9
  <openSearch:totalResults>2</openSearch:totalResults>
10
10
  <openSearch:startIndex>1</openSearch:startIndex>
11
11
  <openSearch:itemsPerPage>2</openSearch:itemsPerPage>
12
- <entry>
12
+ <dxp:segment id='gaid::-1' name='All Visits'>
13
+ <dxp:definition> </dxp:definition>
14
+ </dxp:segment>
15
+ <dxp:segment id='gaid::-2' name='New Visitors'>
16
+ <dxp:definition>ga:visitorType==New Visitor</dxp:definition>
17
+ </dxp:segment>
18
+ <dxp:segment id='gaid::-3' name='Paid Search Traffic'>
19
+ <dxp:definition>ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==ppc</dxp:definition>
20
+ </dxp:segment>
21
+ <dxp:segment id='gaid::0' name='Not New York'>
22
+ <dxp:definition>ga:city!=New York</dxp:definition>
23
+ </dxp:segment>
24
+ <entry gd:etag='W/&quot;CUcHSXs8fip7I2A9WxBUFUg.&quot;' gd:kind='analytics#account'>
13
25
  <id>http://www.google.com/analytics/feeds/accounts/ga:12345</id>
14
26
  <updated>2008-07-21T14:05:57.000-07:00</updated>
15
- <title type="text">Historical</title>
16
- <link rel="alternate" type="text/html" href="http://www.google.com/analytics"/>
27
+ <title>Historical</title>
28
+ <link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
29
+ <ga:goal active='true' name='Read Blog' number='1' value='10.0'>
30
+ <ga:destination caseSensitive='false' expression='/blog.html' matchType='head' step1Required='false'/>
31
+ </ga:goal>
32
+ <ga:goal active='true' name='Go for Support' number='2' value='5.0'>
33
+ <ga:destination caseSensitive='false' expression='/support.html' matchType='head' step1Required='false'/>
34
+ </ga:goal>
35
+ <ga:goal active='true' name='Contact Form Submission' number='3' value='100.0'>
36
+ <ga:destination caseSensitive='false' expression='/contact-submit' matchType='exact' step1Required='true'>
37
+ <ga:step name='Contact Form Page' number='1' path='/contact.html'/>
38
+ </ga:destination>
39
+ </ga:goal>
40
+ <ga:goal active='true' name='Newsletter Form Submission' number='4' value='25.0'>
41
+ <ga:destination caseSensitive='false' expression='/newsletter-submit' matchType='exact' step1Required='false'/>
42
+ </ga:goal>
17
43
  <dxp:property name="ga:accountId" value="1111"/>
18
44
  <dxp:property name="ga:accountName" value="Blog Beta"/>
19
45
  <dxp:property name="ga:profileId" value="1212"/>
@@ -22,11 +48,19 @@
22
48
  <dxp:property name="ga:timezone" value="America/New_York"/>
23
49
  <dxp:tableId>ga:12345</dxp:tableId>
24
50
  </entry>
25
- <entry>
51
+ <entry gd:etag='W/&quot;A0UASX45cCp7I2A9WxFQEUQ.&quot;' gd:kind='analytics#account'>
26
52
  <id>http://www.google.com/analytics/feeds/accounts/ga:12346</id>
27
53
  <updated>2008-11-24T11:51:07.000-08:00</updated>
28
- <title type="text">Presently</title>
29
- <link rel="alternate" type="text/html" href="http://www.google.com/analytics"/>
54
+ <title>Presently</title>
55
+ <link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
56
+ <ga:goal active='true' name='Contact Form Submission' number='1' value='100.0'>
57
+ <ga:destination caseSensitive='false' expression='/contact-submit' matchType='exact' step1Required='true'>
58
+ <ga:step name='Contact Form Page' number='1' path='/contact.html'/>
59
+ </ga:destination>
60
+ </ga:goal>
61
+ <ga:goal active='true' name='Newsletter Form Submission' number='2' value='25.0'>
62
+ <ga:destination caseSensitive='false' expression='/newsletter-submit' matchType='exact' step1Required='false'/>
63
+ </ga:goal>
30
64
  <dxp:property name="ga:accountId" value="1111"/>
31
65
  <dxp:property name="ga:accountName" value="Blog Beta"/>
32
66
  <dxp:property name="ga:profileId" value="1213"/>
@@ -35,4 +69,4 @@
35
69
  <dxp:property name="ga:timezone" value="America/New_York"/>
36
70
  <dxp:tableId>ga:12346</dxp:tableId>
37
71
  </entry>
38
- </feed>
72
+ </feed>
@@ -5,9 +5,15 @@ require 'minitest/unit'
5
5
  require 'shoulda'
6
6
  require 'mocha'
7
7
 
8
- require File.dirname(__FILE__) + '/../lib/garb'
8
+ $:.unshift File.expand_path('../../lib', __FILE__)
9
+ require 'garb'
9
10
 
10
11
  class MiniTest::Unit::TestCase
12
+ include Shoulda::InstanceMethods
13
+ extend Shoulda::ClassMethods
14
+ include Shoulda::Assertions
15
+ extend Shoulda::Macros
16
+ include Shoulda::Helpers
11
17
 
12
18
  def read_fixture(filename)
13
19
  File.read(File.dirname(__FILE__) + "/fixtures/#{filename}")
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ module Garb
4
+ class AccountFeedRequestTest < MiniTest::Unit::TestCase
5
+ context "An AccountFeedRequest" do
6
+
7
+ end
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class AccountTest < MiniTest::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  CA_CERT_FILE = File.join(File.dirname(__FILE__), '..', '/cacert.pem')
4
4
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class DataRequestTest < MiniTest::Unit::TestCase
@@ -26,14 +26,12 @@ module Garb
26
26
  data_request = DataRequest.new(@session, "")
27
27
  assert_equal "", data_request.query_string
28
28
  end
29
-
29
+
30
30
  should "be able to build a uri" do
31
- url = 'http://example.com'
32
- expected = URI.parse('http://example.com')
33
-
34
- assert_equal expected, DataRequest.new(@session, url).uri
31
+ url = 'http://example.com'
32
+ assert_equal URI.parse(url), DataRequest.new(@session, url).uri
35
33
  end
36
-
34
+
37
35
  should "be able to send a request for a single user" do
38
36
  @session.stubs(:single_user?).returns(true)
39
37
  response = mock('Net::HTTPOK') do |m|
@@ -82,7 +80,7 @@ module Garb
82
80
  assert_equal 'responseobject', data_request.oauth_user_request
83
81
 
84
82
  assert_received(@session, :access_token)
85
- assert_received(access_token, :get) {|e| e.with('https://example.com/data?key=value')}
83
+ assert_received(access_token, :get) {|e| e.with('https://example.com/data?key=value', {'GData-Version' => '2'})}
86
84
  end
87
85
 
88
86
  should "be able to request via http with an auth token" do
@@ -92,7 +90,10 @@ module Garb
92
90
  http = mock do |m|
93
91
  m.expects(:use_ssl=).with(true)
94
92
  m.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
95
- m.expects(:get).with('/data?key=value', 'Authorization' => 'GoogleLogin auth=toke').returns(response)
93
+ m.expects(:get).with('/data?key=value', {
94
+ 'Authorization' => 'GoogleLogin auth=toke',
95
+ 'GData-Version' => '2'
96
+ }).returns(response)
96
97
  end
97
98
 
98
99
  Net::HTTP.expects(:new).with('example.com', 443).returns(http)
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ module Garb
4
+ class DestinationTest < MiniTest::Unit::TestCase
5
+ context 'A Destination' do
6
+ should "have a match_type and an expression" do
7
+ destination = Destination.new({'matchType' => 'exact', 'expression' => '/contact.html', 'caseSensitive' => 'false'})
8
+ assert_equal 'exact', destination.match_type
9
+ assert_equal '/contact.html', destination.expression
10
+ end
11
+
12
+ should "know if it's case sensitive" do
13
+ destination = Destination.new({'matchType' => 'exact', 'expression' => '/contact.html', 'caseSensitive' => 'true'})
14
+ assert_equal true, destination.case_sensitive?
15
+ end
16
+
17
+ should "know if it's not case sensitive" do
18
+ destination = Destination.new({'matchType' => 'exact', 'expression' => '/contact.html', 'caseSensitive' => 'false'})
19
+ assert_equal false, destination.case_sensitive?
20
+ end
21
+
22
+ should "have steps" do
23
+ destination = Destination.new({'ga:step' => {'name' => 'Contact', 'number' => '1', 'path' => '/'}})
24
+ assert_equal ['Contact'], destination.steps.map(&:name)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class FilterParametersTest < MiniTest::Unit::TestCase
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ module Garb
4
+ class GoalTest < MiniTest::Unit::TestCase
5
+ context "A Goal" do
6
+ should "have a name, number, and value" do
7
+ goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'true'})
8
+ assert_equal 'Read Blog', goal.name
9
+ assert_equal 1, goal.number
10
+ assert_equal 10.0, goal.value
11
+ end
12
+
13
+ should "know if it is active" do
14
+ goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'true'})
15
+ assert goal.active?
16
+ end
17
+
18
+ should "know if it is not active" do
19
+ goal = Goal.new({'name' => 'Read Blog', 'number' => '1', 'value' => '10.0', 'active' => 'false'})
20
+ assert_equal false, goal.active?
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class OAuthSessionTest < MiniTest::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class ProfileTest < MiniTest::Unit::TestCase
@@ -7,17 +7,12 @@ module Garb
7
7
  setup {@session = Session.new}
8
8
 
9
9
  should "be able to return a list of all profiles" do
10
- url = 'https://www.google.com/analytics/feeds/accounts/default'
11
-
12
- xml = read_fixture('profile_feed.xml')
13
-
14
- data_request = stub
15
- data_request.stubs(:send_request).returns(stub(:body => xml))
16
- DataRequest.stubs(:new).returns(data_request)
10
+ afr = AccountFeedRequest.new
11
+ afr.stubs(:parsed_response).returns(Crack::XML.parse(read_fixture('profile_feed.xml')))
12
+ AccountFeedRequest.stubs(:new).returns(afr)
17
13
 
18
14
  assert_equal ['12345', '12346'], Profile.all(@session).map(&:id)
19
- assert_received(DataRequest, :new) {|e| e.with(@session, url)}
20
- assert_received(data_request, :send_request)
15
+ assert_received(AccountFeedRequest, :new) {|e| e.with(@session)}
21
16
  end
22
17
 
23
18
  should "return the first profile for a given web property id" do
@@ -45,9 +40,12 @@ module Garb
45
40
  end
46
41
  end
47
42
 
48
- context "An instance of the Profile class" do
43
+ context "A Profile" do
49
44
  setup do
50
- entry = Profile.parse(read_fixture('profile_feed.xml')).first
45
+ afr = AccountFeedRequest.new
46
+ afr.stubs(:parsed_response).returns(Crack::XML.parse(read_fixture('profile_feed.xml')))
47
+
48
+ entry = afr.entries.first
51
49
  @profile = Profile.new(entry, Session)
52
50
  end
53
51
 
@@ -70,6 +68,10 @@ module Garb
70
68
  should "have a value for :account_name" do
71
69
  assert_equal 'Blog Beta', @profile.account_name
72
70
  end
71
+
72
+ should "have goals" do
73
+ assert_equal 4, @profile.goals.size
74
+ end
73
75
  end
74
76
  end
75
77
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class ReportParameterTest < MiniTest::Unit::TestCase
@@ -1,13 +1,29 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
+ SpecialKlass = Class.new(OpenStruct)
5
+
4
6
  class ReportResponseTest < MiniTest::Unit::TestCase
5
7
  context "A ReportResponse" do
6
- should "parse results from atom xml" do
7
- filename = File.join(File.dirname(__FILE__), '..', '..', "/fixtures/report_feed.xml")
8
- response = ReportResponse.new(File.read(filename))
9
-
10
- assert_equal ['33', '2', '1'], response.results.map(&:pageviews)
8
+ context "with a report feed" do
9
+ setup do
10
+ @file = File.read(File.join(File.dirname(__FILE__), '..', '..', "/fixtures/report_feed.xml"))
11
+ end
12
+
13
+ should "parse results from atom xml" do
14
+ response = ReportResponse.new(@file)
15
+ assert_equal ['33', '2', '1'], response.results.map(&:pageviews)
16
+ end
17
+
18
+ should "default to returning an array of OpenStruct objects" do
19
+ response = ReportResponse.new(@file)
20
+ assert_equal [OpenStruct, OpenStruct, OpenStruct], response.results.map(&:class)
21
+ end
22
+
23
+ should "return an array of instances of a specified class" do
24
+ response = ReportResponse.new(@file, SpecialKlass)
25
+ assert_equal [SpecialKlass, SpecialKlass, SpecialKlass], response.results.map(&:class)
26
+ end
11
27
  end
12
28
 
13
29
  should "return an empty array if there are no results" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  # Also tests Garb::Resource, which is the basis for Garb::Report
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  class TestReport
4
4
  extend Garb::Resource
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  module Garb
4
4
  class SessionTest < MiniTest::Unit::TestCase
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ module Garb
4
+ class StepTest < MiniTest::Unit::TestCase
5
+ context "A Step" do
6
+ should "have a name, number, and path" do
7
+ step = Step.new({'name' => 'Contact Form Page', 'number' => '1', 'path' => '/contact.html'})
8
+
9
+ assert_equal 'Contact Form Page', step.name
10
+ assert_equal 1, step.number
11
+ assert_equal '/contact.html', step.path
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  class GarbTest < MiniTest::Unit::TestCase
4
4
  context "The Garb module" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '/test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  class SymbolOperatorTest < MiniTest::Unit::TestCase
4
4
  context "An instance of a SymbolOperator" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 5
9
- version: 0.7.5
8
+ - 6
9
+ version: 0.7.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tony Pitale
@@ -14,13 +14,14 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-15 00:00:00 -07:00
17
+ date: 2010-07-06 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: crack
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
24
25
  requirements:
25
26
  - - ">="
26
27
  - !ruby/object:Gem::Version
@@ -35,6 +36,7 @@ dependencies:
35
36
  name: activesupport
36
37
  prerelease: false
37
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
38
40
  requirements:
39
41
  - - ">="
40
42
  - !ruby/object:Gem::Version
@@ -57,9 +59,12 @@ files:
57
59
  - README.md
58
60
  - Rakefile
59
61
  - lib/garb/account.rb
62
+ - lib/garb/account_feed_request.rb
60
63
  - lib/garb/authentication_request.rb
61
64
  - lib/garb/data_request.rb
65
+ - lib/garb/destination.rb
62
66
  - lib/garb/filter_parameters.rb
67
+ - lib/garb/goal.rb
63
68
  - lib/garb/profile.rb
64
69
  - lib/garb/profile_reports.rb
65
70
  - lib/garb/report.rb
@@ -73,6 +78,7 @@ files:
73
78
  - lib/garb/reports.rb
74
79
  - lib/garb/resource.rb
75
80
  - lib/garb/session.rb
81
+ - lib/garb/step.rb
76
82
  - lib/garb/version.rb
77
83
  - lib/garb.rb
78
84
  - lib/support.rb
@@ -80,10 +86,13 @@ files:
80
86
  - test/fixtures/profile_feed.xml
81
87
  - test/fixtures/report_feed.xml
82
88
  - test/test_helper.rb
89
+ - test/unit/garb/account_feed_request_test.rb
83
90
  - test/unit/garb/account_test.rb
84
91
  - test/unit/garb/authentication_request_test.rb
85
92
  - test/unit/garb/data_request_test.rb
93
+ - test/unit/garb/destination_test.rb
86
94
  - test/unit/garb/filter_parameters_test.rb
95
+ - test/unit/garb/goal_test.rb
87
96
  - test/unit/garb/oauth_session_test.rb
88
97
  - test/unit/garb/profile_reports_test.rb
89
98
  - test/unit/garb/profile_test.rb
@@ -92,9 +101,10 @@ files:
92
101
  - test/unit/garb/report_test.rb
93
102
  - test/unit/garb/resource_test.rb
94
103
  - test/unit/garb/session_test.rb
104
+ - test/unit/garb/step_test.rb
95
105
  - test/unit/garb_test.rb
96
106
  - test/unit/symbol_operator_test.rb
97
- has_rdoc: false
107
+ has_rdoc: true
98
108
  homepage: http://github.com/vigetlabs/garb
99
109
  licenses: []
100
110
 
@@ -104,6 +114,7 @@ rdoc_options: []
104
114
  require_paths:
105
115
  - lib
106
116
  required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
107
118
  requirements:
108
119
  - - ">="
109
120
  - !ruby/object:Gem::Version
@@ -111,6 +122,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
122
  - 0
112
123
  version: "0"
113
124
  required_rubygems_version: !ruby/object:Gem::Requirement
125
+ none: false
114
126
  requirements:
115
127
  - - ">="
116
128
  - !ruby/object:Gem::Version
@@ -120,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
132
  requirements: []
121
133
 
122
134
  rubyforge_project: viget
123
- rubygems_version: 1.3.6
135
+ rubygems_version: 1.3.7
124
136
  signing_key:
125
137
  specification_version: 3
126
138
  summary: Google Analytics API Ruby Wrapper
@@ -129,10 +141,13 @@ test_files:
129
141
  - test/fixtures/profile_feed.xml
130
142
  - test/fixtures/report_feed.xml
131
143
  - test/test_helper.rb
144
+ - test/unit/garb/account_feed_request_test.rb
132
145
  - test/unit/garb/account_test.rb
133
146
  - test/unit/garb/authentication_request_test.rb
134
147
  - test/unit/garb/data_request_test.rb
148
+ - test/unit/garb/destination_test.rb
135
149
  - test/unit/garb/filter_parameters_test.rb
150
+ - test/unit/garb/goal_test.rb
136
151
  - test/unit/garb/oauth_session_test.rb
137
152
  - test/unit/garb/profile_reports_test.rb
138
153
  - test/unit/garb/profile_test.rb
@@ -141,5 +156,6 @@ test_files:
141
156
  - test/unit/garb/report_test.rb
142
157
  - test/unit/garb/resource_test.rb
143
158
  - test/unit/garb/session_test.rb
159
+ - test/unit/garb/step_test.rb
144
160
  - test/unit/garb_test.rb
145
161
  - test/unit/symbol_operator_test.rb