metry 2.0.5 → 2.1.0
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.
- data/History.txt +4 -0
- data/Manifest.txt +12 -6
- data/Rakefile +5 -0
- data/TODO +1 -6
- data/example/example.rb +1 -1
- data/features/app_tracking.feature +1 -2
- data/features/basic_tracking.feature +19 -38
- data/features/psycho/dashboard.feature +3 -11
- data/features/psycho/experiments.feature +28 -0
- data/features/psycho/visitor_tracking.feature +4 -4
- data/features/step_definitions/experiments.rb +8 -0
- data/features/step_definitions/psycho.rb +14 -0
- data/features/step_definitions/tracking.rb +56 -24
- data/features/support/env.rb +0 -1
- data/features/support/helpers.rb +6 -0
- data/lib/metry.rb +12 -5
- data/lib/metry/cohort.rb +19 -0
- data/lib/metry/event.rb +26 -0
- data/lib/metry/experiment.rb +36 -13
- data/lib/metry/goal.rb +18 -0
- data/lib/metry/psycho.rb +24 -93
- data/lib/metry/psycho/dashboard.erb +5 -5
- data/lib/metry/psycho/edit_goal.erb +1 -1
- data/lib/metry/psycho/experiment.erb +25 -0
- data/lib/metry/psycho/new_goal.erb +1 -1
- data/lib/metry/psycho/visitor.erb +4 -1
- data/lib/metry/psycho/visitors.erb +6 -0
- data/lib/metry/rack/tracking.rb +19 -18
- data/lib/metry/visitor.rb +30 -0
- data/radiant/example/features/metry.feature +21 -43
- data/radiant/example/features/step_definitions/tracking.rb +56 -24
- data/radiant/example/features/step_definitions/web.rb +0 -7
- data/radiant/example/features/support/env.rb +7 -3
- data/radiant/example/features/support/helpers.rb +6 -0
- data/radiant/extension/lib/metry_tags.rb +3 -1
- data/test/shared.rb +3 -1
- data/test/test_experiment.rb +104 -0
- metadata +45 -9
- data/features/psycho/goals.feature +0 -53
- data/features/step_definitions/goals.rb +0 -3
- data/lib/metry/psycho/goal.erb +0 -9
- data/lib/metry/storage.rb +0 -142
- data/radiant/example/features/step_definitions/experiments.rb +0 -12
- data/test/test_storage.rb +0 -25
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -8,24 +8,30 @@ example/example.rb
|
|
8
8
|
features/app_tracking.feature
|
9
9
|
features/basic_tracking.feature
|
10
10
|
features/psycho/dashboard.feature
|
11
|
-
features/psycho/
|
11
|
+
features/psycho/experiments.feature
|
12
12
|
features/psycho/visitor_tracking.feature
|
13
13
|
features/sample_application.feature
|
14
|
-
features/step_definitions/
|
14
|
+
features/step_definitions/experiments.rb
|
15
|
+
features/step_definitions/psycho.rb
|
15
16
|
features/step_definitions/tracking.rb
|
16
17
|
features/step_definitions/web.rb
|
17
18
|
features/support/env.rb
|
19
|
+
features/support/helpers.rb
|
18
20
|
lib/metry.rb
|
21
|
+
lib/metry/cohort.rb
|
22
|
+
lib/metry/event.rb
|
19
23
|
lib/metry/experiment.rb
|
24
|
+
lib/metry/goal.rb
|
20
25
|
lib/metry/psycho.rb
|
21
26
|
lib/metry/psycho/dashboard.erb
|
22
27
|
lib/metry/psycho/edit_goal.erb
|
23
|
-
lib/metry/psycho/
|
28
|
+
lib/metry/psycho/experiment.erb
|
24
29
|
lib/metry/psycho/layout.erb
|
25
30
|
lib/metry/psycho/new_goal.erb
|
26
31
|
lib/metry/psycho/visitor.erb
|
32
|
+
lib/metry/psycho/visitors.erb
|
27
33
|
lib/metry/rack/tracking.rb
|
28
|
-
lib/metry/
|
34
|
+
lib/metry/visitor.rb
|
29
35
|
radiant/example/CHANGELOG
|
30
36
|
radiant/example/CONTRIBUTORS
|
31
37
|
radiant/example/INSTALL
|
@@ -43,11 +49,11 @@ radiant/example/config/routes.rb
|
|
43
49
|
radiant/example/db/schema.rb
|
44
50
|
radiant/example/features/metry.feature
|
45
51
|
radiant/example/features/psycho.feature
|
46
|
-
radiant/example/features/step_definitions/experiments.rb
|
47
52
|
radiant/example/features/step_definitions/radiant.rb
|
48
53
|
radiant/example/features/step_definitions/tracking.rb
|
49
54
|
radiant/example/features/step_definitions/web.rb
|
50
55
|
radiant/example/features/support/env.rb
|
56
|
+
radiant/example/features/support/helpers.rb
|
51
57
|
radiant/example/public/.htaccess
|
52
58
|
radiant/example/public/404.html
|
53
59
|
radiant/example/public/500.html
|
@@ -114,7 +120,7 @@ radiant/extension/lib/metry_tags.rb
|
|
114
120
|
radiant/extension/lib/tasks/metry_extension_tasks.rake
|
115
121
|
radiant/extension/metry_extension.rb
|
116
122
|
test/shared.rb
|
117
|
-
test/
|
123
|
+
test/test_experiment.rb
|
118
124
|
vendor/webrat/.document
|
119
125
|
vendor/webrat/History.txt
|
120
126
|
vendor/webrat/MIT-LICENSE.txt
|
data/Rakefile
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
+
ENV["RUBY_FLAGS"] = "-I#{%w(lib ext bin test).join(File::PATH_SEPARATOR)}"
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'hoe'
|
3
5
|
|
4
6
|
Hoe.spec 'metry' do
|
5
7
|
developer('Nathaniel Talbott', 'nathaniel@terralien.com')
|
6
8
|
self.rubyforge_name = 'terralien'
|
9
|
+
extra_deps << ['mongomapper', '~> 0.3']
|
10
|
+
extra_deps << ['mongodb-mongo', '~> 0.10']
|
11
|
+
extra_deps << ['mongodb-mongo_ext', '~> 0.4']
|
7
12
|
end
|
8
13
|
|
9
14
|
require 'cucumber/rake/task'
|
data/TODO
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
Limit visitors on dashboard to 10 most recent
|
2
|
-
Add full listing of visitors
|
3
|
-
Show more details about visitors
|
4
|
-
Add referrer to event display on visitor pages
|
5
|
-
Add display of last 10 events to dashboard
|
6
1
|
Show goal conversion for each experiment
|
7
|
-
Allow manually viewing a particular
|
2
|
+
Allow manually viewing a particular alternative
|
8
3
|
|
9
4
|
More unit tests
|
10
5
|
|
data/example/example.rb
CHANGED
@@ -6,6 +6,5 @@ Feature: Application Tracking
|
|
6
6
|
Scenario: Track an additional facet
|
7
7
|
Given an empty tracking database
|
8
8
|
When I view "/extra?track=stuff"
|
9
|
-
Then
|
10
|
-
| key | value |
|
9
|
+
Then tracking event #1 extra should contain:
|
11
10
|
| extra | stuff |
|
@@ -20,73 +20,54 @@ Feature: Access Tracking
|
|
20
20
|
Scenario: Basic request data is tracked
|
21
21
|
When I view "/"
|
22
22
|
And I view "/subpage"
|
23
|
-
Then
|
24
|
-
| key | value |
|
23
|
+
Then tracking event #1 should contain:
|
25
24
|
| path | / |
|
26
|
-
|
|
27
|
-
And
|
28
|
-
| key | value |
|
25
|
+
| created_at | _exists_ |
|
26
|
+
And tracking event #2 should contain:
|
29
27
|
| path | /subpage |
|
30
|
-
|
|
28
|
+
| created_at | _exists_ |
|
31
29
|
|
32
30
|
Scenario: New visitor is tracked
|
33
31
|
When I view "/"
|
34
32
|
And I view "/subpage"
|
35
|
-
Then there should be a tracking event
|
36
|
-
|
37
|
-
|
38
|
-
And there should be a tracking event "2":
|
39
|
-
| key | value |
|
40
|
-
| visitor | 1 |
|
41
|
-
And there should be a visitor "1"
|
33
|
+
Then there should be a tracking event #1 with visitor #1
|
34
|
+
And there should be a tracking event #2 with visitor #1
|
35
|
+
And there should be a visitor #1
|
42
36
|
|
43
37
|
Scenario: Two visitors are tracked
|
44
38
|
Given I view "/"
|
45
39
|
When I am a new visitor
|
46
40
|
Given I view "/"
|
47
|
-
Then there should be a tracking event
|
48
|
-
|
49
|
-
| visitor | 1 |
|
50
|
-
And there should be a tracking event "2":
|
51
|
-
| key | value |
|
52
|
-
| visitor | 2 |
|
41
|
+
Then there should be a tracking event #1 with visitor #1
|
42
|
+
Then there should be a tracking event #2 with visitor #2
|
53
43
|
And there should be 2 visitors
|
54
|
-
And there should be a visitor "1"
|
55
|
-
And there should be a visitor "2"
|
56
44
|
|
57
45
|
Scenario: All facets should be tracked
|
58
46
|
When I view "/"
|
59
|
-
Then
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
| host | example.org |
|
47
|
+
Then tracking event #1 should contain:
|
48
|
+
| path | / |
|
49
|
+
| created_at | _exists_ |
|
50
|
+
| ip | 127.0.0.1 |
|
51
|
+
| host | www.example.com |
|
65
52
|
|
66
53
|
Scenario: path should include query string
|
67
54
|
When I view "/?here=there"
|
68
|
-
Then
|
69
|
-
| key | value |
|
55
|
+
Then tracking event #1 should contain:
|
70
56
|
| path | /?here=there |
|
71
57
|
|
72
58
|
Scenario: Should track status codes
|
73
59
|
When I view "/"
|
74
60
|
And I view "/missing"
|
75
|
-
Then
|
76
|
-
| key | value |
|
61
|
+
Then tracking event #1 should contain:
|
77
62
|
| status | 200 |
|
78
|
-
Then
|
79
|
-
| key | value |
|
63
|
+
Then tracking event #2 should contain:
|
80
64
|
| status | 404 |
|
81
65
|
|
82
66
|
Scenario: Should track method
|
83
67
|
When I view "/"
|
84
68
|
And I post to "/post":
|
85
|
-
| key | value |
|
86
69
|
| bogus | bogus |
|
87
|
-
Then
|
88
|
-
| key | value |
|
70
|
+
Then tracking event #1 should contain:
|
89
71
|
| method | GET |
|
90
|
-
Then
|
91
|
-
| key | value |
|
72
|
+
Then tracking event #2 should contain:
|
92
73
|
| method | POST |
|
@@ -2,16 +2,8 @@ Feature: Psycho Dashboard
|
|
2
2
|
|
3
3
|
Scenario: Basics
|
4
4
|
Given an empty tracking database
|
5
|
-
And I add
|
6
|
-
And I am a new visitor
|
7
|
-
And I view "/"
|
8
|
-
And I view "/subpage"
|
9
|
-
And I am a new visitor
|
10
|
-
And I view "/"
|
5
|
+
And I add an experiment "sweet"
|
11
6
|
When I view "/admin/metry"
|
12
|
-
Then I should see "
|
13
|
-
And I should see "sweet
|
14
|
-
And I should see "Recent Visitors"
|
15
|
-
And I should see "Visitor 1"
|
16
|
-
And I should see "Visitor 2"
|
7
|
+
Then I should see "Experiments"
|
8
|
+
And I should see "sweet"
|
17
9
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Track Experiments
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given an empty tracking database
|
5
|
+
And I add an experiment "Fred"
|
6
|
+
|
7
|
+
Scenario: Add a goal
|
8
|
+
Given I view "/admin/metry"
|
9
|
+
And I follow "Fred"
|
10
|
+
And I follow "New Goal"
|
11
|
+
And I fill in "name" with "Cool"
|
12
|
+
And I fill in "path" with "/goal"
|
13
|
+
And I press "Create"
|
14
|
+
Then I should be on the page for experiment #1
|
15
|
+
And I should see "Cool"
|
16
|
+
And I should see "Path: /goal"
|
17
|
+
|
18
|
+
Scenario: Edit a Goal
|
19
|
+
Given I add a goal named "Bogus" to experiment "Fred" with path "/"
|
20
|
+
When I view "/admin/metry"
|
21
|
+
And I follow "Fred"
|
22
|
+
And I follow "Edit"
|
23
|
+
And I fill in "name" with "Right"
|
24
|
+
And I fill in "path" with "/subpage"
|
25
|
+
And I press "Save"
|
26
|
+
Then I should be on the page for experiment #1
|
27
|
+
And I should see "Right"
|
28
|
+
And I should see "Path: /subpage"
|
@@ -12,8 +12,8 @@ Feature: Psycho Visitor Tracking
|
|
12
12
|
And I am a new visitor
|
13
13
|
And I view "/"
|
14
14
|
When I view "/admin/metry"
|
15
|
-
Then I should see
|
16
|
-
And I should see
|
15
|
+
Then I should see visitor #1
|
16
|
+
And I should see visitor #2
|
17
17
|
|
18
18
|
Scenario: View visitor detail
|
19
19
|
Given I view "/"
|
@@ -21,7 +21,7 @@ Feature: Psycho Visitor Tracking
|
|
21
21
|
And I am a new visitor
|
22
22
|
And I view "/"
|
23
23
|
When I view "/admin/metry"
|
24
|
-
And I follow "Visitor
|
24
|
+
And I follow "Visitor"
|
25
25
|
Then I should see "/"
|
26
26
|
And I should see "/subpage"
|
27
27
|
|
@@ -29,4 +29,4 @@ Feature: Psycho Visitor Tracking
|
|
29
29
|
Given I view "/admin/metry"
|
30
30
|
And I view "/admin/metry"
|
31
31
|
When I view "/admin/metry"
|
32
|
-
Then I should
|
32
|
+
Then I should see "0 events"
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Given /^I add an experiment "([^\"]*)"$/ do |name|
|
2
|
+
Metry::Experiment.create(:name => name)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^I add a goal named "([^\"]*)" to experiment "([^\"]*)" with path "([^\"]*)"$/ do |name, experiment, path|
|
6
|
+
experiment = Metry::Experiment.find(:first, :conditions => {:name => experiment})
|
7
|
+
experiment.goals << Metry::Goal.create(:name => name, :path => path)
|
8
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Then /^I should see visitor #(\d+)$/ do |index|
|
2
|
+
visitor = at(Metry::Visitor, index)
|
3
|
+
assert_contain "Visitor #{visitor.id}"
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^I should not see visitor #(\d+)$/ do |index|
|
7
|
+
visitor = at(Metry::Visitor, index)
|
8
|
+
assert_not_contain "Visitor #{visitor.id}"
|
9
|
+
end
|
10
|
+
|
11
|
+
Then /^I should be on the page for experiment #(\d+)$/ do |index|
|
12
|
+
experiment = at(Metry::Experiment, index)
|
13
|
+
assert_equal "/admin/metry/experiments/#{experiment.id}", current_url
|
14
|
+
end
|
@@ -1,43 +1,75 @@
|
|
1
1
|
Given /^an empty tracking database$/ do
|
2
|
-
Metry.
|
2
|
+
Metry.clear
|
3
3
|
end
|
4
4
|
|
5
5
|
Then /^there should be (\d+) tracking events?$/ do |event_count|
|
6
|
-
assert_equal(event_count.to_i, Metry.
|
6
|
+
assert_equal(event_count.to_i, Metry::Event.count)
|
7
7
|
end
|
8
8
|
|
9
9
|
Then /^there should be (\d+) visitors$/ do |visitor_count|
|
10
|
-
assert_equal(visitor_count.to_i, Metry.
|
10
|
+
assert_equal(visitor_count.to_i, Metry::Visitor.count)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
event = Metry
|
15
|
-
assert event, "Unable to lookup event #{
|
16
|
-
table.
|
17
|
-
expected = hash["value"]
|
13
|
+
Then /^tracking event #(\d+) should contain:$/ do |index, table|
|
14
|
+
event = at(Metry::Event, index)
|
15
|
+
assert event, "Unable to lookup event at #{index}."
|
16
|
+
table.rows_hash.each do |key, expected|
|
18
17
|
case expected
|
19
18
|
when "_exists_"
|
20
|
-
assert event
|
19
|
+
assert event.send(key), "Key #{key} does not exist."
|
21
20
|
else
|
22
|
-
assert_equal expected, event
|
21
|
+
assert_equal expected, event.send(key), "Key #{key} does not match."
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
27
|
-
Then /^
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
expected = hash["value"]
|
32
|
-
case expected
|
33
|
-
when "_exists_"
|
34
|
-
assert visitor[hash["key"]], "Key #{hash["key"]} does not exist."
|
35
|
-
else
|
36
|
-
assert_equal expected, visitor[hash["key"]], "Key #{hash["key"]} does not match."
|
37
|
-
end
|
26
|
+
Then /^tracking event #(\d+) extra should contain:$/ do |index, table|
|
27
|
+
event = at(Metry::Event, index)
|
28
|
+
table.rows_hash.each do |key, expected|
|
29
|
+
assert_equal expected, event.extra[key]
|
38
30
|
end
|
39
31
|
end
|
40
32
|
|
41
|
-
Then /^there should be a visitor
|
42
|
-
|
43
|
-
|
33
|
+
Then /^there should be a tracking event #(\d+) with visitor #(\d+)$/ do |event_index, visitor_index|
|
34
|
+
event = at(Metry::Event, event_index)
|
35
|
+
visitor = at(Metry::Visitor, visitor_index)
|
36
|
+
assert_equal event.visitor, visitor
|
37
|
+
end
|
38
|
+
|
39
|
+
Then /^there should be a visitor #(\d+)$/ do |index|
|
40
|
+
assert at(Metry::Visitor, index)
|
41
|
+
end
|
42
|
+
|
43
|
+
Then /^visitor #(\d+) should have experiment "([^\"]*)" with "([^\"]*)"$/ do |index, experiment, alternative|
|
44
|
+
visitor = at(Metry::Visitor, index)
|
45
|
+
experiment = Metry::Experiment.find(:first, :conditions => {:name => experiment})
|
46
|
+
assert experiment.cohort_for(visitor)
|
47
|
+
end
|
48
|
+
|
49
|
+
Then /^event #(\d+) should have experiment "([^\"]*)" with "([^\"]*)"$/ do |index, experiment, alternative|
|
50
|
+
event = at(Metry::Event, index)
|
51
|
+
experiment = Metry::Experiment.find(:first, :conditions => {:name => experiment})
|
52
|
+
assert_equal alternative, event.experiments[experiment.id]
|
53
|
+
end
|
54
|
+
|
55
|
+
Then /^I should see the same page (\d+) times$/ do |count|
|
56
|
+
expected_body = webrat.response_body
|
57
|
+
count.to_i.times do
|
58
|
+
When(%(I view "#{current_url}"))
|
59
|
+
assert_equal expected_body, webrat.response_body
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
When /^(\d+) visitors view "([^\"]*)"$/ do |count, path|
|
64
|
+
@alternatives = Hash.new(0)
|
65
|
+
count.to_i.times do
|
66
|
+
visit(path)
|
67
|
+
@alternatives[webrat.response_body] += 1
|
68
|
+
clear_cookies
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
Then /^there should be (\d+) alternatives each displayed at least (\d+) times$/ do |alternatives, minimum|
|
73
|
+
assert_equal alternatives.to_i, @alternatives.size
|
74
|
+
assert @alternatives.values.all?{|e| e >= minimum.to_i}
|
75
|
+
end
|
data/features/support/env.rb
CHANGED
data/lib/metry.rb
CHANGED
@@ -1,18 +1,25 @@
|
|
1
1
|
$: << File.dirname(__FILE__)
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'mongomapper'
|
4
|
+
|
5
|
+
require 'metry/event'
|
6
|
+
require 'metry/visitor'
|
7
|
+
require 'metry/goal'
|
4
8
|
require 'metry/rack/tracking'
|
5
9
|
require 'metry/experiment'
|
10
|
+
require 'metry/cohort'
|
6
11
|
require 'metry/psycho'
|
7
12
|
|
8
13
|
module Metry
|
9
|
-
VERSION = '2.0
|
14
|
+
VERSION = '2.1.0'
|
10
15
|
|
11
16
|
def self.init(dbname)
|
12
|
-
|
17
|
+
MongoMapper.database = dbname
|
13
18
|
end
|
14
19
|
|
15
|
-
def self.
|
16
|
-
|
20
|
+
def self.clear
|
21
|
+
[Metry::Event, Metry::Visitor, Metry::Goal, Metry::Experiment].each do |m|
|
22
|
+
m.delete_all
|
23
|
+
end
|
17
24
|
end
|
18
25
|
end
|