mixpannenkoek 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +42 -2
- data/lib/mixpannenkoek/base.rb +2 -0
- data/lib/mixpannenkoek/query.rb +7 -9
- data/lib/mixpannenkoek/version.rb +1 -1
- data/spec/fixtures/funnel_response_data.json +29 -29
- data/spec/lib/mixpannenkoek/query_spec.rb +9 -8
- data/spec/lib/mixpannenkoek/results/base_spec.rb +26 -0
- data/spec/lib/mixpannenkoek/results/funnels_spec.rb +26 -0
- data/spec/lib/mixpannenkoek/results_spec.rb +17 -0
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7399793b312fda362a710cab02c13c0061f3181
|
4
|
+
data.tar.gz: 3d4990a74dc58c7d011c83d7d9f0794ceb0eba76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebed70b8633f90ef5976f67defa8d8351e47e5ac9690fafd1ec192f0d55151c25f212aa0235d604892a3e419d7b090dcc39f3026d4f1d5a890fe20ecca329634
|
7
|
+
data.tar.gz: a93ba52c09f8f521558305c7432f5115bc253f43d9f25933eeb6422c0df350984a5ced58048153356829fa565bf937fb77c291e75ddea36733c7c6e5451095f1
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Mixpannenkoek
|
2
2
|
|
3
|
-
|
3
|
+
This gem implements a fluent query interface for mixpanel_client.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,7 +18,47 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
Begin by configuring a model.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class ConversionFunnel < Mixpannenkoek::Base
|
25
|
+
set_api_key 'MY_API_KEY'
|
26
|
+
set_api_secret 'MY_API_SECRET'
|
27
|
+
set_endpoint 'funnels'
|
28
|
+
|
29
|
+
default_scope { set(funnel_id: 123456) }
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Build up a query with `where`, `group`, and `set`.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
ConversionFunnel.where(date: 31.days.ago..1.day.ago)
|
37
|
+
|
38
|
+
ConversionFunnel.where(date: 31.days.ago..1.day.ago).where(user_id: 123).set(interval: 50).group('traffic_source')
|
39
|
+
```
|
40
|
+
|
41
|
+
Operate on the query results fluently
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
ConversionFunnel.where(date: 31.days.ago..1.day.ago).map { |date,data| data['steps'].last['count'] }
|
45
|
+
#=> [1, 4, 2]
|
46
|
+
```
|
47
|
+
|
48
|
+
Organize your query models with default scopes. Default scopes are heritable, so they will be automatically be applied to subclasses.
|
49
|
+
```ruby
|
50
|
+
class ConversionFunnel < Mixpannenkoek::Base
|
51
|
+
default_scope { set(interval: 50) }
|
52
|
+
default_scope { where(user_type: 'visitor') }
|
53
|
+
end
|
54
|
+
|
55
|
+
# default scopes are heritable
|
56
|
+
# (GroupedConversionFunnel will get the default scopes
|
57
|
+
# of ConversionFunnel, in addition to its own)
|
58
|
+
class GroupedConversionFunnel < ConversionFunnel
|
59
|
+
default_scope { group('traffic_source') }
|
60
|
+
end
|
61
|
+
```
|
22
62
|
|
23
63
|
## Contributing
|
24
64
|
|
data/lib/mixpannenkoek/base.rb
CHANGED
data/lib/mixpannenkoek/query.rb
CHANGED
@@ -2,13 +2,6 @@ require 'rubygems'
|
|
2
2
|
require 'mixpanel_client'
|
3
3
|
|
4
4
|
module Mixpannenkoek
|
5
|
-
class Benchmark
|
6
|
-
def self.ms(&block)
|
7
|
-
return block.call unless defined?(::Benchmark)
|
8
|
-
::Benchmark.ms(&block)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
5
|
class Query
|
13
6
|
class MissingRange < Exception; end
|
14
7
|
class MissingConfiguration < Exception; end
|
@@ -114,11 +107,16 @@ module Mixpannenkoek
|
|
114
107
|
|
115
108
|
def response_data
|
116
109
|
check_parameters
|
117
|
-
|
110
|
+
log do
|
118
111
|
@mixpanel_request ||= mixpanel_client.request(*request_parameters)
|
119
112
|
end
|
120
|
-
Rails.logger.info " Mixpanel (#{time.round(1)}ms) #{request_parameters.inspect}" if defined? Rails
|
121
113
|
@mixpanel_request
|
122
114
|
end
|
115
|
+
|
116
|
+
def log(&block)
|
117
|
+
return block.call unless defined?(::Benchmark)
|
118
|
+
time = ::Benchmark.ms(&block)
|
119
|
+
Rails.logger.info " Mixpanel (#{time.round(1)}ms) #{request_parameters.inspect}" if defined? Rails
|
120
|
+
end
|
123
121
|
end
|
124
122
|
end
|
@@ -1,29 +1,29 @@
|
|
1
|
-
{"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
1
|
+
{"data": {"2010-05-24": {"analysis": {"completion": 0.064679359580052493,
|
2
|
+
"starting_amount": 762,
|
3
|
+
"steps": 3,
|
4
|
+
"worst": 2},
|
5
|
+
"steps": [{"count": 762,
|
6
|
+
"goal": "pages",
|
7
|
+
"overall_conv_ratio": 1.0,
|
8
|
+
"step_conv_ratio": 1.0},
|
9
|
+
{"count": 69,
|
10
|
+
"goal": "View signup",
|
11
|
+
"overall_conv_ratio": 0.09055118110236221,
|
12
|
+
"step_conv_ratio": 0.09055118110236221},
|
13
|
+
{"count": 10,
|
14
|
+
"goal": "View docs",
|
15
|
+
"overall_conv_ratio": 0.064679359580052493,
|
16
|
+
"step_conv_ratio": 0.7142857142857143}]},
|
17
|
+
"2010-05-31": {"analysis": {"completion": 0.12362030905077263,
|
18
|
+
"starting_amount": 906,
|
19
|
+
"steps": 2,
|
20
|
+
"worst": 2},
|
21
|
+
"steps": [{"count": 906,
|
22
|
+
"goal": "homepage",
|
23
|
+
"overall_conv_ratio": 1.0,
|
24
|
+
"step_conv_ratio": 1.0},
|
25
|
+
{"count": 112,
|
26
|
+
"goal": "View signup",
|
27
|
+
"overall_conv_ratio": 0.12362030905077263,
|
28
|
+
"step_conv_ratio": 0.12362030905077263}]}},
|
29
|
+
"meta": {"dates": ["2010-05-24", "2010-05-31"]}}
|
@@ -96,24 +96,25 @@ describe Mixpannenkoek::Base do
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
describe '#
|
100
|
-
subject { Mixpannenkoek::TestQuery.where(date: date_range).
|
99
|
+
describe '#results' do
|
100
|
+
subject { Mixpannenkoek::TestQuery.where(date: date_range).results }
|
101
101
|
|
102
102
|
let(:response_data) { JSON.parse(File.open("#{File.dirname(__FILE__)}/../../fixtures/funnel_response_data.json").read) }
|
103
103
|
before { Mixpanel::Client.any_instance.stub(:request).and_return(response_data) }
|
104
104
|
|
105
|
-
it 'returns
|
106
|
-
expect(subject).to
|
105
|
+
it 'returns a Mixpannenkoek::Results::Base object' do
|
106
|
+
expect(subject).to be_a Mixpannenkoek::Results::Base
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
110
|
describe '#method_missing' do
|
111
|
-
before {
|
112
|
-
it 'delegates all calls to #
|
113
|
-
expect(Mixpannenkoek::TestQuery.where(date: date_range).keys).to eq ['
|
111
|
+
before { Mixpanel::Client.any_instance.stub(:request).and_return({ "data" => { "2014-01-01" => [{ 'count' => '1' }, { 'count' => '4' }] } }) }
|
112
|
+
it 'delegates all calls to #results.send(*args)' do
|
113
|
+
expect(Mixpannenkoek::TestQuery.where(date: date_range).keys).to eq ['2014-01-01']
|
114
114
|
end
|
115
|
+
|
115
116
|
it 'delegates blocks' do
|
116
|
-
expect(Mixpannenkoek::TestQuery.where(date: date_range)
|
117
|
+
expect(Mixpannenkoek::TestQuery.where(date: date_range).values[0].map { |hash| hash['count'] }).to eq ['1','4']
|
117
118
|
end
|
118
119
|
end
|
119
120
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mixpannenkoek::Results::Base do
|
4
|
+
let(:response_data) { JSON.parse(File.open("#{File.dirname(__FILE__)}/../../../fixtures/funnel_response_data.json").read) }
|
5
|
+
|
6
|
+
describe '#to_hash' do
|
7
|
+
subject { described_class.new(response_data).to_hash }
|
8
|
+
it 'returns the response data' do
|
9
|
+
expect(subject).to eq response_data
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#response_data' do
|
14
|
+
subject { described_class.new(response_data).response_data }
|
15
|
+
it 'returns the response data' do
|
16
|
+
expect(subject).to eq response_data
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#method_missing' do
|
21
|
+
subject { described_class.new(response_data) }
|
22
|
+
it 'delegates to to_hash' do
|
23
|
+
expect(subject.keys).to eq ['data', 'meta']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mixpannenkoek::Results::Funnels do
|
4
|
+
let(:response_data) { JSON.parse(File.open("#{File.dirname(__FILE__)}/../../../fixtures/funnel_response_data.json").read) }
|
5
|
+
|
6
|
+
describe '#to_hash' do
|
7
|
+
subject { described_class.new(response_data).to_hash }
|
8
|
+
it 'returns the response data' do
|
9
|
+
expect(subject).to eq response_data['data']
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#response_data' do
|
14
|
+
subject { described_class.new(response_data).response_data }
|
15
|
+
it 'returns the response data' do
|
16
|
+
expect(subject).to eq response_data
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#method_missing' do
|
21
|
+
subject { described_class.new(response_data) }
|
22
|
+
it 'delegates to to_hash' do
|
23
|
+
expect(subject.keys).to eq ['2010-05-24', '2010-05-31']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mixpannenkoek::Results do
|
4
|
+
describe '.new' do
|
5
|
+
subject { Mixpannenkoek::Results.new(endpoint, {}) }
|
6
|
+
|
7
|
+
context 'any endpoint' do
|
8
|
+
let(:endpoint) { 'endpoint' }
|
9
|
+
it { expect(subject).to be_a Mixpannenkoek::Results::Base }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'funnels endoint' do
|
13
|
+
let(:endpoint) { 'funnels' }
|
14
|
+
it { expect(subject).to be_a Mixpannenkoek::Results::Funnels }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixpannenkoek
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Kraan
|
@@ -92,6 +92,9 @@ files:
|
|
92
92
|
- spec/lib/mixpannenkoek/base_spec.rb
|
93
93
|
- spec/lib/mixpannenkoek/class_inheritable_attributes_spec.rb
|
94
94
|
- spec/lib/mixpannenkoek/query_spec.rb
|
95
|
+
- spec/lib/mixpannenkoek/results/base_spec.rb
|
96
|
+
- spec/lib/mixpannenkoek/results/funnels_spec.rb
|
97
|
+
- spec/lib/mixpannenkoek/results_spec.rb
|
95
98
|
- spec/lib/mixpannenkoek_spec.rb
|
96
99
|
- spec/spec_helper.rb
|
97
100
|
homepage: https://github.com/Springest/mixpannenkoek
|
@@ -123,5 +126,8 @@ test_files:
|
|
123
126
|
- spec/lib/mixpannenkoek/base_spec.rb
|
124
127
|
- spec/lib/mixpannenkoek/class_inheritable_attributes_spec.rb
|
125
128
|
- spec/lib/mixpannenkoek/query_spec.rb
|
129
|
+
- spec/lib/mixpannenkoek/results/base_spec.rb
|
130
|
+
- spec/lib/mixpannenkoek/results/funnels_spec.rb
|
131
|
+
- spec/lib/mixpannenkoek/results_spec.rb
|
126
132
|
- spec/lib/mixpannenkoek_spec.rb
|
127
133
|
- spec/spec_helper.rb
|