analytics-ruby 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +39 -243
- data/analytics-ruby-0.0.1.gem +0 -0
- data/analytics.gemspec +14 -6
- data/lib/analytics.rb +2 -1
- data/lib/analytics/client.rb +8 -8
- data/lib/analytics/defaults.rb +3 -3
- data/lib/analytics/request.rb +3 -2
- data/lib/analytics/version.rb +3 -0
- data/spec/client.rb +9 -9
- data/spec/module.rb +11 -13
- data/spec/test.rb +25 -0
- metadata +55 -6
- data/.rspec +0 -1
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
analytics-ruby
|
2
2
|
==============
|
3
3
|
|
4
|
-
analytics-ruby is a ruby client for [Segment.io](https://segment.io).
|
4
|
+
analytics-ruby is a ruby client for [Segment.io](https://segment.io).
|
5
5
|
|
6
|
-
###
|
6
|
+
### Ruby Analytics Made Simple
|
7
7
|
|
8
8
|
[Segment.io](https://segment.io) is the cleanest, simplest API for recording analytics data.
|
9
9
|
|
@@ -11,10 +11,11 @@ Setting up a new analytics solution can be a real pain. The APIs from each analy
|
|
11
11
|
|
12
12
|
[Segment.io](https://segment.io) wraps all those APIs in one beautiful, simple API. Then we route your analytics data wherever you want, whether it's Google Analytics, Mixpanel, Customer io, Chartbeat, or any of our other integrations. After you set up Segment.io you can swap or add analytics providers at any time with a single click. You won't need to touch code or push to production. You'll save valuable development time so that you can focus on what really matters: your product.
|
13
13
|
|
14
|
-
```
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
```ruby
|
15
|
+
gem "analytics-ruby"; require "analytics"
|
16
|
+
Analytics.init "secrettoken"
|
17
|
+
Analytics.track(user_id: "ilya@segment.io",
|
18
|
+
event: "Played a Song")
|
18
19
|
```
|
19
20
|
|
20
21
|
and turn on integrations with just one click at [Segment.io](https://segment.io).
|
@@ -26,7 +27,7 @@ More on integrations [here](#integrations).
|
|
26
27
|
### High Performance
|
27
28
|
|
28
29
|
This client uses an internal queue to efficiently send your events in aggregate, rather than making an HTTP
|
29
|
-
request every time. It is also non-blocking and asynchronous, meaning it makes batch requests on another thread. This allows your code to call `analytics.track` or `analytics.identify` without incurring a large performance cost on the calling thread. Because of this, analytics-
|
30
|
+
request every time. It is also non-blocking and asynchronous, meaning it makes batch requests on another thread. This allows your code to call `analytics.track` or `analytics.identify` without incurring a large performance cost on the calling thread. Because of this, analytics-ruby is safe to use in your high scale web server controllers, or in your backend services
|
30
31
|
without worrying that it will make too many HTTP requests and slow down the program. You also no longer need to use a message queue to have analytics.
|
31
32
|
|
32
33
|
[Feedback is very welcome!](mailto:friends@segment.io)
|
@@ -37,61 +38,62 @@ If you haven't yet, get an API secret [here](https://segment.io).
|
|
37
38
|
|
38
39
|
#### Install
|
39
40
|
```bash
|
40
|
-
|
41
|
+
gem install analytics-ruby
|
41
42
|
```
|
42
43
|
|
43
44
|
#### Initialize the client
|
44
45
|
|
45
|
-
You can create separate analytics-
|
46
|
+
You can create separate analytics-ruby clients, but the easiest and recommended way is to just use the module:
|
46
47
|
|
47
|
-
```
|
48
|
-
|
49
|
-
|
48
|
+
```ruby
|
49
|
+
gem 'analytics-ruby'; require 'analytics'
|
50
|
+
Analytics.init 'secrettoken'
|
50
51
|
```
|
51
52
|
|
52
53
|
#### Identify a User
|
53
54
|
|
54
55
|
Whenever a user triggers an event, you’ll want to track it.
|
55
56
|
|
56
|
-
```
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
})
|
57
|
+
```ruby
|
58
|
+
Analytics.identify(session_id: 'ajsk2jdj29fj298',
|
59
|
+
user_id: 'ilya@segment.io',
|
60
|
+
traits: { subscription_plan: "Free",
|
61
|
+
friends: 30 })
|
61
62
|
```
|
62
63
|
|
63
|
-
**session_id** (
|
64
|
-
is logged in, you can still send us the **session_id** or you can just use `
|
64
|
+
**session_id** (String) is a unique id associated with an anonymous user **before** they are logged in. Even if the user
|
65
|
+
is logged in, you can still send us the **session_id** or you can just use `nil`.
|
65
66
|
|
66
|
-
**user_id** (
|
67
|
+
**user_id** (String) is the user's id **after** they are logged in. It's the same id as which you would recognize a signed-in user in your system. Note: you must provide either a `session_id` or a `user_id`.
|
67
68
|
|
68
|
-
**traits** (
|
69
|
+
**traits** (Hash) is a Hash with keys like `subscriptionPlan` or `favoriteGenre`. This argument is optional, but highly recommended—you’ll find these properties extremely useful later.
|
69
70
|
|
70
|
-
**timestamp** (
|
71
|
+
**timestamp** (Time, optional) is a Time object representing when the identify took place. If the event just happened, don't bother adding a time and we'll use the server's time. If you are importing data from the past, make sure you provide this argument.
|
71
72
|
|
72
73
|
#### Track an Action
|
73
74
|
|
74
75
|
Whenever a user triggers an event on your site, you’ll want to track it so that you can analyze and segment by those events later.
|
75
76
|
|
76
|
-
```
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
```ruby
|
78
|
+
Analytics.track(session_id: 'skdj2jj2dj2j3i5',
|
79
|
+
user_id: 'ilya@segment.io',
|
80
|
+
event: 'Drank some milk',
|
81
|
+
properties: {
|
82
|
+
fat: 0.02,
|
83
|
+
quantity: '4 gallons' })
|
82
84
|
```
|
83
85
|
|
84
86
|
|
85
|
-
**session_id** (
|
86
|
-
is logged in, you can still send us the **session_id** or you can just use `
|
87
|
+
**session_id** (String) is a unique id associated with an anonymous user **before** they are logged in. Even if the user
|
88
|
+
is logged in, you can still send us the **session_id** or you can just use `nil`.
|
87
89
|
|
88
|
-
**user_id** (
|
90
|
+
**user_id** (String) is the user's id **after** they are logged in. It's the same id as which you would recognize a signed-in user in your system. Note: you must provide either a `session_id` or a `user_id`.
|
89
91
|
|
90
|
-
**event** (
|
92
|
+
**event** (String) describes what this user just did. It's a human readable description like "Played a Song", "Printed a Report" or "Updated Status".
|
91
93
|
|
92
|
-
**properties** (
|
94
|
+
**properties** (Hash) is a hash with items that describe the event in more detail. This argument is optional, but highly recommended—you’ll find these properties extremely useful later.
|
93
95
|
|
94
|
-
**timestamp** (
|
96
|
+
**timestamp** (Time, optional) is a Time object representing when the identify took place. If the event just happened, leave it `nil` and we'll use the server's time. If you are importing data from the past, make sure you provide this argument.
|
95
97
|
|
96
98
|
That's it, just two functions!
|
97
99
|
|
@@ -118,223 +120,17 @@ You can learn which integrations are supported server-side vs. client-side on yo
|
|
118
120
|
By default, the client will flush:
|
119
121
|
|
120
122
|
1. the first time it gets a message
|
121
|
-
1.
|
122
|
-
1. if 10 seconds passes without a flush (control with ```flush_after```)
|
123
|
-
|
124
|
-
#### Turn Off Batching
|
125
|
-
|
126
|
-
When debugging or in short-lived programs, you might the client to make the
|
127
|
-
request right away. In this case, you can turn off batching by setting the
|
128
|
-
flush_at argument to 1.
|
129
|
-
|
130
|
-
```python
|
131
|
-
analytics.init('secret', flush_at=1)
|
132
|
-
```
|
133
|
-
|
134
|
-
|
135
|
-
#### Turn Off Asynchronous Flushing
|
136
|
-
|
137
|
-
By default, the client will create a new thread to flush the messages to the server.
|
138
|
-
This is so the calling thread doesn't block, [as is important in server side
|
139
|
-
environments](http://ivolo.me/batching-rest-apis/).
|
140
|
-
|
141
|
-
If you're not running a server or writing performance sensitive code ,
|
142
|
-
you might want to flush on the same thread that calls identify/track.
|
143
|
-
|
144
|
-
In this case, you can disable asynchronous flushing like so:
|
145
|
-
```python
|
146
|
-
analytics.init('secret', async=False)
|
147
|
-
```
|
148
|
-
|
149
|
-
#### Calling Flush Before Program End
|
150
|
-
|
151
|
-
If you're using the batching, it's a good idea to call
|
152
|
-
```python
|
153
|
-
analytics.flush(async=False)
|
154
|
-
```
|
155
|
-
before your program ends. This prevents your program from turning off with
|
156
|
-
items still in the queue.
|
157
|
-
|
158
|
-
#### Logging
|
159
|
-
|
160
|
-
analytics-python client uses the standard python logging module. By default, logging
|
161
|
-
is enabled and set at the logging.INFO level. If you want it to talk more,
|
162
|
-
|
163
|
-
```python
|
164
|
-
import logging
|
165
|
-
analytics.init('secret', log_level=logging.DEBUG)
|
166
|
-
```
|
167
|
-
|
168
|
-
If you hate logging with an undying passion, try this:
|
169
|
-
|
170
|
-
```python
|
171
|
-
analytics.init('secret', log=False)
|
172
|
-
```
|
173
|
-
|
174
|
-
#### Troubleshooting
|
175
|
-
|
176
|
-
**Turn off Async / Batching**
|
177
|
-
|
178
|
-
If you're having trouble sending messages to Segment.io, the first thing to try
|
179
|
-
is to turn off asynchronous flushing and disable batching, like so:
|
180
|
-
|
181
|
-
```python
|
182
|
-
analytics.init('secret', async=False, flush_at=1)
|
183
|
-
```
|
184
|
-
|
185
|
-
Now the client will flush on every message, and every time you call identify or
|
186
|
-
track.
|
187
|
-
|
188
|
-
**Enable Debug Logging**
|
189
|
-
|
190
|
-
```python
|
191
|
-
analytics.init('secret', async=False, flush_at=1, log_level=logging.DEBUG)
|
192
|
-
```
|
193
|
-
|
194
|
-
**Success / Failure Events**
|
195
|
-
|
196
|
-
Use events to receive successful or failed events.
|
197
|
-
```python
|
198
|
-
def on_success(data, response):
|
199
|
-
print 'Success', response
|
200
|
-
|
201
|
-
|
202
|
-
def on_failure(data, error):
|
203
|
-
print 'Failure', error
|
204
|
-
|
205
|
-
analytics.on_success(on_success)
|
206
|
-
analytics.on_failure(on_failure)
|
207
|
-
```
|
123
|
+
1. whenever messages are queued and there is no outstanding request
|
208
124
|
|
209
|
-
|
210
|
-
on_failure event callback.
|
125
|
+
The queue consumer runs in a different thread for each client to avoid blocking your webserver process. However, the consumer makes only a single outbound request at a time to avoid saturating your server's resources. If multiple messages are in the queue, they are sent together in a batch call.
|
211
126
|
|
212
127
|
#### Importing Historical Data
|
213
128
|
|
214
129
|
You can import historical data by adding the timestamp argument (of type
|
215
|
-
|
130
|
+
Time) to the identify / track calls. Note: if you are tracking
|
216
131
|
things that are happening now, we prefer that you leave the timestamp out and
|
217
132
|
let our servers timestamp your requests.
|
218
133
|
|
219
|
-
##### Example
|
220
|
-
|
221
|
-
```python
|
222
|
-
import datetime
|
223
|
-
from dateutil.tz import tzutc
|
224
|
-
|
225
|
-
when = datetime.datetime(2538, 10, 17, 0, 0, 0, 0, tzinfo=tzutc())
|
226
|
-
analytics.track(user_id=user_id, timestamp=when, event='Bought a game', properties={
|
227
|
-
"game": "Duke Nukem Forever",
|
228
|
-
})
|
229
|
-
```
|
230
|
-
|
231
|
-
##### Python and Timezones
|
232
|
-
|
233
|
-
Python's standard datetime object is broken because it
|
234
|
-
[loses timezone information](http://stackoverflow.com/questions/2331592/datetime-datetime-utcnow-why-no-tzinfo).
|
235
|
-
|
236
|
-
```python
|
237
|
-
>>> import datetime
|
238
|
-
>>> print datetime.datetime.now().isoformat()
|
239
|
-
2012-10-17T11:51:17.351481
|
240
|
-
>>> print datetime.datetime.utcnow().isoformat()
|
241
|
-
2012-10-17T18:51:17.919517
|
242
|
-
>>> print datetime.datetime.now().tzinfo
|
243
|
-
None
|
244
|
-
>>> print datetime.datetime.utcnow().tzinfo
|
245
|
-
None
|
246
|
-
````
|
247
|
-
|
248
|
-
You'll notice that a utcnow() and a now() date are very different (since I'm
|
249
|
-
in PDT, they are exactly -7:00 hours different). However, by default, Python
|
250
|
-
doesn't retain timezone information with the datetime object. This means that
|
251
|
-
our code can only guess about what timezone you were referring to.
|
252
|
-
|
253
|
-
If you have an ISO format timestamp string that contains timezone information, you
|
254
|
-
can do the following:
|
255
|
-
```python
|
256
|
-
>>> import dateutil.parser
|
257
|
-
>>> dateutil.parser.parse('2012-10-17T18:58:57.911Z')
|
258
|
-
datetime.datetime(2012, 10, 17, 18, 58, 57, 911000, tzinfo=tzutc())
|
259
|
-
```
|
260
|
-
|
261
|
-
Or if you're not parsing a string, make sure to
|
262
|
-
supply timezone information using [pytz](http://pytz.sourceforge.net/):
|
263
|
-
```python
|
264
|
-
from pytz import timezone
|
265
|
-
eastern = timezone('US/Eastern')
|
266
|
-
loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
|
267
|
-
```
|
268
|
-
|
269
|
-
Whatever your method, please include the timezone information in your datetime objects or
|
270
|
-
else your data may be in the incorrect time.
|
271
|
-
```python
|
272
|
-
# checks that dt has a timezone
|
273
|
-
assert dt.tzinfo
|
274
|
-
```
|
275
|
-
|
276
|
-
##### Server Logs Example
|
277
|
-
|
278
|
-
```python
|
279
|
-
|
280
|
-
import dateutil.parser
|
281
|
-
|
282
|
-
import analytics
|
283
|
-
analytics.init('MY_API_SECRET', async=False)
|
284
|
-
|
285
|
-
log = [
|
286
|
-
'2012-10-17T18:58:57.911Z ilya@segment.io /purchased/tshirt'
|
287
|
-
]
|
288
|
-
|
289
|
-
for entry in log:
|
290
|
-
|
291
|
-
(timestamp_str, user_id, url) = entry.split(' ')
|
292
|
-
|
293
|
-
timestamp = dateutil.parser.parse(timestamp_str) # datetime.datetime object has a timezone
|
294
|
-
|
295
|
-
# have a timezone? check yo'self
|
296
|
-
assert timestamp.tzinfo
|
297
|
-
|
298
|
-
analytics.track(user_id=user_id, timestamp=timestamp, event='Bought a shirt', properties={
|
299
|
-
"color": "Blue",
|
300
|
-
"revenue": 17.90
|
301
|
-
})
|
302
|
-
|
303
|
-
analytics.flush(async=False)
|
304
|
-
|
305
|
-
|
306
|
-
```
|
307
|
-
|
308
|
-
#### Full Client Configuration
|
309
|
-
|
310
|
-
If you hate defaults, than you'll love how configurable the Segment.io client is.
|
311
|
-
Check out these gizmos:
|
312
|
-
|
313
|
-
```python
|
314
|
-
|
315
|
-
import analytics
|
316
|
-
analytics.init('MY_API_SECRET',
|
317
|
-
log_level=logging.INFO, log=True,
|
318
|
-
flush_at=20, flush_after=datetime.timedelta(0, 10),
|
319
|
-
async=True
|
320
|
-
max_queue_size=100000)
|
321
|
-
|
322
|
-
```
|
323
|
-
|
324
|
-
|
325
|
-
* **log_level** (logging.LOG_LEVEL): The logging log level for the client talks to. Use log_level=logging.DEBUG to troubleshoot.
|
326
|
-
* **log** (bool): False to turn off logging completely, True by default
|
327
|
-
* **flush_at** (int): Specicies after how many messages the client will flush to the server. Use flush_at=1 to disable batching
|
328
|
-
* **flush_after** (datetime.timedelta): Specifies after how much time of no flushing that the server will flush. Used in conjunction with the flush_at size policy
|
329
|
-
* **async** (bool): True to have the client flush to the server on another thread, therefore not blocking code (this is the default). False to enable blocking and making the request on the calling thread.
|
330
|
-
* **max_queue_size** (int): Maximum number of elements allowed in the queue. If this condition is ever reached, that means you're identifying / tracking faster than you can flush. If this happens, let us know!
|
331
|
-
|
332
|
-
#### Testing
|
333
|
-
|
334
|
-
```bash
|
335
|
-
python test.py
|
336
|
-
```
|
337
|
-
|
338
134
|
#### License
|
339
135
|
|
340
136
|
```
|
Binary file
|
data/analytics.gemspec
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
$:.
|
1
|
+
$:.push File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'analytics/version'
|
4
|
+
|
2
5
|
|
3
6
|
Gem::Specification.new do |spec|
|
4
|
-
spec.name =
|
5
|
-
spec.version =
|
6
|
-
spec.files =
|
7
|
+
spec.name = 'analytics-ruby'
|
8
|
+
spec.version = Analytics::VERSION
|
9
|
+
spec.files = Dir.glob('**/*')
|
7
10
|
spec.require_paths = ['lib']
|
8
|
-
spec.summary =
|
9
|
-
spec.authors = [
|
11
|
+
spec.summary = 'Segment.io analytics library'
|
12
|
+
spec.authors = ['friends@segment.io']
|
13
|
+
|
14
|
+
spec.add_dependency 'faraday', ['~> 0.8', '< 0.10']
|
15
|
+
spec.add_dependency 'faraday_middleware', ['~> 0.9.0']
|
16
|
+
spec.add_dependency 'multi_json', ['~> 1.0']
|
17
|
+
spec.add_dependency 'typhoeus', ['~> 0.5.0']
|
10
18
|
end
|
data/lib/analytics.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
require 'forwardable'
|
3
|
-
|
3
|
+
require 'analytics/version'
|
4
4
|
require 'analytics/client'
|
5
5
|
|
6
6
|
module Analytics
|
@@ -8,6 +8,7 @@ module Analytics
|
|
8
8
|
|
9
9
|
def_delegators :@client, :track, :identify
|
10
10
|
|
11
|
+
# By default use a single client for the module
|
11
12
|
def self.init(options = {})
|
12
13
|
@client = Analytics::Client.new(options)
|
13
14
|
end
|
data/lib/analytics/client.rb
CHANGED
@@ -50,7 +50,7 @@ module Analytics
|
|
50
50
|
check_timestamp(timestamp)
|
51
51
|
|
52
52
|
if event.nil? || event.empty?
|
53
|
-
fail ArgumentError,
|
53
|
+
fail ArgumentError, 'Must supply event as a non-empty string'
|
54
54
|
end
|
55
55
|
|
56
56
|
add_context(context)
|
@@ -61,7 +61,7 @@ module Analytics
|
|
61
61
|
context: context,
|
62
62
|
properties: properties,
|
63
63
|
timestamp: timestamp.iso8601,
|
64
|
-
action:
|
64
|
+
action: 'track' })
|
65
65
|
end
|
66
66
|
|
67
67
|
# Public: Identifies a user
|
@@ -85,7 +85,7 @@ module Analytics
|
|
85
85
|
ensure_user(session_id, user_id)
|
86
86
|
check_timestamp(timestamp)
|
87
87
|
|
88
|
-
fail ArgumentError,
|
88
|
+
fail ArgumentError, 'Must supply traits as a hash' unless traits.is_a? Hash
|
89
89
|
|
90
90
|
add_context(context)
|
91
91
|
|
@@ -94,7 +94,7 @@ module Analytics
|
|
94
94
|
context: context,
|
95
95
|
traits: traits,
|
96
96
|
timestamp: timestamp.iso8601,
|
97
|
-
action:
|
97
|
+
action: 'identify' })
|
98
98
|
end
|
99
99
|
|
100
100
|
|
@@ -116,7 +116,7 @@ module Analytics
|
|
116
116
|
# user_id - String of the user id
|
117
117
|
#
|
118
118
|
def ensure_user(session_id, user_id)
|
119
|
-
message =
|
119
|
+
message = 'Must supply either a non-empty session_id or user_id (or both)'
|
120
120
|
|
121
121
|
valid = user_id.is_a?(String) && !user_id.empty?
|
122
122
|
valid ||= session_id.is_a?(String) && !session_id.empty?
|
@@ -128,17 +128,17 @@ module Analytics
|
|
128
128
|
#
|
129
129
|
# context - Hash of call context
|
130
130
|
def add_context(context)
|
131
|
-
context[:library] =
|
131
|
+
context[:library] = 'analytics-ruby'
|
132
132
|
end
|
133
133
|
|
134
134
|
# Private: Checks that the secret is properly initialized
|
135
135
|
def check_secret
|
136
|
-
fail
|
136
|
+
fail 'Secret must be initialized' if @secret.nil?
|
137
137
|
end
|
138
138
|
|
139
139
|
# Private: Checks the timstamp option to make sure it is a Time.
|
140
140
|
def check_timestamp(timestamp)
|
141
|
-
fail ArgumentError,
|
141
|
+
fail ArgumentError, 'Timestamp must be a Time' unless timestamp.is_a? Time
|
142
142
|
end
|
143
143
|
end
|
144
144
|
end
|
data/lib/analytics/defaults.rb
CHANGED
@@ -3,10 +3,10 @@ module Analytics
|
|
3
3
|
module Defaults
|
4
4
|
|
5
5
|
module Request
|
6
|
-
BASE_URL =
|
7
|
-
PATH =
|
6
|
+
BASE_URL = 'https://api.segment.io' unless defined? Analytics::Defaults::Request::BASE_URL
|
7
|
+
PATH = '/v1/import' unless defined? Analytics::Defaults::Request::PATH
|
8
8
|
SSL = { verify: false } unless defined? Analytics::Defaults::Request::SSL
|
9
|
-
HEADERS = { accept:
|
9
|
+
HEADERS = { accept: 'application/json' } unless defined? Analytics::Defaults::Request::HEADERS
|
10
10
|
end
|
11
11
|
|
12
12
|
module Queue
|
data/lib/analytics/request.rb
CHANGED
@@ -10,7 +10,7 @@ module Analytics
|
|
10
10
|
|
11
11
|
class Request
|
12
12
|
|
13
|
-
# Creates a new request object
|
13
|
+
# public: Creates a new request object to send analytics batch
|
14
14
|
#
|
15
15
|
def initialize(options = {})
|
16
16
|
|
@@ -26,7 +26,8 @@ module Analytics
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
# public: Posts
|
30
|
+
#
|
30
31
|
def post(secret, batch)
|
31
32
|
@conn.post do |req|
|
32
33
|
req.url(@path)
|
data/spec/client.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
require_relative '../lib/analytics'
|
2
2
|
|
3
3
|
|
4
|
-
describe Analytics::Client,
|
4
|
+
describe Analytics::Client, '#track' do
|
5
5
|
|
6
|
-
before(:all) { @client = Analytics::Client.new(secret:
|
6
|
+
before(:all) { @client = Analytics::Client.new(secret: 'testsecret') }
|
7
7
|
|
8
|
-
it
|
9
|
-
expect { @client.track(user_id:
|
8
|
+
it 'should error without an event' do
|
9
|
+
expect { @client.track(user_id: 'user') }.to raise_error(ArgumentError)
|
10
10
|
end
|
11
11
|
|
12
|
-
it
|
13
|
-
expect { @client.track(event:
|
12
|
+
it 'should error without a user or session' do
|
13
|
+
expect { @client.track(event: 'Event') }.to raise_error(ArgumentError)
|
14
14
|
end
|
15
15
|
|
16
|
-
it
|
17
|
-
@client.track(user_id:
|
18
|
-
event:
|
16
|
+
it 'should not error with the required options' do
|
17
|
+
@client.track(user_id: 'user',
|
18
|
+
event: 'Event')
|
19
19
|
end
|
20
20
|
|
21
21
|
end
|
data/spec/module.rb
CHANGED
@@ -1,29 +1,27 @@
|
|
1
1
|
require_relative '../lib/analytics'
|
2
2
|
|
3
3
|
|
4
|
-
describe Analytics,
|
4
|
+
describe Analytics, '#init' do
|
5
5
|
|
6
|
-
it
|
7
|
-
Analytics.init
|
6
|
+
it 'should successfully init' do
|
7
|
+
Analytics.init secret: 'testsecret'
|
8
8
|
end
|
9
|
-
|
10
|
-
|
11
9
|
end
|
12
10
|
|
13
11
|
|
14
|
-
describe Analytics,
|
12
|
+
describe Analytics, '#track' do
|
15
13
|
|
16
|
-
it
|
17
|
-
expect { Analytics.track
|
14
|
+
it 'should error without an event' do
|
15
|
+
expect { Analytics.track user_id: 'user' }.to raise_error(ArgumentError)
|
18
16
|
end
|
19
17
|
|
20
|
-
it
|
21
|
-
expect { Analytics.track
|
18
|
+
it 'should error without a user or session' do
|
19
|
+
expect { Analytics.track event: 'Event' }.to raise_error(ArgumentError)
|
22
20
|
end
|
23
21
|
|
24
|
-
it
|
25
|
-
Analytics.track
|
26
|
-
|
22
|
+
it 'should not error with the required options' do
|
23
|
+
Analytics.track user_id: 'user',
|
24
|
+
event: 'Event'
|
27
25
|
end
|
28
26
|
|
29
27
|
end
|
data/spec/test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Analytics
|
4
|
+
module Defaults
|
5
|
+
module Request
|
6
|
+
BASE_URL = "http://localhost:7001"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
require_relative '../lib/analytics'
|
12
|
+
|
13
|
+
puts "Hello"
|
14
|
+
|
15
|
+
|
16
|
+
client = Analytics::Client.new(secret: "testsecret")
|
17
|
+
|
18
|
+
puts "Client made"
|
19
|
+
|
20
|
+
100.times do
|
21
|
+
client.identify(user_id: "user")
|
22
|
+
client.track(user_id: "user",
|
23
|
+
event: "No Typhoeus")
|
24
|
+
end
|
25
|
+
sleep 10
|
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.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,21 +10,70 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2013-01-16 00:00:00.000000000 Z
|
13
|
-
dependencies:
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: faraday
|
16
|
+
requirement: &14967320 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.8'
|
22
|
+
- - <
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0.10'
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: *14967320
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: faraday_middleware
|
30
|
+
requirement: &14962920 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.9.0
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: *14962920
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: multi_json
|
41
|
+
requirement: &14961260 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: *14961260
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: typhoeus
|
52
|
+
requirement: &14956120 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.5.0
|
58
|
+
type: :runtime
|
59
|
+
prerelease: false
|
60
|
+
version_requirements: *14956120
|
14
61
|
description:
|
15
62
|
email:
|
16
63
|
executables: []
|
17
64
|
extensions: []
|
18
65
|
extra_rdoc_files: []
|
19
66
|
files:
|
20
|
-
- .rspec
|
21
|
-
- README.md
|
22
67
|
- analytics.gemspec
|
68
|
+
- README.md
|
23
69
|
- lib/analytics.rb
|
24
|
-
- lib/analytics/client.rb
|
25
|
-
- lib/analytics/consumer.rb
|
26
70
|
- lib/analytics/defaults.rb
|
71
|
+
- lib/analytics/consumer.rb
|
27
72
|
- lib/analytics/request.rb
|
73
|
+
- lib/analytics/version.rb
|
74
|
+
- lib/analytics/client.rb
|
75
|
+
- analytics-ruby-0.0.1.gem
|
76
|
+
- spec/test.rb
|
28
77
|
- spec/client.rb
|
29
78
|
- spec/module.rb
|
30
79
|
homepage:
|
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|