vanity 3.1.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/linting.yml +28 -0
- data/.github/workflows/test.yml +3 -6
- data/.rubocop.yml +114 -0
- data/.rubocop_todo.yml +67 -0
- data/Appraisals +9 -31
- data/CHANGELOG +5 -0
- data/Gemfile +7 -3
- data/Gemfile.lock +31 -3
- data/README.md +4 -9
- data/Rakefile +25 -24
- data/bin/vanity +1 -1
- data/doc/configuring.textile +1 -0
- data/gemfiles/rails52.gemfile +6 -3
- data/gemfiles/rails52.gemfile.lock +34 -9
- data/gemfiles/rails60.gemfile +6 -3
- data/gemfiles/rails60.gemfile.lock +34 -9
- data/gemfiles/rails61.gemfile +6 -3
- data/gemfiles/rails61.gemfile.lock +34 -9
- data/lib/generators/vanity/migration_generator.rb +5 -7
- data/lib/vanity/adapters/abstract_adapter.rb +43 -45
- data/lib/vanity/adapters/active_record_adapter.rb +30 -30
- data/lib/vanity/adapters/mock_adapter.rb +14 -18
- data/lib/vanity/adapters/mongodb_adapter.rb +73 -69
- data/lib/vanity/adapters/redis_adapter.rb +19 -27
- data/lib/vanity/adapters.rb +1 -1
- data/lib/vanity/autoconnect.rb +6 -7
- data/lib/vanity/commands/list.rb +7 -7
- data/lib/vanity/commands/report.rb +18 -22
- data/lib/vanity/configuration.rb +19 -19
- data/lib/vanity/connection.rb +12 -14
- data/lib/vanity/experiment/ab_test.rb +82 -70
- data/lib/vanity/experiment/alternative.rb +3 -5
- data/lib/vanity/experiment/base.rb +24 -19
- data/lib/vanity/experiment/bayesian_bandit_score.rb +7 -13
- data/lib/vanity/experiment/definition.rb +6 -6
- data/lib/vanity/frameworks/rails.rb +39 -39
- data/lib/vanity/frameworks.rb +2 -2
- data/lib/vanity/helpers.rb +1 -1
- data/lib/vanity/metric/active_record.rb +21 -19
- data/lib/vanity/metric/base.rb +22 -23
- data/lib/vanity/metric/google_analytics.rb +6 -9
- data/lib/vanity/metric/remote.rb +3 -5
- data/lib/vanity/playground.rb +3 -6
- data/lib/vanity/vanity.rb +8 -12
- data/lib/vanity/version.rb +1 -1
- data/test/adapters/active_record_adapter_test.rb +1 -5
- data/test/adapters/mock_adapter_test.rb +0 -2
- data/test/adapters/mongodb_adapter_test.rb +1 -5
- data/test/adapters/redis_adapter_test.rb +2 -3
- data/test/adapters/shared_tests.rb +9 -12
- data/test/autoconnect_test.rb +3 -3
- data/test/cli_test.rb +0 -1
- data/test/configuration_test.rb +18 -34
- data/test/connection_test.rb +3 -3
- data/test/dummy/Rakefile +1 -1
- data/test/dummy/app/controllers/use_vanity_controller.rb +12 -8
- data/test/dummy/app/mailers/vanity_mailer.rb +3 -3
- data/test/dummy/config/application.rb +1 -1
- data/test/dummy/config/boot.rb +3 -3
- data/test/dummy/config/environment.rb +1 -1
- data/test/dummy/config/environments/development.rb +0 -1
- data/test/dummy/config/environments/test.rb +1 -1
- data/test/dummy/config/initializers/session_store.rb +1 -1
- data/test/dummy/config.ru +1 -1
- data/test/dummy/script/rails +2 -2
- data/test/experiment/ab_test.rb +148 -154
- data/test/experiment/base_test.rb +48 -32
- data/test/frameworks/rails/action_controller_test.rb +25 -25
- data/test/frameworks/rails/action_mailer_test.rb +2 -2
- data/test/frameworks/rails/action_view_test.rb +5 -6
- data/test/frameworks/rails/rails_test.rb +147 -181
- data/test/helper_test.rb +2 -2
- data/test/metric/active_record_test.rb +174 -212
- data/test/metric/base_test.rb +21 -46
- data/test/metric/google_analytics_test.rb +17 -25
- data/test/metric/remote_test.rb +7 -10
- data/test/playground_test.rb +7 -14
- data/test/templates_test.rb +16 -20
- data/test/test_helper.rb +28 -29
- data/test/vanity_test.rb +4 -10
- data/test/web/rails/dashboard_test.rb +21 -21
- data/vanity.gemspec +8 -7
- metadata +28 -30
- data/gemfiles/rails42.gemfile +0 -33
- data/gemfiles/rails42.gemfile.lock +0 -265
- data/gemfiles/rails42_protected_attributes.gemfile +0 -34
- data/gemfiles/rails42_protected_attributes.gemfile.lock +0 -264
- data/gemfiles/rails51.gemfile +0 -33
- data/gemfiles/rails51.gemfile.lock +0 -285
@@ -6,9 +6,10 @@ module Vanity
|
|
6
6
|
# @since 1.4.0
|
7
7
|
def redis_connection(spec)
|
8
8
|
require "redis"
|
9
|
-
|
9
|
+
raise "redis >= 2.1 is required" unless valid_redis_version?
|
10
|
+
|
10
11
|
require "redis/namespace"
|
11
|
-
|
12
|
+
raise "redis-namespace >= 1.1.0 is required" unless valid_redis_namespace_version?
|
12
13
|
|
13
14
|
RedisAdapter.new(spec)
|
14
15
|
end
|
@@ -28,7 +29,7 @@ module Vanity
|
|
28
29
|
class RedisAdapter < AbstractAdapter
|
29
30
|
attr_reader :redis
|
30
31
|
|
31
|
-
def initialize(options)
|
32
|
+
def initialize(options) # rubocop:todo Lint/MissingSuper
|
32
33
|
@options = options.clone
|
33
34
|
@options[:db] ||= @options[:database] || (@options[:path] && @options.delete(:path).split("/")[1].to_i)
|
34
35
|
@options[:thread_safe] = true
|
@@ -40,9 +41,7 @@ module Vanity
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def disconnect!
|
43
|
-
if redis
|
44
|
-
redis.disconnect!
|
45
|
-
end
|
44
|
+
redis.disconnect! if redis
|
46
45
|
@redis = nil
|
47
46
|
end
|
48
47
|
|
@@ -53,8 +52,8 @@ module Vanity
|
|
53
52
|
|
54
53
|
def connect!
|
55
54
|
@redis = @options[:redis] || Redis.new(@options)
|
56
|
-
@metrics = Redis::Namespace.new("vanity:metrics", :redis
|
57
|
-
@experiments = Redis::Namespace.new("vanity:experiments", :redis
|
55
|
+
@metrics = Redis::Namespace.new("vanity:metrics", redis: redis)
|
56
|
+
@experiments = Redis::Namespace.new("vanity:experiments", redis: redis)
|
58
57
|
end
|
59
58
|
|
60
59
|
def to_s
|
@@ -74,7 +73,7 @@ module Vanity
|
|
74
73
|
|
75
74
|
def metric_track(metric, timestamp, identity, values)
|
76
75
|
call_redis_with_failover(metric, timestamp, identity, values) do
|
77
|
-
values.each_with_index do |v,i|
|
76
|
+
values.each_with_index do |v, i|
|
78
77
|
@metrics.incrby "#{metric}:#{timestamp.to_date}:value:#{i}", v
|
79
78
|
end
|
80
79
|
@metrics.set("#{metric}:last_update_at", Time.now.to_i)
|
@@ -90,7 +89,6 @@ module Vanity
|
|
90
89
|
@metrics.del(*@metrics.keys("#{metric}:*"))
|
91
90
|
end
|
92
91
|
|
93
|
-
|
94
92
|
# -- Experiments --
|
95
93
|
|
96
94
|
def experiment_persisted?(experiment)
|
@@ -117,7 +115,7 @@ module Vanity
|
|
117
115
|
completed_at && Time.at(completed_at.to_i)
|
118
116
|
end
|
119
117
|
|
120
|
-
def is_experiment_completed?(experiment)
|
118
|
+
def is_experiment_completed?(experiment) # rubocop:todo Naming/PredicateName
|
121
119
|
call_redis_with_failover do
|
122
120
|
@experiments.exists("#{experiment}:completed_at")
|
123
121
|
end
|
@@ -129,7 +127,7 @@ module Vanity
|
|
129
127
|
end
|
130
128
|
end
|
131
129
|
|
132
|
-
def is_experiment_enabled?(experiment)
|
130
|
+
def is_experiment_enabled?(experiment) # rubocop:todo Naming/PredicateName
|
133
131
|
value = @experiments.get("#{experiment}:enabled")
|
134
132
|
if Vanity.configuration.experiments_start_enabled
|
135
133
|
value != 'false'
|
@@ -140,9 +138,9 @@ module Vanity
|
|
140
138
|
|
141
139
|
def ab_counts(experiment, alternative)
|
142
140
|
{
|
143
|
-
:
|
144
|
-
:
|
145
|
-
:
|
141
|
+
participants: @experiments.scard("#{experiment}:alts:#{alternative}:participants").to_i,
|
142
|
+
converted: @experiments.scard("#{experiment}:alts:#{alternative}:converted").to_i,
|
143
|
+
conversions: @experiments.get("#{experiment}:alts:#{alternative}:conversions").to_i,
|
146
144
|
}
|
147
145
|
end
|
148
146
|
|
@@ -174,11 +172,7 @@ module Vanity
|
|
174
172
|
def ab_seen(experiment, identity, alternative_or_id)
|
175
173
|
with_ab_seen_deprecation(experiment, identity, alternative_or_id) do |expt, ident, alt_id|
|
176
174
|
call_redis_with_failover(expt, ident, alt_id) do
|
177
|
-
if @experiments.sismember "#{expt}:alts:#{alt_id}:participants", ident
|
178
|
-
alt_id
|
179
|
-
else
|
180
|
-
nil
|
181
|
-
end
|
175
|
+
alt_id if @experiments.sismember "#{expt}:alts:#{alt_id}:participants", ident
|
182
176
|
end
|
183
177
|
end
|
184
178
|
end
|
@@ -187,9 +181,7 @@ module Vanity
|
|
187
181
|
def ab_assigned(experiment, identity)
|
188
182
|
call_redis_with_failover do
|
189
183
|
Vanity.playground.experiments[experiment].alternatives.each do |alternative|
|
190
|
-
if @experiments.sismember "#{experiment}:alts:#{alternative.id}:participants", identity
|
191
|
-
return alternative.id
|
192
|
-
end
|
184
|
+
return alternative.id if @experiments.sismember "#{experiment}:alts:#{alternative.id}:participants", identity
|
193
185
|
end
|
194
186
|
nil
|
195
187
|
end
|
@@ -219,7 +211,7 @@ module Vanity
|
|
219
211
|
def destroy_experiment(experiment)
|
220
212
|
cursor = nil
|
221
213
|
|
222
|
-
while cursor != "0"
|
214
|
+
while cursor != "0"
|
223
215
|
cursor, keys = @experiments.scan(cursor || "0", match: "#{experiment}:*")
|
224
216
|
|
225
217
|
@experiments.del(*keys) unless keys.empty?
|
@@ -229,11 +221,11 @@ module Vanity
|
|
229
221
|
protected
|
230
222
|
|
231
223
|
def call_redis_with_failover(*arguments)
|
232
|
-
calling_method = caller[
|
224
|
+
calling_method = caller(1..1).first[/`.*'/][1..-2]
|
233
225
|
begin
|
234
226
|
yield
|
235
|
-
rescue => e
|
236
|
-
if Vanity.configuration.failover_on_datastore_error
|
227
|
+
rescue StandardError => e
|
228
|
+
if Vanity.configuration.failover_on_datastore_error # rubocop:todo Style/GuardClause
|
237
229
|
Vanity.configuration.on_datastore_error.call(e, self.class, calling_method, arguments)
|
238
230
|
else
|
239
231
|
raise e
|
data/lib/vanity/adapters.rb
CHANGED
data/lib/vanity/autoconnect.rb
CHANGED
@@ -2,8 +2,7 @@ module Vanity
|
|
2
2
|
# A singleton responsible for determining if the playground should connect
|
3
3
|
# to the datastore.
|
4
4
|
module Autoconnect
|
5
|
-
|
6
|
-
BLACKLISTED_RAILS_RAKE_TASKS = [
|
5
|
+
BLACKLISTED_RAILS_RAKE_TASKS = [
|
7
6
|
'about',
|
8
7
|
'assets:clean',
|
9
8
|
'assets:clobber',
|
@@ -38,7 +37,7 @@ module Vanity
|
|
38
37
|
'stats',
|
39
38
|
'time:zones:all',
|
40
39
|
'tmp:clear',
|
41
|
-
'tmp:create'
|
40
|
+
'tmp:create',
|
42
41
|
]
|
43
42
|
ENVIRONMENT_VANITY_DISABLED_FLAG = "VANITY_DISABLED"
|
44
43
|
|
@@ -46,10 +45,10 @@ module Vanity
|
|
46
45
|
def should_connect?
|
47
46
|
!environment_disabled? && !in_blacklisted_rake_task?
|
48
47
|
end
|
49
|
-
|
48
|
+
alias playground_should_autoconnect? should_connect?
|
50
49
|
|
51
50
|
def schema_relevant?
|
52
|
-
current_rake_tasks.any? { |task| task
|
51
|
+
current_rake_tasks.any? { |task| task.start_with?('db:') }
|
53
52
|
end
|
54
53
|
|
55
54
|
def environment_disabled?
|
@@ -62,9 +61,9 @@ module Vanity
|
|
62
61
|
|
63
62
|
def current_rake_tasks
|
64
63
|
::Rake.application.top_level_tasks
|
65
|
-
rescue
|
64
|
+
rescue StandardError
|
66
65
|
[]
|
67
66
|
end
|
68
67
|
end
|
69
68
|
end
|
70
|
-
end
|
69
|
+
end
|
data/lib/vanity/commands/list.rb
CHANGED
@@ -4,16 +4,16 @@ module Vanity
|
|
4
4
|
# Lists all experiments and metrics.
|
5
5
|
def list
|
6
6
|
Vanity.playground.experiments.each do |id, experiment|
|
7
|
-
puts "experiment :%-.20s (%-.40s)"
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
puts format("experiment :%-.20s (%-.40s)", id, experiment.name)
|
8
|
+
next unless experiment.respond_to?(:alternatives)
|
9
|
+
|
10
|
+
experiment.alternatives.each do |alt|
|
11
|
+
hash = experiment.fingerprint(alt)
|
12
|
+
puts format(" %s: %-40.40s (%s)", alt.name, alt.value, hash)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
Vanity.playground.metrics.each do |id, metric|
|
16
|
-
puts "metric :%-.20s (%-.40s)"
|
16
|
+
puts format("metric :%-.20s (%-.40s)", id, metric.name)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -2,11 +2,9 @@ require "erb"
|
|
2
2
|
require "cgi"
|
3
3
|
|
4
4
|
module Vanity
|
5
|
-
|
6
5
|
# Render method available to templates (when used by Vanity command line,
|
7
6
|
# outside Rails).
|
8
7
|
module Render
|
9
|
-
|
10
8
|
# Render the named template. Used for reporting and the dashboard.
|
11
9
|
def render(path_or_options, locals = {})
|
12
10
|
if path_or_options.respond_to?(:keys)
|
@@ -29,21 +27,23 @@ module Vanity
|
|
29
27
|
end
|
30
28
|
|
31
29
|
class ProxyEmpty < String
|
32
|
-
def method_missing(
|
30
|
+
def method_missing(_method, *_args) # rubocop:todo Style/MissingRespondToMissing
|
31
|
+
self.class.new
|
32
|
+
end
|
33
33
|
end
|
34
34
|
|
35
35
|
# prevent certain url helper methods from failing so we can run erb templates outside of rails for reports.
|
36
|
-
def method_missing(method, *args, &block)
|
36
|
+
def method_missing(method, *args, &block) # rubocop:todo Style/MissingRespondToMissing
|
37
37
|
%w(url_for flash).include?(method.to_s) ? ProxyEmpty.new : super
|
38
38
|
end
|
39
39
|
|
40
40
|
# Dumbed down from Rails' simple_format.
|
41
|
-
def vanity_simple_format(text, options={})
|
42
|
-
open = "<p #{options.map { |k,v| "#{k}=\"#{CGI.escapeHTML v}\"" }.join(
|
43
|
-
text = open + text.gsub(/\r\n?/, "\n")
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
def vanity_simple_format(text, options = {})
|
42
|
+
open = "<p #{options.map { |k, v| "#{k}=\"#{CGI.escapeHTML v}\"" }.join(' ')}>"
|
43
|
+
text = open + text.gsub(/\r\n?/, "\n") # \r\n and \r -> \n # rubocop:todo Lint/UselessAssignment
|
44
|
+
.gsub(/\n\n+/, "</p>\n\n#{open}") # 2+ newline -> paragraph
|
45
|
+
.gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') + # 1 newline -> br
|
46
|
+
"</p>"
|
47
47
|
end
|
48
48
|
|
49
49
|
protected
|
@@ -54,7 +54,7 @@ module Vanity
|
|
54
54
|
struct = Struct.new(*keys)
|
55
55
|
struct.send :include, Render
|
56
56
|
locals = struct.new(*locals.values_at(*keys))
|
57
|
-
path = "#{Vanity.template(path)}.erb" unless
|
57
|
+
path = "#{Vanity.template(path)}.erb" unless /\/.*\.erb\z/.match?(path)
|
58
58
|
dir, base = File.split(path)
|
59
59
|
path = File.join(dir, partialize(base))
|
60
60
|
erb = ERB.new(File.read(path), nil, '<>')
|
@@ -63,10 +63,10 @@ module Vanity
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def partialize(template_name)
|
66
|
-
if template_name[0]
|
67
|
-
"_#{template_name}"
|
68
|
-
else
|
66
|
+
if template_name[0] == '_'
|
69
67
|
template_name
|
68
|
+
else
|
69
|
+
"_#{template_name}"
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -80,20 +80,16 @@ module Vanity
|
|
80
80
|
# arguments.
|
81
81
|
def report(output = nil)
|
82
82
|
html = render(Vanity.template("_report.erb"),
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
)
|
83
|
+
experiments: Vanity.playground.experiments,
|
84
|
+
experiments_persisted: Vanity.playground.experiments_persisted?,
|
85
|
+
metrics: Vanity.playground.metrics)
|
87
86
|
if output
|
88
|
-
File.
|
89
|
-
file.write html
|
90
|
-
end
|
87
|
+
File.write(output, html)
|
91
88
|
puts "New report available in #{output}"
|
92
89
|
else
|
93
90
|
$stdout.write html
|
94
91
|
end
|
95
92
|
end
|
96
|
-
|
97
93
|
end
|
98
94
|
end
|
99
95
|
end
|
data/lib/vanity/configuration.rb
CHANGED
@@ -7,7 +7,7 @@ module Vanity
|
|
7
7
|
LEGACY_CONNECTION_KEY = :connection
|
8
8
|
LEGACY_REDIS_CONFIG_FILE = "redis.yml"
|
9
9
|
|
10
|
-
class<<self
|
10
|
+
class << self
|
11
11
|
private
|
12
12
|
|
13
13
|
def default_logger # :nodoc:
|
@@ -30,9 +30,9 @@ module Vanity
|
|
30
30
|
#
|
31
31
|
def default_request_filter(request) # :nodoc:
|
32
32
|
request &&
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
request.env &&
|
34
|
+
request.env["HTTP_USER_AGENT"] &&
|
35
|
+
request.env["HTTP_USER_AGENT"].match(/(?:https?:\/\/)|(?:bot|spider|crawler)/i)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -46,7 +46,7 @@ module Vanity
|
|
46
46
|
failover_on_datastore_error: false,
|
47
47
|
locales_path: File.expand_path(File.join(File.dirname(__FILE__), 'locales')),
|
48
48
|
logger: default_logger,
|
49
|
-
on_datastore_error:
|
49
|
+
on_datastore_error: lambda { |error, klass, method, arguments|
|
50
50
|
default_on_datastore_error(error, klass, method, arguments)
|
51
51
|
},
|
52
52
|
on_assignment: nil,
|
@@ -188,7 +188,7 @@ module Vanity
|
|
188
188
|
# We independently list each attr_accessor to includes docs, otherwise
|
189
189
|
# something like DEFAULTS.each { |key, value| attr_accessor key } would be
|
190
190
|
# shorter.
|
191
|
-
DEFAULTS.each do |default,
|
191
|
+
DEFAULTS.each do |default, _value|
|
192
192
|
define_method default do
|
193
193
|
self[default]
|
194
194
|
end
|
@@ -208,22 +208,22 @@ module Vanity
|
|
208
208
|
end
|
209
209
|
|
210
210
|
# @return nil or a hash of symbolized keys for connection settings
|
211
|
-
def connection_params(file_name=nil)
|
211
|
+
def connection_params(file_name = nil)
|
212
212
|
file_name ||= config_file
|
213
213
|
file_path = File.join(config_path, file_name)
|
214
214
|
|
215
|
-
if File.exist?(file_path)
|
216
|
-
config = YAML.
|
215
|
+
if File.exist?(file_path) # rubocop:todo Style/GuardClause
|
216
|
+
config = YAML.safe_load(ERB.new(File.read(file_path)).result)
|
217
217
|
config ||= {}
|
218
218
|
params_for_environment = config[environment.to_s]
|
219
219
|
|
220
|
-
unless params_for_environment
|
221
|
-
raise MissingEnvironment.new("No configuration for #{environment}")
|
222
|
-
end
|
220
|
+
raise MissingEnvironment, "No configuration for #{environment}" unless params_for_environment
|
223
221
|
|
224
222
|
# Symbolize keys if it's a hash.
|
225
223
|
if params_for_environment.respond_to?(:inject)
|
226
|
-
params_for_environment.
|
224
|
+
params_for_environment.each_with_object({}) do |kv, h|
|
225
|
+
h[kv.first.to_sym] = kv.last
|
226
|
+
end
|
227
227
|
else
|
228
228
|
params_for_environment
|
229
229
|
end
|
@@ -238,11 +238,11 @@ module Vanity
|
|
238
238
|
|
239
239
|
connection_url = connection_config[LEGACY_CONNECTION_KEY]
|
240
240
|
|
241
|
-
if connection_url
|
242
|
-
logger.warn(
|
241
|
+
if connection_url # rubocop:todo Style/GuardClause
|
242
|
+
logger.warn('Deprecated: Please specify connection urls using the `url` key with a protocol prefix instead of `connection`. This fallback will be removed in a future version.')
|
243
243
|
|
244
244
|
# Legacy lack of protocol handling
|
245
|
-
if
|
245
|
+
if /^\w+:/.match?(connection_url)
|
246
246
|
connection_url
|
247
247
|
else
|
248
248
|
"redis://" + connection_url
|
@@ -254,10 +254,10 @@ module Vanity
|
|
254
254
|
def redis_url_from_file
|
255
255
|
connection_url = connection_params(LEGACY_REDIS_CONFIG_FILE)
|
256
256
|
|
257
|
-
if connection_url
|
258
|
-
logger.warn(
|
257
|
+
if connection_url # rubocop:todo Style/GuardClause
|
258
|
+
logger.warn('Deprecated: Please specify the vanity config file, the default fallback to "config/redis.yml" may be removed in a future version.')
|
259
259
|
|
260
|
-
if
|
260
|
+
if /^\w+:/.match?(connection_url)
|
261
261
|
connection_url
|
262
262
|
else
|
263
263
|
"redis://" + connection_url
|
data/lib/vanity/connection.rb
CHANGED
@@ -30,12 +30,10 @@ module Vanity
|
|
30
30
|
# :host=>"redis.local"
|
31
31
|
# )
|
32
32
|
# @since 2.0.0
|
33
|
-
def initialize(specification=nil)
|
33
|
+
def initialize(specification = nil)
|
34
34
|
@specification = Specification.new(specification || DEFAULT_SPECIFICATION).to_h
|
35
35
|
|
36
|
-
if Autoconnect.playground_should_autoconnect?
|
37
|
-
@adapter = setup_connection(@specification)
|
38
|
-
end
|
36
|
+
@adapter = setup_connection(@specification) if Autoconnect.playground_should_autoconnect?
|
39
37
|
end
|
40
38
|
|
41
39
|
# Closes the current connection.
|
@@ -68,16 +66,16 @@ module Vanity
|
|
68
66
|
when String
|
69
67
|
@spec = build_specification_hash_from_url(spec)
|
70
68
|
when Hash
|
71
|
-
if spec[:redis]
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
69
|
+
@spec = if spec[:redis]
|
70
|
+
{
|
71
|
+
adapter: :redis,
|
72
|
+
redis: spec[:redis],
|
73
|
+
}
|
74
|
+
else
|
75
|
+
spec
|
76
|
+
end
|
79
77
|
else
|
80
|
-
raise InvalidSpecification
|
78
|
+
raise InvalidSpecification, "Unsupported connection specification: #{spec.inspect}"
|
81
79
|
end
|
82
80
|
|
83
81
|
validate_specification_hash(@spec)
|
@@ -104,7 +102,7 @@ module Vanity
|
|
104
102
|
host: uri.host,
|
105
103
|
port: uri.port,
|
106
104
|
path: uri.path,
|
107
|
-
params: params
|
105
|
+
params: params,
|
108
106
|
}
|
109
107
|
end
|
110
108
|
end
|