analytics-ruby 2.2.6.pre → 2.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +0,0 @@
1
- Releasing
2
- =========
3
-
4
- 1. Verify everything works with `make check build`.
5
- 2. Bump version in [`version.rb`](https://github.com/segmentio/analytics-ruby/blob/master/lib/segment/analytics/version.rb).
6
- 3. Update [`History.md`](https://github.com/segmentio/analytics-ruby/blob/master/History.md).
7
- 4. Commit and tag `git commit -am "Release {version}" && git tag -a {version} -m "Version {version}"`.
8
- 5. Upload to Github with `git push -u origin master && git push --tags`.
9
- The tagged commit will be pushed to RubyGems via Travis.
data/Rakefile DELETED
@@ -1,33 +0,0 @@
1
- require 'rspec/core/rake_task'
2
-
3
- default_tasks = []
4
-
5
- RSpec::Core::RakeTask.new(:spec) do |spec|
6
- spec.pattern = 'spec/segment/**/*_spec.rb'
7
- spec.rspec_opts = "--tag ~e2e" if ENV["RUN_E2E_TESTS"] != "true"
8
- end
9
-
10
- default_tasks << :spec
11
-
12
- # Isolated tests are run as separate rake tasks so that gem conflicts can be
13
- # tests in different processes
14
- Dir.glob('spec/isolated/**/*.rb').each do |isolated_test_path|
15
- RSpec::Core::RakeTask.new(isolated_test_path) do |spec|
16
- spec.pattern = isolated_test_path
17
- end
18
-
19
- default_tasks << isolated_test_path
20
- end
21
-
22
- # Rubocop doesn't support < 2.1
23
- if RUBY_VERSION >= "2.1"
24
- require 'rubocop/rake_task'
25
-
26
- RuboCop::RakeTask.new(:rubocop) do |task|
27
- task.patterns = ['lib/**/*.rb','spec/**/*.rb',]
28
- end
29
-
30
- default_tasks << :rubocop
31
- end
32
-
33
- task :default => default_tasks
@@ -1,37 +0,0 @@
1
- require File.expand_path('../lib/segment/analytics/version', __FILE__)
2
-
3
- Gem::Specification.new do |spec|
4
- spec.name = 'analytics-ruby'
5
- spec.version = Segment::Analytics::VERSION
6
- spec.files = Dir.glob('**/*')
7
- spec.require_paths = ['lib']
8
- spec.bindir = 'bin'
9
- spec.executables = ['analytics']
10
- spec.summary = 'Segment.io analytics library'
11
- spec.description = 'The Segment.io ruby analytics library'
12
- spec.authors = ['Segment.io']
13
- spec.email = 'friends@segment.io'
14
- spec.homepage = 'https://github.com/segmentio/analytics-ruby'
15
- spec.license = 'MIT'
16
-
17
- # Ruby 1.8 requires json
18
- spec.add_dependency 'json', ['~> 1.7'] if RUBY_VERSION < "1.9"
19
- spec.add_dependency 'commander', '~> 4.4'
20
-
21
- spec.add_development_dependency 'rake', '~> 10.3'
22
- spec.add_development_dependency 'rspec', '~> 3.0'
23
- spec.add_development_dependency 'tzinfo', '1.2.1'
24
- spec.add_development_dependency 'activesupport', '~> 4.1.11'
25
- spec.add_development_dependency 'faraday', '~> 0.13'
26
- spec.add_development_dependency 'pmap', '~> 1.1'
27
-
28
- if RUBY_VERSION >= '2.0' && RUBY_PLATFORM != 'java'
29
- spec.add_development_dependency 'oj', '~> 3.6.2'
30
- end
31
-
32
- if RUBY_VERSION >= "2.1"
33
- spec.add_development_dependency 'rubocop', '~> 0.51.0'
34
- end
35
-
36
- spec.add_development_dependency 'codecov', '~> 0.1.4'
37
- end
@@ -1,2 +0,0 @@
1
- ignore:
2
- - "spec/**/*"
@@ -1,38 +0,0 @@
1
- require 'faraday'
2
- require 'pmap'
3
-
4
- class RunscopeClient
5
- def initialize(api_token)
6
- headers = { 'Authorization' => "Bearer #{api_token}" }
7
- @conn = Faraday.new('https://api.runscope.com', headers: headers)
8
- end
9
-
10
- def requests(bucket_key)
11
- with_retries(3) do
12
- response = @conn.get("/buckets/#{bucket_key}/messages", count: 20)
13
-
14
- raise "Runscope error. #{response.body}" unless response.status == 200
15
-
16
- message_uuids = JSON.parse(response.body)['data'].map { |message|
17
- message.fetch('uuid')
18
- }
19
-
20
- message_uuids.pmap { |uuid|
21
- response = @conn.get("/buckets/#{bucket_key}/messages/#{uuid}")
22
- raise "Runscope error. #{response.body}" unless response.status == 200
23
- JSON.parse(response.body).fetch('data').fetch('request')
24
- }
25
- end
26
- end
27
-
28
- private
29
-
30
- def with_retries(max_retries)
31
- retries ||= 0
32
- yield
33
- rescue StandardError => e
34
- retries += 1
35
- retry if retries < max_retries
36
- raise e
37
- end
38
- end
@@ -1,9 +0,0 @@
1
- RSpec.shared_examples 'message_batch_json' do
2
- it 'MessageBatch generates proper JSON' do
3
- batch = Segment::Analytics::MessageBatch.new(100)
4
- batch << { 'a' => 'b' }
5
- batch << { 'c' => 'd' }
6
-
7
- expect(JSON.generate(batch)).to eq('[{"a":"b"},{"c":"d"}]')
8
- end
9
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
- require 'isolated/json_example'
3
-
4
- describe 'with active_support' do
5
- before do
6
- require 'active_support'
7
- require 'active_support/json'
8
- end
9
-
10
- include_examples 'message_batch_json'
11
- end
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
- require 'isolated/json_example'
3
-
4
- if RUBY_VERSION >= '2.0' && RUBY_PLATFORM != 'java'
5
- describe 'with active_support and oj' do
6
- before do
7
- require 'active_support'
8
- require 'active_support/json'
9
-
10
- require 'oj'
11
- Oj.mimic_JSON
12
- end
13
-
14
- include_examples 'message_batch_json'
15
- end
16
- end
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
- require 'isolated/json_example'
3
-
4
- if RUBY_VERSION >= '2.0' && RUBY_PLATFORM != 'java'
5
- describe 'with oj' do
6
- before do
7
- require 'oj'
8
- Oj.mimic_JSON
9
- end
10
-
11
- include_examples 'message_batch_json'
12
- end
13
- end
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Segment
4
- class Analytics
5
- describe BackoffPolicy do
6
- describe '#initialize' do
7
- context 'no options are given' do
8
- it 'sets default min_timeout_ms' do
9
- actual = subject.instance_variable_get(:@min_timeout_ms)
10
- expect(actual).to eq(described_class::MIN_TIMEOUT_MS)
11
- end
12
-
13
- it 'sets default max_timeout_ms' do
14
- actual = subject.instance_variable_get(:@max_timeout_ms)
15
- expect(actual).to eq(described_class::MAX_TIMEOUT_MS)
16
- end
17
-
18
- it 'sets default multiplier' do
19
- actual = subject.instance_variable_get(:@multiplier)
20
- expect(actual).to eq(described_class::MULTIPLIER)
21
- end
22
-
23
- it 'sets default randomization factor' do
24
- actual = subject.instance_variable_get(:@randomization_factor)
25
- expect(actual).to eq(described_class::RANDOMIZATION_FACTOR)
26
- end
27
- end
28
-
29
- context 'options are given' do
30
- let(:min_timeout_ms) { 1234 }
31
- let(:max_timeout_ms) { 5678 }
32
- let(:multiplier) { 24 }
33
- let(:randomization_factor) { 0.4 }
34
-
35
- let(:options) do
36
- {
37
- min_timeout_ms: min_timeout_ms,
38
- max_timeout_ms: max_timeout_ms,
39
- multiplier: multiplier,
40
- randomization_factor: randomization_factor
41
- }
42
- end
43
-
44
- subject { described_class.new(options) }
45
-
46
- it 'sets passed in min_timeout_ms' do
47
- actual = subject.instance_variable_get(:@min_timeout_ms)
48
- expect(actual).to eq(min_timeout_ms)
49
- end
50
-
51
- it 'sets passed in max_timeout_ms' do
52
- actual = subject.instance_variable_get(:@max_timeout_ms)
53
- expect(actual).to eq(max_timeout_ms)
54
- end
55
-
56
- it 'sets passed in multiplier' do
57
- actual = subject.instance_variable_get(:@multiplier)
58
- expect(actual).to eq(multiplier)
59
- end
60
-
61
- it 'sets passed in randomization_factor' do
62
- actual = subject.instance_variable_get(:@randomization_factor)
63
- expect(actual).to eq(randomization_factor)
64
- end
65
- end
66
- end
67
-
68
- describe '#next_interval' do
69
- subject {
70
- described_class.new(
71
- min_timeout_ms: 1000,
72
- max_timeout_ms: 10000,
73
- multiplier: 2,
74
- randomization_factor: 0.5
75
- )
76
- }
77
-
78
- it 'returns exponentially increasing durations' do
79
- expect(subject.next_interval).to be_within(500).of(1000)
80
- expect(subject.next_interval).to be_within(1000).of(2000)
81
- expect(subject.next_interval).to be_within(2000).of(4000)
82
- expect(subject.next_interval).to be_within(4000).of(8000)
83
- end
84
-
85
- it 'caps maximum duration at max_timeout_secs' do
86
- 10.times { subject.next_interval }
87
- expect(subject.next_interval).to eq(10000)
88
- end
89
- end
90
- end
91
- end
92
- end
@@ -1,328 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Segment
4
- class Analytics
5
- describe Client do
6
- let(:client) do
7
- Client.new(:write_key => WRITE_KEY).tap { |client|
8
- # Ensure that worker doesn't consume items from the queue
9
- client.instance_variable_set(:@worker, NoopWorker.new)
10
- }
11
- end
12
- let(:queue) { client.instance_variable_get :@queue }
13
-
14
- describe '#initialize' do
15
- it 'errors if no write_key is supplied' do
16
- expect { Client.new }.to raise_error(ArgumentError)
17
- end
18
-
19
- it 'does not error if a write_key is supplied' do
20
- expect do
21
- Client.new :write_key => WRITE_KEY
22
- end.to_not raise_error
23
- end
24
-
25
- it 'does not error if a write_key is supplied as a string' do
26
- expect do
27
- Client.new 'write_key' => WRITE_KEY
28
- end.to_not raise_error
29
- end
30
- end
31
-
32
- describe '#track' do
33
- it 'errors without an event' do
34
- expect { client.track(:user_id => 'user') }.to raise_error(ArgumentError)
35
- end
36
-
37
- it 'errors without a user_id' do
38
- expect { client.track(:event => 'Event') }.to raise_error(ArgumentError)
39
- end
40
-
41
- it 'errors if properties is not a hash' do
42
- expect {
43
- client.track({
44
- :user_id => 'user',
45
- :event => 'Event',
46
- :properties => [1, 2, 3]
47
- })
48
- }.to raise_error(ArgumentError)
49
- end
50
-
51
- it 'uses the timestamp given' do
52
- time = Time.parse('1990-07-16 13:30:00.123 UTC')
53
-
54
- client.track({
55
- :event => 'testing the timestamp',
56
- :user_id => 'joe',
57
- :timestamp => time
58
- })
59
-
60
- msg = queue.pop
61
-
62
- expect(Time.parse(msg[:timestamp])).to eq(time)
63
- end
64
-
65
- it 'does not error with the required options' do
66
- expect do
67
- client.track Queued::TRACK
68
- queue.pop
69
- end.to_not raise_error
70
- end
71
-
72
- it 'does not error when given string keys' do
73
- expect do
74
- client.track Utils.stringify_keys(Queued::TRACK)
75
- queue.pop
76
- end.to_not raise_error
77
- end
78
-
79
- it 'converts time and date traits into iso8601 format' do
80
- client.track({
81
- :user_id => 'user',
82
- :event => 'Event',
83
- :properties => {
84
- :time => Time.utc(2013),
85
- :time_with_zone => Time.zone.parse('2013-01-01'),
86
- :date_time => DateTime.new(2013, 1, 1),
87
- :date => Date.new(2013, 1, 1),
88
- :nottime => 'x'
89
- }
90
- })
91
- message = queue.pop
92
-
93
- properties = message[:properties]
94
- expect(properties[:time]).to eq('2013-01-01T00:00:00.000Z')
95
- expect(properties[:time_with_zone]).to eq('2013-01-01T00:00:00.000Z')
96
- expect(properties[:date_time]).to eq('2013-01-01T00:00:00.000+00:00')
97
- expect(properties[:date]).to eq('2013-01-01')
98
- expect(properties[:nottime]).to eq('x')
99
- end
100
- end
101
-
102
- describe '#identify' do
103
- it 'errors without any user id' do
104
- expect { client.identify({}) }.to raise_error(ArgumentError)
105
- end
106
-
107
- it 'does not error with the required options' do
108
- expect do
109
- client.identify Queued::IDENTIFY
110
- queue.pop
111
- end.to_not raise_error
112
- end
113
-
114
- it 'does not error with the required options as strings' do
115
- expect do
116
- client.identify Utils.stringify_keys(Queued::IDENTIFY)
117
- queue.pop
118
- end.to_not raise_error
119
- end
120
-
121
- it 'converts time and date traits into iso8601 format' do
122
- client.identify({
123
- :user_id => 'user',
124
- :traits => {
125
- :time => Time.utc(2013),
126
- :time_with_zone => Time.zone.parse('2013-01-01'),
127
- :date_time => DateTime.new(2013, 1, 1),
128
- :date => Date.new(2013, 1, 1),
129
- :nottime => 'x'
130
- }
131
- })
132
-
133
- message = queue.pop
134
-
135
- traits = message[:traits]
136
- expect(traits[:time]).to eq('2013-01-01T00:00:00.000Z')
137
- expect(traits[:time_with_zone]).to eq('2013-01-01T00:00:00.000Z')
138
- expect(traits[:date_time]).to eq('2013-01-01T00:00:00.000+00:00')
139
- expect(traits[:date]).to eq('2013-01-01')
140
- expect(traits[:nottime]).to eq('x')
141
- end
142
- end
143
-
144
- describe '#alias' do
145
- it 'errors without from' do
146
- expect { client.alias :user_id => 1234 }.to raise_error(ArgumentError)
147
- end
148
-
149
- it 'errors without to' do
150
- expect { client.alias :previous_id => 1234 }.to raise_error(ArgumentError)
151
- end
152
-
153
- it 'does not error with the required options' do
154
- expect { client.alias ALIAS }.to_not raise_error
155
- end
156
-
157
- it 'does not error with the required options as strings' do
158
- expect do
159
- client.alias Utils.stringify_keys(ALIAS)
160
- end.to_not raise_error
161
- end
162
- end
163
-
164
- describe '#group' do
165
- it 'errors without group_id' do
166
- expect { client.group :user_id => 'foo' }.to raise_error(ArgumentError)
167
- end
168
-
169
- it 'errors without user_id' do
170
- expect { client.group :group_id => 'foo' }.to raise_error(ArgumentError)
171
- end
172
-
173
- it 'does not error with the required options' do
174
- client.group Queued::GROUP
175
- end
176
-
177
- it 'does not error with the required options as strings' do
178
- client.group Utils.stringify_keys(Queued::GROUP)
179
- end
180
-
181
- it 'converts time and date traits into iso8601 format' do
182
- client.identify({
183
- :user_id => 'user',
184
- :group_id => 'group',
185
- :traits => {
186
- :time => Time.utc(2013),
187
- :time_with_zone => Time.zone.parse('2013-01-01'),
188
- :date_time => DateTime.new(2013, 1, 1),
189
- :date => Date.new(2013, 1, 1),
190
- :nottime => 'x'
191
- }
192
- })
193
-
194
- message = queue.pop
195
-
196
- traits = message[:traits]
197
- expect(traits[:time]).to eq('2013-01-01T00:00:00.000Z')
198
- expect(traits[:time_with_zone]).to eq('2013-01-01T00:00:00.000Z')
199
- expect(traits[:date_time]).to eq('2013-01-01T00:00:00.000+00:00')
200
- expect(traits[:date]).to eq('2013-01-01')
201
- expect(traits[:nottime]).to eq('x')
202
- end
203
- end
204
-
205
- describe '#page' do
206
- it 'errors without user_id' do
207
- expect { client.page :name => 'foo' }.to raise_error(ArgumentError)
208
- end
209
-
210
- it 'does not error with the required options' do
211
- expect { client.page Queued::PAGE }.to_not raise_error
212
- end
213
-
214
- it 'does not error with the required options as strings' do
215
- expect do
216
- client.page Utils.stringify_keys(Queued::PAGE)
217
- end.to_not raise_error
218
- end
219
- end
220
-
221
- describe '#screen' do
222
- it 'errors without user_id' do
223
- expect { client.screen :name => 'foo' }.to raise_error(ArgumentError)
224
- end
225
-
226
- it 'does not error with the required options' do
227
- expect { client.screen Queued::SCREEN }.to_not raise_error
228
- end
229
-
230
- it 'does not error with the required options as strings' do
231
- expect do
232
- client.screen Utils.stringify_keys(Queued::SCREEN)
233
- end.to_not raise_error
234
- end
235
- end
236
-
237
- describe '#flush' do
238
- let(:client_with_worker) { Client.new(:write_key => WRITE_KEY) }
239
-
240
- it 'waits for the queue to finish on a flush' do
241
- client_with_worker.identify Queued::IDENTIFY
242
- client_with_worker.track Queued::TRACK
243
- client_with_worker.flush
244
-
245
- expect(client_with_worker.queued_messages).to eq(0)
246
- end
247
-
248
- unless defined? JRUBY_VERSION
249
- it 'completes when the process forks' do
250
- client_with_worker.identify Queued::IDENTIFY
251
-
252
- Process.fork do
253
- client_with_worker.track Queued::TRACK
254
- client_with_worker.flush
255
- expect(client_with_worker.queued_messages).to eq(0)
256
- end
257
-
258
- Process.wait
259
- end
260
- end
261
- end
262
-
263
- context 'common' do
264
- check_property = proc { |msg, k, v| msg[k] && msg[k] == v }
265
-
266
- let(:data) { { :user_id => 1, :group_id => 2, :previous_id => 3, :anonymous_id => 4, :message_id => 5, :event => 'coco barked', :name => 'coco' } }
267
-
268
- it 'does not convert ids given as fixnums to strings' do
269
- [:track, :screen, :page, :identify].each do |s|
270
- client.send(s, data)
271
- message = queue.pop(true)
272
-
273
- expect(check_property.call(message, :userId, 1)).to eq(true)
274
- expect(check_property.call(message, :anonymousId, 4)).to eq(true)
275
- end
276
- end
277
-
278
- it 'returns false if queue is full' do
279
- client.instance_variable_set(:@max_queue_size, 1)
280
-
281
- [:track, :screen, :page, :group, :identify, :alias].each do |s|
282
- expect(client.send(s, data)).to eq(true)
283
- expect(client.send(s, data)).to eq(false) # Queue is full
284
- queue.pop(true)
285
- end
286
- end
287
-
288
- it 'converts message id to string' do
289
- [:track, :screen, :page, :group, :identify, :alias].each do |s|
290
- client.send(s, data)
291
- message = queue.pop(true)
292
-
293
- expect(check_property.call(message, :messageId, '5')).to eq(true)
294
- end
295
- end
296
-
297
- context 'group' do
298
- it 'does not convert ids given as fixnums to strings' do
299
- client.group(data)
300
- message = queue.pop(true)
301
-
302
- expect(check_property.call(message, :userId, 1)).to eq(true)
303
- expect(check_property.call(message, :groupId, 2)).to eq(true)
304
- end
305
- end
306
-
307
- context 'alias' do
308
- it 'does not convert ids given as fixnums to strings' do
309
- client.alias(data)
310
- message = queue.pop(true)
311
-
312
- expect(check_property.call(message, :userId, 1)).to eq(true)
313
- expect(check_property.call(message, :previousId, 3)).to eq(true)
314
- end
315
- end
316
-
317
- it 'sends integrations' do
318
- [:track, :screen, :page, :group, :identify, :alias].each do |s|
319
- client.send s, :integrations => { :All => true, :Salesforce => false }, :user_id => 1, :group_id => 2, :previous_id => 3, :anonymous_id => 4, :event => 'coco barked', :name => 'coco'
320
- message = queue.pop(true)
321
- expect(message[:integrations][:All]).to eq(true)
322
- expect(message[:integrations][:Salesforce]).to eq(false)
323
- end
324
- end
325
- end
326
- end
327
- end
328
- end