analytics-ruby 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- analytics-ruby (0.3.2)
4
+ analytics-ruby (0.3.3)
5
5
  faraday (>= 0.8, < 0.10)
6
6
  faraday_middleware (>= 0.8, < 0.10)
7
7
  multi_json (~> 1.0)
data/History.md CHANGED
@@ -1,3 +1,7 @@
1
+ 0.3.4 / 2013-8-26
2
+ ===========
3
+ * Pass `Time` values as iso8601 timestamp strings
4
+
1
5
  0.3.3 / 2013-8-2
2
6
  ===========
3
7
  * Allow init/track/identify/alias to accept strings as keys. by [@shipstar](https://github.com/shipstar)
@@ -0,0 +1,5 @@
1
+
2
+ test:
3
+ rake spec
4
+
5
+ .PHONY: test
@@ -5,22 +5,22 @@ module AnalyticsRuby
5
5
  module ClassMethods
6
6
  # By default use a single client for the module
7
7
  def init(options = {})
8
- @client = AnalyticsRuby::Client.new(options)
8
+ @client = AnalyticsRuby::Client.new options
9
9
  end
10
10
 
11
11
  def track(options)
12
12
  return false unless @client
13
- @client.track(options)
13
+ @client.track options
14
14
  end
15
15
 
16
16
  def identify(options)
17
17
  return false unless @client
18
- @client.identify(options)
18
+ @client.identify options
19
19
  end
20
20
 
21
21
  def alias(options)
22
22
  return false unless @client
23
- @client.alias(options)
23
+ @client.alias options
24
24
  end
25
25
 
26
26
  def flush
@@ -18,7 +18,7 @@ module AnalyticsRuby
18
18
  # :on_error - Proc which handles error calls from the API
19
19
  def initialize(options = {})
20
20
 
21
- Util.symbolize_keys!(options)
21
+ Util.symbolize_keys! options
22
22
 
23
23
  @queue = Queue.new
24
24
  @secret = options[:secret]
@@ -26,7 +26,7 @@ module AnalyticsRuby
26
26
 
27
27
  check_secret
28
28
 
29
- @consumer = AnalyticsRuby::Consumer.new(@queue, @secret, options)
29
+ @consumer = AnalyticsRuby::Consumer.new @queue, @secret, options
30
30
  @thread = Thread.new { @consumer.run }
31
31
  end
32
32
 
@@ -52,7 +52,7 @@ module AnalyticsRuby
52
52
 
53
53
  check_secret
54
54
 
55
- Util.symbolize_keys!(options)
55
+ Util.symbolize_keys! options
56
56
 
57
57
  event = options[:event]
58
58
  user_id = options[:user_id].to_s
@@ -60,23 +60,26 @@ module AnalyticsRuby
60
60
  timestamp = options[:timestamp] || Time.new
61
61
  context = options[:context] || {}
62
62
 
63
- ensure_user(user_id)
64
- check_timestamp(timestamp)
63
+ ensure_user user_id
64
+ check_timestamp timestamp
65
65
 
66
66
  if event.nil? || event.empty?
67
67
  fail ArgumentError, 'Must supply event as a non-empty string'
68
68
  end
69
69
 
70
70
  fail ArgumentError, 'Properties must be a Hash' unless properties.is_a? Hash
71
-
72
- add_context(context)
73
-
74
- enqueue({ event: event,
75
- userId: user_id,
76
- context: context,
77
- properties: properties,
78
- timestamp: timestamp.iso8601,
79
- action: 'track' })
71
+ Util.isoify_dates! properties
72
+
73
+ add_context context
74
+
75
+ enqueue({
76
+ :event => event,
77
+ :userId => user_id,
78
+ :context => context,
79
+ :properties => properties,
80
+ :timestamp => timestamp.iso8601,
81
+ :action => 'track'
82
+ })
80
83
  end
81
84
 
82
85
  # public: Identifies a user
@@ -90,25 +93,28 @@ module AnalyticsRuby
90
93
 
91
94
  check_secret
92
95
 
93
- Util.symbolize_keys!(options)
96
+ Util.symbolize_keys! options
94
97
 
95
98
  user_id = options[:user_id].to_s
96
99
  traits = options[:traits] || {}
97
100
  timestamp = options[:timestamp] || Time.new
98
101
  context = options[:context] || {}
99
102
 
100
- ensure_user(user_id)
101
- check_timestamp(timestamp)
103
+ ensure_user user_id
104
+ check_timestamp timestamp
102
105
 
103
106
  fail ArgumentError, 'Must supply traits as a hash' unless traits.is_a? Hash
107
+ Util.isoify_dates! traits
104
108
 
105
- add_context(context)
109
+ add_context context
106
110
 
107
- enqueue({ userId: user_id,
108
- context: context,
109
- traits: traits,
110
- timestamp: timestamp.iso8601,
111
- action: 'identify' })
111
+ enqueue({
112
+ :userId => user_id,
113
+ :context => context,
114
+ :traits => traits,
115
+ :timestamp => timestamp.iso8601,
116
+ :action => 'identify'
117
+ })
112
118
  end
113
119
 
114
120
  # public: Aliases a user from one id to another
@@ -122,24 +128,26 @@ module AnalyticsRuby
122
128
 
123
129
  check_secret
124
130
 
125
- Util.symbolize_keys!(options)
131
+ Util.symbolize_keys! options
126
132
 
127
133
  from = options[:from].to_s
128
134
  to = options[:to].to_s
129
135
  timestamp = options[:timestamp] || Time.new
130
136
  context = options[:context] || {}
131
137
 
132
- ensure_user(from)
133
- ensure_user(to)
134
- check_timestamp(timestamp)
138
+ ensure_user from
139
+ ensure_user to
140
+ check_timestamp timestamp
135
141
 
136
- add_context(context)
142
+ add_context context
137
143
 
138
- enqueue({ from: from,
139
- to: to,
140
- context: context,
141
- timestamp: timestamp.iso8601,
142
- action: 'alias' })
144
+ enqueue({
145
+ :from => from,
146
+ :to => to,
147
+ :context => context,
148
+ :timestamp => timestamp.iso8601,
149
+ :action => 'alias'
150
+ })
143
151
  end
144
152
 
145
153
  # public: Returns the number of queued messages
@@ -19,7 +19,7 @@ module AnalyticsRuby
19
19
  # on_error - Proc of what to do on an error
20
20
  #
21
21
  def initialize(queue, secret, options = {})
22
- Util.symbolize_keys!(options)
22
+ Util.symbolize_keys! options
23
23
 
24
24
  @queue = queue
25
25
  @secret = secret
@@ -43,19 +43,19 @@ module AnalyticsRuby
43
43
  #
44
44
  def flush
45
45
  # Block until we have something to send
46
- item = @queue.pop()
46
+ item = @queue.pop
47
47
 
48
48
  # Synchronize on additions to the current batch
49
49
  @mutex.synchronize {
50
50
  @current_batch << item
51
51
  until @current_batch.length >= @batch_size || @queue.empty?
52
- @current_batch << @queue.pop()
52
+ @current_batch << @queue.pop
53
53
  end
54
54
  }
55
55
 
56
56
  req = AnalyticsRuby::Request.new
57
- res = req.post(@secret, @current_batch)
58
- @on_error.call(res.status, res.error) unless res.status == 200
57
+ res = req.post @secret, @current_batch
58
+ @on_error.call res.status, res.error unless res.status == 200
59
59
  @mutex.synchronize {
60
60
  @current_batch = []
61
61
  }
@@ -5,8 +5,8 @@ module AnalyticsRuby
5
5
  module Request
6
6
  BASE_URL = 'https://api.segment.io' unless defined? AnalyticsRuby::Defaults::Request::BASE_URL
7
7
  PATH = '/v1/import' unless defined? AnalyticsRuby::Defaults::Request::PATH
8
- SSL = { verify: false } unless defined? AnalyticsRuby::Defaults::Request::SSL
9
- HEADERS = { accept: 'application/json' } unless defined? AnalyticsRuby::Defaults::Request::HEADERS
8
+ SSL = { :verify => false } unless defined? AnalyticsRuby::Defaults::Request::SSL
9
+ HEADERS = { :accept => 'application/json' } unless defined? AnalyticsRuby::Defaults::Request::HEADERS
10
10
  end
11
11
 
12
12
  module Queue
@@ -7,7 +7,7 @@ module AnalyticsRuby
7
7
  #
8
8
  # .dump was added in MultiJson 1.3
9
9
  module JSON
10
- if MultiJson.respond_to?(:dump)
10
+ if MultiJson.respond_to? :dump
11
11
  def self.dump(*args)
12
12
  MultiJson.dump(*args)
13
13
  end
@@ -18,7 +18,7 @@ module AnalyticsRuby
18
18
  options[:headers] ||= AnalyticsRuby::Defaults::Request::HEADERS
19
19
  @path = options[:path] || AnalyticsRuby::Defaults::Request::PATH
20
20
 
21
- @conn = Faraday.new(options) do |faraday|
21
+ @conn = Faraday.new options do |faraday|
22
22
  faraday.request :json
23
23
  faraday.response :json, :content_type => /\bjson$/
24
24
  faraday.adapter Faraday.default_adapter
@@ -37,7 +37,7 @@ module AnalyticsRuby
37
37
  req.options[:timeout] = 8
38
38
  req.options[:open_timeout] = 3
39
39
  req.url(@path)
40
- req.body = AnalyticsRuby::JSON::dump(secret: secret, batch: batch)
40
+ req.body = AnalyticsRuby::JSON::dump :secret => secret, :batch => batch
41
41
  end
42
42
  status = res.status
43
43
  error = res.body["error"]
@@ -47,7 +47,7 @@ module AnalyticsRuby
47
47
  error = "Connection error: #{err}"
48
48
  end
49
49
 
50
- AnalyticsRuby::Response.new(status, error)
50
+ AnalyticsRuby::Response.new status, error
51
51
  end
52
52
  end
53
53
  end
@@ -4,10 +4,21 @@ module Util
4
4
  end
5
5
 
6
6
  def self.symbolize_keys!(hash)
7
- hash.replace symbolize_keys(hash)
7
+ hash.replace symbolize_keys hash
8
8
  end
9
9
 
10
10
  def self.stringify_keys(hash)
11
11
  hash.inject({}) { |memo, (k,v)| memo[k.to_s] = v; memo }
12
12
  end
13
+
14
+ def self.isoify_dates(hash)
15
+ hash.inject({}) { |memo, (k, v)|
16
+ memo[k] = v.respond_to?(:iso8601) ? v.iso8601 : v
17
+ memo
18
+ }
19
+ end
20
+
21
+ def self.isoify_dates!(hash)
22
+ hash.replace isoify_dates hash
23
+ end
13
24
  end
@@ -1,3 +1,3 @@
1
1
  module AnalyticsRuby
2
- VERSION = '0.3.3'
2
+ VERSION = '0.3.4'
3
3
  end
@@ -11,7 +11,7 @@ describe Analytics::Client do
11
11
  end
12
12
 
13
13
  it 'should not error if a secret is supplied' do
14
- Analytics::Client.new secret: AnalyticsHelpers::SECRET
14
+ Analytics::Client.new :secret => AnalyticsHelpers::SECRET
15
15
  end
16
16
 
17
17
  it 'should not error if a secret is supplied as a string' do
@@ -22,29 +22,51 @@ describe Analytics::Client do
22
22
  describe '#track' do
23
23
 
24
24
  before(:all) do
25
- @client = Analytics::Client.new secret: AnalyticsHelpers::SECRET
25
+ @client = Analytics::Client.new :secret => AnalyticsHelpers::SECRET
26
+ @client.instance_variable_get(:@thread).kill
27
+ @queue = @client.instance_variable_get :@queue
26
28
  end
27
29
 
28
30
  it 'should error without an event' do
29
- expect { @client.track(user_id: 'user') }.to raise_error(ArgumentError)
31
+ expect { @client.track(:user_id => 'user') }.to raise_error(ArgumentError)
30
32
  end
31
33
 
32
34
  it 'should error without a user_id' do
33
- expect { @client.track(event: 'Event') }.to raise_error(ArgumentError)
35
+ expect { @client.track(:event => 'Event') }.to raise_error(ArgumentError)
34
36
  end
35
37
 
36
38
  it 'should error if properties is not a hash' do
37
39
  expect {
38
- @client.track(user_id: 'user', event: 'Event', properties: [1,2,3])
40
+ @client.track({
41
+ :user_id => 'user',
42
+ :event => 'Event',
43
+ :properties => [1,2,3]
44
+ })
39
45
  }.to raise_error(ArgumentError)
40
46
  end
41
47
 
42
48
  it 'should not error with the required options' do
43
49
  @client.track AnalyticsHelpers::Queued::TRACK
50
+ @queue.pop
44
51
  end
45
52
 
46
53
  it 'should not error when given string keys' do
47
54
  @client.track Util.stringify_keys(AnalyticsHelpers::Queued::TRACK)
55
+ @queue.pop
56
+ end
57
+
58
+ it 'should convert Time properties into iso8601 format' do
59
+ @client.track({
60
+ :user_id => 'user',
61
+ :event => 'Event',
62
+ :properties => {
63
+ :time => Time.utc(2013),
64
+ :nottime => 'x'
65
+ }
66
+ })
67
+ message = @queue.pop
68
+ message[:properties][:time].should == '2013-01-01T00:00:00Z'
69
+ message[:properties][:nottime].should == 'x'
48
70
  end
49
71
  end
50
72
 
@@ -52,7 +74,9 @@ describe Analytics::Client do
52
74
  describe '#identify' do
53
75
 
54
76
  before(:all) do
55
- @client = Analytics::Client.new secret: AnalyticsHelpers::SECRET
77
+ @client = Analytics::Client.new :secret => AnalyticsHelpers::SECRET
78
+ @client.instance_variable_get(:@thread).kill
79
+ @queue = @client.instance_variable_get :@queue
56
80
  end
57
81
 
58
82
  it 'should error without any user id' do
@@ -61,24 +85,39 @@ describe Analytics::Client do
61
85
 
62
86
  it 'should not error with the required options' do
63
87
  @client.identify AnalyticsHelpers::Queued::IDENTIFY
88
+ @queue.pop
64
89
  end
65
90
 
66
91
  it 'should not error with the required options as strings' do
67
92
  @client.identify Util.stringify_keys(AnalyticsHelpers::Queued::IDENTIFY)
93
+ @queue.pop
94
+ end
95
+
96
+ it 'should convert Time traits into iso8601 format' do
97
+ @client.identify({
98
+ :user_id => 'user',
99
+ :traits => {
100
+ :time => Time.utc(2013),
101
+ :nottime => 'x'
102
+ }
103
+ })
104
+ message = @queue.pop
105
+ message[:traits][:time].should == '2013-01-01T00:00:00Z'
106
+ message[:traits][:nottime].should == 'x'
68
107
  end
69
108
  end
70
109
 
71
110
  describe '#alias' do
72
111
  before :all do
73
- @client = Analytics::Client.new secret: AnalyticsHelpers::SECRET
112
+ @client = Analytics::Client.new :secret => AnalyticsHelpers::SECRET
74
113
  end
75
114
 
76
115
  it 'should error without from' do
77
- expect { @client.alias to: 1234 }.to raise_error(ArgumentError)
116
+ expect { @client.alias :to => 1234 }.to raise_error(ArgumentError)
78
117
  end
79
118
 
80
119
  it 'should error without to' do
81
- expect { @client.alias from: 1234 }.to raise_error(ArgumentError)
120
+ expect { @client.alias :from => 1234 }.to raise_error(ArgumentError)
82
121
  end
83
122
 
84
123
  it 'should not error with the required options' do
@@ -92,7 +131,7 @@ describe Analytics::Client do
92
131
 
93
132
  describe '#flush' do
94
133
  before(:all) do
95
- @client = Analytics::Client.new secret: AnalyticsHelpers::SECRET
134
+ @client = Analytics::Client.new :secret => AnalyticsHelpers::SECRET
96
135
  end
97
136
 
98
137
  it 'should wait for the queue to finish on a flush' do
@@ -30,9 +30,8 @@ describe Analytics::Consumer do
30
30
 
31
31
  it 'should execute the error handler if the request is invalid' do
32
32
 
33
- Analytics::Request.any_instance
34
- .stub(:post)
35
- .and_return(Analytics::Response.new(400, "Some error"))
33
+ Analytics::Request.any_instance.stub(:post).and_return(
34
+ Analytics::Response.new(400, "Some error"))
36
35
 
37
36
  on_error = Proc.new do |status, error|
38
37
  puts "#{status}, #{error}"
@@ -42,7 +41,7 @@ describe Analytics::Consumer do
42
41
 
43
42
  queue = Queue.new
44
43
  queue << {}
45
- consumer = Analytics::Consumer.new(queue, 'secret', { on_error: on_error })
44
+ consumer = Analytics::Consumer.new queue, 'secret', :on_error => on_error
46
45
  consumer.flush
47
46
 
48
47
  Analytics::Request::any_instance.unstub(:post)
@@ -60,7 +59,7 @@ describe Analytics::Consumer do
60
59
 
61
60
  queue = Queue.new
62
61
  queue << AnalyticsHelpers::Requested::TRACK
63
- consumer = Analytics::Consumer.new(queue, 'testsecret', { on_error: on_error })
62
+ consumer = Analytics::Consumer.new queue, 'testsecret', :on_error => on_error
64
63
  consumer.flush
65
64
 
66
65
  queue.should be_empty
@@ -24,18 +24,18 @@ describe Analytics do
24
24
  describe '#init' do
25
25
 
26
26
  it 'should successfully init' do
27
- Analytics.init secret: AnalyticsHelpers::SECRET
27
+ Analytics.init :secret => AnalyticsHelpers::SECRET
28
28
  end
29
29
  end
30
30
 
31
31
  describe '#track' do
32
32
 
33
33
  it 'should error without an event' do
34
- expect { Analytics.track user_id: 'user' }.to raise_error(ArgumentError)
34
+ expect { Analytics.track :user_id => 'user' }.to raise_error(ArgumentError)
35
35
  end
36
36
 
37
37
  it 'should error without a user_id' do
38
- expect { Analytics.track event: 'Event' }.to raise_error(ArgumentError)
38
+ expect { Analytics.track :event => 'Event' }.to raise_error(ArgumentError)
39
39
  end
40
40
 
41
41
  it 'should not error with the required options' do
@@ -47,7 +47,7 @@ describe Analytics do
47
47
 
48
48
  describe '#identify' do
49
49
  it 'should error without a user_id' do
50
- expect { Analytics.identify traits: {} }.to raise_error(ArgumentError)
50
+ expect { Analytics.identify :traits => {} }.to raise_error(ArgumentError)
51
51
  end
52
52
 
53
53
  it 'should not error with the required options' do
@@ -58,11 +58,11 @@ describe Analytics do
58
58
 
59
59
  describe '#alias' do
60
60
  it 'should error without from' do
61
- expect { Analytics.alias to: 1234 }.to raise_error(ArgumentError)
61
+ expect { Analytics.alias :to => 1234 }.to raise_error(ArgumentError)
62
62
  end
63
63
 
64
64
  it 'should error without to' do
65
- expect { Analytics.alias from: 1234 }.to raise_error(ArgumentError)
65
+ expect { Analytics.alias :from => 1234 }.to raise_error(ArgumentError)
66
66
  end
67
67
 
68
68
  it 'should not error with the required options' do
@@ -3,41 +3,48 @@ module AnalyticsHelpers
3
3
 
4
4
  SECRET = 'testsecret'
5
5
 
6
- TRACK = { event: 'Ruby Library test event',
7
- properties: {
8
- type: 'Chocolate',
9
- is_a_lie: true,
10
- layers: 20,
11
- created: Time.new
12
- }
13
- }
14
-
15
- IDENTIFY = { traits: {
16
- likes_animals: true,
17
- instrument: 'Guitar',
18
- age: 25
19
- },
20
- action: 'identify'
21
- }
22
-
23
- ALIAS = { from: 1234,
24
- to: 'abcd' }
6
+ TRACK = {
7
+ :event => 'Ruby Library test event',
8
+ :properties => {
9
+ :type => 'Chocolate',
10
+ :is_a_lie => true,
11
+ :layers => 20,
12
+ :created => Time.new
13
+ }
14
+ }
15
+
16
+ IDENTIFY = {
17
+ :traits => {
18
+ :likes_animals => true,
19
+ :instrument => 'Guitar',
20
+ :age => 25
21
+ },
22
+ :action => 'identify'
23
+ }
24
+
25
+ ALIAS = {
26
+ :from => 1234,
27
+ :to => 'abcd'
28
+ }
25
29
 
26
30
  USER_ID = 1234
27
31
 
28
32
  # Hashes sent to the client
29
33
  module Queued
30
- TRACK = TRACK.merge({ user_id: USER_ID })
31
-
32
- IDENTIFY = IDENTIFY.merge({ user_id: USER_ID })
34
+ TRACK = TRACK.merge :user_id => USER_ID
35
+ IDENTIFY = IDENTIFY.merge :user_id => USER_ID
33
36
  end
34
37
 
35
38
  # Hashes which are sent from the consumer
36
39
  module Requested
37
- TRACK = TRACK.merge({ userId: USER_ID,
38
- action: 'track' })
39
-
40
- IDENTIFY = IDENTIFY.merge({ userId: USER_ID,
41
- action: 'identify' })
40
+ TRACK = TRACK.merge({
41
+ :userId => USER_ID,
42
+ :action => 'track'
43
+ })
44
+
45
+ IDENTIFY = IDENTIFY.merge({
46
+ :userId => USER_ID,
47
+ :action => 'identify'
48
+ })
42
49
  end
43
50
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: analytics-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-03 00:00:00.000000000 Z
12
+ date: 2013-08-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -122,6 +122,7 @@ files:
122
122
  - lib/analytics-ruby/util.rb
123
123
  - lib/analytics-ruby/version.rb
124
124
  - lib/analytics-ruby.rb
125
+ - Makefile
125
126
  - Rakefile
126
127
  - README.md
127
128
  - spec/client_spec.rb