fabes 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.
- data/VERSION +1 -1
- data/fabes.gemspec +3 -2
- data/lib/fabes.rb +2 -7
- data/lib/fabes/admin/public/application.css +77 -11
- data/lib/fabes/admin/views/index.haml +12 -10
- data/lib/fabes/admin/views/layout.haml +3 -2
- data/lib/fabes/configuration.rb +11 -8
- data/lib/fabes/connection_adapters/abstract_adapter.rb +20 -6
- data/lib/fabes/connection_adapters/redis_adapter.rb +2 -2
- data/lib/fabes/experiment.rb +1 -1
- data/lib/fabes/railtie.rb +7 -0
- data/test/test_abstract_adapter.rb +4 -6
- data/test/test_configuration.rb +25 -10
- data/test/test_redis_adapter.rb +1 -0
- metadata +4 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/fabes.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "fabes"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alejandro Andres"]
|
12
|
-
s.date = "2012-07-
|
12
|
+
s.date = "2012-07-25"
|
13
13
|
s.description = "Fabes is an A/B testing system for your ruby projects"
|
14
14
|
s.email = "fuzzy.alej@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -39,6 +39,7 @@ Gem::Specification.new do |s|
|
|
39
39
|
"lib/fabes/connection_handling.rb",
|
40
40
|
"lib/fabes/experiment.rb",
|
41
41
|
"lib/fabes/helper.rb",
|
42
|
+
"lib/fabes/railtie.rb",
|
42
43
|
"lib/fabes/utils.rb",
|
43
44
|
"test/helper.rb",
|
44
45
|
"test/test_abstract_adapter.rb",
|
data/lib/fabes.rb
CHANGED
@@ -17,15 +17,10 @@ module Fabes
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def db
|
20
|
-
@db ||= ConnectionHandling.establish_connection Fabes.configuration.
|
20
|
+
@db ||= ConnectionHandling.establish_connection Fabes.configuration.database
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
Fabes.configure
|
25
25
|
|
26
|
-
if defined? Rails
|
27
|
-
ActionController::Base.send :include, Fabes::Helper
|
28
|
-
ActionController::Base.helper Fabes::Helper
|
29
|
-
#TODO: Autoadd route to admin panel
|
30
|
-
#TODO: Railtie???
|
31
|
-
end
|
26
|
+
require 'fabes/railtie' if defined? Rails
|
@@ -1,7 +1,8 @@
|
|
1
1
|
body {
|
2
|
-
font:
|
3
|
-
|
4
|
-
|
2
|
+
font-family: 'trebuchet MS', 'Lucida sans', Arial, sans-serif;
|
3
|
+
font-size: 14px;
|
4
|
+
color: #3b3b3b;
|
5
|
+
background-image: url('http://subtlepatterns.com/patterns/fabric_plaid.png');
|
5
6
|
}
|
6
7
|
|
7
8
|
a {
|
@@ -18,38 +19,103 @@ h2.span {
|
|
18
19
|
font-size: 16px;
|
19
20
|
}
|
20
21
|
|
22
|
+
#logo {
|
23
|
+
margin-bottom: 25px;
|
24
|
+
}
|
25
|
+
|
26
|
+
#logo h1 {
|
27
|
+
font-family: Arial, sans-serif;
|
28
|
+
font-size: 75px;
|
29
|
+
margin: 25px 0 0 0;
|
30
|
+
color: #504f4f;
|
31
|
+
text-shadow: 0px 2px 1px #bbbaba;
|
32
|
+
}
|
33
|
+
|
34
|
+
#logo span {
|
35
|
+
text-shadow: 0px 1px 1px #bbbaba;
|
36
|
+
}
|
37
|
+
|
21
38
|
table {
|
22
39
|
width: 700px;
|
23
40
|
padding: 0px;
|
24
41
|
margin: 0px;
|
42
|
+
border: solid 1px #999;
|
43
|
+
*border-collapse: collapse;
|
44
|
+
border-spacing: 0;
|
45
|
+
border-radius: 6px;
|
46
|
+
-moz-border-radius: 6px;
|
47
|
+
-wekit-border-radius: 6px;
|
48
|
+
box-shadow: 0 1px 1px #999;
|
49
|
+
-webkit-box-shadow: 0 1px 1px #999;
|
50
|
+
-moz-box-shadow: 0 1px 1px #999;
|
25
51
|
}
|
26
52
|
|
27
53
|
th {
|
28
|
-
border-right: 1px solid #A64C2E;
|
29
|
-
border-bottom: 1px solid #A64C2E;
|
30
|
-
border-top: 1px solid #D53500;
|
31
|
-
border-left: 1px solid #D53500;
|
32
54
|
letter-spacing: 2px;
|
33
55
|
text-transform: uppercase;
|
34
56
|
text-align: center;
|
35
57
|
font-size: 13px;
|
36
58
|
padding: 10px;
|
37
|
-
background: #C63D0F;
|
38
59
|
color: #FFFFFF;
|
60
|
+
background-color: #C63D0F;
|
61
|
+
background-image: linear-gradient(top, #c63d0f, #6f1b00);
|
62
|
+
background-image: -webkit-linear-gradient(top, #c63d0f, #6f1b00);
|
63
|
+
background-image: -moz-linear-gradient(top, #c63d0f, #6f1b00);
|
39
64
|
text-shadow: 1px 1px 1px black;
|
65
|
+
box-shadow: 0 1px 0 rgba(255, 200, 200, .8) inset;
|
66
|
+
-moz-box-shadow: 0 1px 0 rgba(255, 200, 200, .8) inset;
|
67
|
+
-webkit-box-shadow: 0 1px 0 rgba(255, 200, 200, .8) inset;
|
68
|
+
}
|
69
|
+
|
70
|
+
th:first-child {
|
71
|
+
background-color: #C63D0F;
|
72
|
+
background-image: linear-gradient(top, #c63d0f, #6f1b00)
|
73
|
+
background-image: -webkit-linear-gradient(top, #c63d0f, #6f1b00);
|
74
|
+
background-image: -moz-linear-gradient(top, #c63d0f, #6f1b00);
|
75
|
+
-moz-border-radius: 6px 0 0 0;
|
76
|
+
-webkit-border-radius: 6px 0 0 0;
|
77
|
+
border-radius: 6px 0 0 0;
|
78
|
+
}
|
79
|
+
|
80
|
+
th:last-child {
|
81
|
+
-moz-border-radius: 0 6px 0 0;
|
82
|
+
-webkit-border-radius: 0 6px 0 0;
|
83
|
+
border-radius: 0 6px 0 0;
|
40
84
|
}
|
41
85
|
|
42
86
|
td {
|
43
87
|
border-right: 1px solid #C1DAD7;
|
44
88
|
border-bottom: 1px solid #C1DAD7;
|
45
|
-
background: #FDF3E7;
|
46
89
|
padding: 6px;
|
47
90
|
color: #3B3738;
|
48
|
-
|
91
|
+
}
|
92
|
+
|
93
|
+
td:first-child {
|
94
|
+
font-weight: bold;
|
95
|
+
}
|
96
|
+
|
97
|
+
tr {
|
98
|
+
background: white;
|
99
|
+
}
|
100
|
+
|
101
|
+
tr:last-child td:first-child {
|
102
|
+
border-radius: 0 0 0 6px;
|
103
|
+
-moz-border-radius: 0 0 0 6px;
|
104
|
+
-webkit-border-radius: 0 0 0 6px;
|
105
|
+
}
|
106
|
+
|
107
|
+
tr:last-child td:last-child {
|
108
|
+
border-radius: 0 0 6px 0;
|
109
|
+
-moz-border-radius: 0 0 6px 0;
|
110
|
+
-webkit-border-radius: 0 0 6px 0;
|
111
|
+
}
|
112
|
+
|
113
|
+
tr:hover {
|
114
|
+
background: #FBF8E9;
|
49
115
|
}
|
50
116
|
|
51
117
|
#container {
|
52
|
-
margin:
|
118
|
+
margin: 0 auto;
|
53
119
|
text-align: center;
|
54
120
|
overflow: hidden;
|
55
121
|
}
|
@@ -4,14 +4,16 @@
|
|
4
4
|
.experiment
|
5
5
|
%h2= "Experiment: #{name.capitalize}"
|
6
6
|
%table{id: name.first, cellspacing: 0, summary: "Data for experiment '#{name}'"}
|
7
|
-
%
|
8
|
-
%th{scope: 'col'} Alternative
|
9
|
-
%th{scope: 'col'} Participants
|
10
|
-
%th{scope: 'col'} Hits
|
11
|
-
%th{scope: 'col'} Weight
|
12
|
-
- experiment.alternatives.each do |alternative|
|
7
|
+
%thead
|
13
8
|
%tr
|
14
|
-
%
|
15
|
-
%
|
16
|
-
%
|
17
|
-
%
|
9
|
+
%th{scope: 'col'} Alternative
|
10
|
+
%th{scope: 'col'} Participants
|
11
|
+
%th{scope: 'col'} Hits
|
12
|
+
%th{scope: 'col'} Weight
|
13
|
+
%tbody
|
14
|
+
- experiment.alternatives.each do |alternative|
|
15
|
+
%tr
|
16
|
+
%td{title: alternative.id}= alternative.payload
|
17
|
+
%td= alternative.participants
|
18
|
+
%td= alternative.hits
|
19
|
+
%td= alternative.weight
|
data/lib/fabes/configuration.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
module Fabes
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :database, :factor
|
4
4
|
|
5
5
|
def initialize
|
6
|
-
@
|
7
|
-
@
|
6
|
+
@database = ENV['FABES_DB_URL'] || ENV['REDISTOGO_URL']
|
7
|
+
@factor = 0.1
|
8
8
|
end
|
9
9
|
|
10
|
-
def use(
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def use(options)
|
11
|
+
@database = options[:database] || options [:db]
|
12
|
+
rescue
|
13
|
+
@database = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def bandit_factor(percentage)
|
17
|
+
@factor = percentage
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
@@ -1,17 +1,31 @@
|
|
1
1
|
module Fabes
|
2
2
|
module ConnectionHandling
|
3
|
+
require 'ostruct'
|
3
4
|
extend self
|
4
5
|
|
5
|
-
def establish_connection(db
|
6
|
-
|
7
|
-
|
6
|
+
def establish_connection(db)
|
7
|
+
database = connection_url_to_hash(db)
|
8
|
+
adapter = database.delete :adapter
|
8
9
|
adapter_method = "#{adapter}_connection"
|
9
|
-
send adapter_method,
|
10
|
-
rescue
|
10
|
+
send adapter_method, database
|
11
|
+
rescue
|
11
12
|
raise "Could not find #{adapter} adapter!"
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
+
#from https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/connection_specification.rb#L65
|
16
|
+
def connection_url_to_hash(url)
|
17
|
+
url ||= ''
|
18
|
+
uri = URI.parse url
|
19
|
+
spec = {
|
20
|
+
host: uri.host,
|
21
|
+
port: uri.port,
|
22
|
+
adapter: uri.scheme,
|
23
|
+
username: uri.user,
|
24
|
+
password: uri.password,
|
25
|
+
database: uri.path.sub(%r{^/}, '')
|
26
|
+
}
|
27
|
+
spec.reject! {|_, value| !value}
|
28
|
+
{adapter: 'redis'}.merge spec
|
15
29
|
end
|
16
30
|
end
|
17
31
|
|
data/lib/fabes/experiment.rb
CHANGED
@@ -4,17 +4,15 @@ class TestAbstractAdapter < Test::Unit::TestCase
|
|
4
4
|
context 'establish_connection' do
|
5
5
|
should 'raise if no suitable adapter' do
|
6
6
|
assert_raise RuntimeError do
|
7
|
-
|
8
|
-
db
|
9
|
-
Fabes::ConnectionHandling.establish_connection(db, adapter)
|
7
|
+
db = 'http://uno:dos@tres.com:123/'
|
8
|
+
Fabes::ConnectionHandling.establish_connection(db)
|
10
9
|
end
|
11
10
|
end
|
12
11
|
|
13
12
|
should 'work if suitable adapter (redis)' do
|
14
|
-
|
15
|
-
db = ''
|
13
|
+
db = 'redis://uno:dos@tres.com:123/'
|
16
14
|
Fabes::ConnectionHandling.expects :redis_connection
|
17
|
-
Fabes::ConnectionHandling.establish_connection(db
|
15
|
+
Fabes::ConnectionHandling.establish_connection(db)
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
data/test/test_configuration.rb
CHANGED
@@ -2,9 +2,14 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TestConfiguration < Test::Unit::TestCase
|
4
4
|
context 'initialization' do
|
5
|
-
should 'have
|
5
|
+
should 'have a database' do
|
6
6
|
configuration = Fabes::Configuration.new
|
7
|
-
assert configuration.respond_to? :
|
7
|
+
assert configuration.respond_to? :database
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'have a factor' do
|
11
|
+
configuration = Fabes::Configuration.new
|
12
|
+
assert configuration.respond_to? :factor
|
8
13
|
end
|
9
14
|
end
|
10
15
|
|
@@ -14,20 +19,30 @@ class TestConfiguration < Test::Unit::TestCase
|
|
14
19
|
assert configuration.respond_to? :use
|
15
20
|
end
|
16
21
|
|
17
|
-
should '
|
22
|
+
should 'have a factor command' do
|
23
|
+
configuration = Fabes::Configuration.new
|
24
|
+
assert configuration.respond_to? :factor
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'set the database' do
|
28
|
+
configuration = Fabes.configure do |c|
|
29
|
+
c.use database: 'redis://user:pwd@host.com:123/'
|
30
|
+
end
|
31
|
+
assert_not_nil configuration.instance_variable_get :@database
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'nilify the db with bad configuration' do
|
18
35
|
configuration = Fabes.configure do |c|
|
19
|
-
c.use
|
36
|
+
c.use fail: 'redis://user:pwd@host.com:123/'
|
20
37
|
end
|
21
|
-
|
22
|
-
assert_equal configuration.instance_variable_get(:@adapter), 'redis'
|
38
|
+
assert_nil configuration.instance_variable_get :@database
|
23
39
|
end
|
24
40
|
|
25
|
-
should 'set the
|
41
|
+
should 'set the factor' do
|
26
42
|
configuration = Fabes.configure do |c|
|
27
|
-
c.
|
43
|
+
c.bandit_factor 0.25
|
28
44
|
end
|
29
|
-
|
30
|
-
assert_equal configuration.instance_variable_get(:@db), 'abc'
|
45
|
+
assert_equal configuration.factor, 0.25
|
31
46
|
end
|
32
47
|
end
|
33
48
|
end
|
data/test/test_redis_adapter.rb
CHANGED
@@ -15,6 +15,7 @@ class TestRedisAdapter < Test::Unit::TestCase
|
|
15
15
|
setup do
|
16
16
|
@db = Redis.new
|
17
17
|
@adapter = Fabes::ConnectionAdapters::RedisAdapter.new(@db)
|
18
|
+
Fabes.stubs(:db).returns(@adapter)
|
18
19
|
@experiment = Fabes::Experiment.new 'test', 'a', 'b', 'c'
|
19
20
|
@adapter.save_experiment(@experiment)
|
20
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fabes
|
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:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -185,6 +185,7 @@ files:
|
|
185
185
|
- lib/fabes/connection_handling.rb
|
186
186
|
- lib/fabes/experiment.rb
|
187
187
|
- lib/fabes/helper.rb
|
188
|
+
- lib/fabes/railtie.rb
|
188
189
|
- lib/fabes/utils.rb
|
189
190
|
- test/helper.rb
|
190
191
|
- test/test_abstract_adapter.rb
|
@@ -208,7 +209,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
208
209
|
version: '0'
|
209
210
|
segments:
|
210
211
|
- 0
|
211
|
-
hash:
|
212
|
+
hash: 3698846090476597919
|
212
213
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
213
214
|
none: false
|
214
215
|
requirements:
|