split 3.0.0 → 3.3.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +2 -2
- data/.travis.yml +39 -2
- data/Appraisals +8 -1
- data/CHANGELOG.md +41 -0
- data/CONTRIBUTING.md +54 -5
- data/LICENSE +1 -1
- data/README.md +184 -110
- data/gemfiles/4.2.gemfile +1 -1
- data/gemfiles/5.0.gemfile +1 -2
- data/gemfiles/5.1.gemfile +9 -0
- data/gemfiles/5.2.gemfile +9 -0
- data/lib/split/alternative.rb +3 -0
- data/lib/split/combined_experiments_helper.rb +37 -0
- data/lib/split/configuration.rb +8 -0
- data/lib/split/dashboard/pagination_helpers.rb +87 -0
- data/lib/split/dashboard/paginator.rb +16 -0
- data/lib/split/dashboard/public/style.css +9 -0
- data/lib/split/dashboard/views/index.erb +5 -1
- data/lib/split/dashboard.rb +2 -0
- data/lib/split/engine.rb +2 -0
- data/lib/split/experiment.rb +5 -4
- data/lib/split/helper.rb +14 -1
- data/lib/split/persistence/cookie_adapter.rb +53 -15
- data/lib/split/redis_interface.rb +1 -3
- data/lib/split/version.rb +1 -1
- data/lib/split.rb +1 -0
- data/spec/alternative_spec.rb +12 -0
- data/spec/combined_experiments_helper_spec.rb +57 -0
- data/spec/dashboard/pagination_helpers_spec.rb +198 -0
- data/spec/dashboard/paginator_spec.rb +37 -0
- data/spec/experiment_spec.rb +1 -1
- data/spec/helper_spec.rb +20 -0
- data/spec/persistence/cookie_adapter_spec.rb +90 -23
- data/spec/persistence/dual_adapter_spec.rb +2 -2
- data/spec/split_spec.rb +7 -7
- data/split.gemspec +16 -6
- metadata +33 -16
data/spec/helper_spec.rb
CHANGED
|
@@ -35,6 +35,18 @@ describe Split::Helper do
|
|
|
35
35
|
expect(lambda { ab_test({'link_color' => "purchase"}, 'blue', 'red') }).not_to raise_error
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
it "raises an appropriate error when processing combined expirements" do
|
|
39
|
+
Split.configuration.experiments = {
|
|
40
|
+
:combined_exp_1 => {
|
|
41
|
+
:alternatives => [ { name: "control", percent: 50 }, { name: "test-alt", percent: 50 } ],
|
|
42
|
+
:metric => :my_metric,
|
|
43
|
+
:combined_experiments => [:combined_exp_1_sub_1]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
Split::ExperimentCatalog.find_or_create('combined_exp_1')
|
|
47
|
+
expect(lambda { ab_test('combined_exp_1')}).to raise_error(Split::InvalidExperimentsFormatError )
|
|
48
|
+
end
|
|
49
|
+
|
|
38
50
|
it "should assign a random alternative to a new user when there are an equal number of alternatives assigned" do
|
|
39
51
|
ab_test('link_color', 'blue', 'red')
|
|
40
52
|
expect(['red', 'blue']).to include(ab_user['link_color'])
|
|
@@ -687,6 +699,14 @@ describe Split::Helper do
|
|
|
687
699
|
end
|
|
688
700
|
end
|
|
689
701
|
|
|
702
|
+
describe 'when user is previewing' do
|
|
703
|
+
before(:each) do
|
|
704
|
+
@request = OpenStruct.new(headers: { 'x-purpose' => 'preview' })
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
it_behaves_like "a disabled test"
|
|
708
|
+
end
|
|
709
|
+
|
|
690
710
|
describe 'versioned experiments' do
|
|
691
711
|
it "should use version zero if no version is present" do
|
|
692
712
|
alternative_name = ab_test('link_color', 'blue', 'red')
|
|
@@ -1,39 +1,106 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require "spec_helper"
|
|
3
|
+
require 'rack/test'
|
|
3
4
|
|
|
4
5
|
describe Split::Persistence::CookieAdapter do
|
|
6
|
+
subject { described_class.new(context) }
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
shared_examples "sets cookies correctly" do
|
|
9
|
+
describe "#[] and #[]=" do
|
|
10
|
+
it "set and return the value for given key" do
|
|
11
|
+
subject["my_key"] = "my_value"
|
|
12
|
+
expect(subject["my_key"]).to eq("my_value")
|
|
13
|
+
end
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
it "handles invalid JSON" do
|
|
16
|
+
context.request.cookies[:split] = {
|
|
17
|
+
:value => '{"foo":2,',
|
|
18
|
+
:expires => Time.now
|
|
19
|
+
}
|
|
20
|
+
expect(subject["my_key"]).to be_nil
|
|
21
|
+
subject["my_key"] = "my_value"
|
|
22
|
+
expect(subject["my_key"]).to eq("my_value")
|
|
23
|
+
end
|
|
13
24
|
end
|
|
14
|
-
end
|
|
15
25
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
describe "#delete" do
|
|
27
|
+
it "should delete the given key" do
|
|
28
|
+
subject["my_key"] = "my_value"
|
|
29
|
+
subject.delete("my_key")
|
|
30
|
+
expect(subject["my_key"]).to be_nil
|
|
31
|
+
end
|
|
21
32
|
end
|
|
22
|
-
end
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
describe "#keys" do
|
|
35
|
+
it "should return an array of the session's stored keys" do
|
|
36
|
+
subject["my_key"] = "my_value"
|
|
37
|
+
subject["my_second_key"] = "my_second_value"
|
|
38
|
+
expect(subject.keys).to match(["my_key", "my_second_key"])
|
|
39
|
+
end
|
|
29
40
|
end
|
|
30
41
|
end
|
|
31
42
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
|
|
44
|
+
context "when using Rack" do
|
|
45
|
+
let(:env) { Rack::MockRequest.env_for("http://example.com:8080/") }
|
|
46
|
+
let(:request) { Rack::Request.new(env) }
|
|
47
|
+
let(:response) { Rack::MockResponse.new(200, {}, "") }
|
|
48
|
+
let(:context) { double(request: request, response: response, cookies: CookiesMock.new) }
|
|
49
|
+
|
|
50
|
+
include_examples "sets cookies correctly"
|
|
51
|
+
|
|
52
|
+
it "puts multiple experiments in a single cookie" do
|
|
53
|
+
subject["foo"] = "FOO"
|
|
54
|
+
subject["bar"] = "BAR"
|
|
55
|
+
expect(context.response.headers["Set-Cookie"]).to match(/\Asplit=%7B%22foo%22%3A%22FOO%22%2C%22bar%22%3A%22BAR%22%7D; path=\/; expires=[a-zA-Z]{3}, \d{2} [a-zA-Z]{3} \d{4} \d{2}:\d{2}:\d{2} -0000\Z/)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "ensure other added cookies are not overriden" do
|
|
59
|
+
context.response.set_cookie 'dummy', 'wow'
|
|
60
|
+
subject["foo"] = "FOO"
|
|
61
|
+
expect(context.response.headers["Set-Cookie"]).to include("dummy=wow")
|
|
62
|
+
expect(context.response.headers["Set-Cookie"]).to include("split=")
|
|
63
|
+
end
|
|
37
64
|
end
|
|
38
65
|
|
|
66
|
+
context "when @context is an ActionController::Base" do
|
|
67
|
+
before :context do
|
|
68
|
+
require "rails"
|
|
69
|
+
require "action_controller/railtie"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
let(:context) do
|
|
73
|
+
controller = controller_class.new
|
|
74
|
+
if controller.respond_to?(:set_request!)
|
|
75
|
+
controller.set_request!(ActionDispatch::Request.new({}))
|
|
76
|
+
else # Before rails 5.0
|
|
77
|
+
controller.send(:"request=", ActionDispatch::Request.new({}))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
response = ActionDispatch::Response.new(200, {}, '').tap do |res|
|
|
81
|
+
res.request = controller.request
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if controller.respond_to?(:set_response!)
|
|
85
|
+
controller.set_response!(response)
|
|
86
|
+
else # Before rails 5.0
|
|
87
|
+
controller.send(:set_response!, response)
|
|
88
|
+
end
|
|
89
|
+
controller
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
let(:controller_class) { Class.new(ActionController::Base) }
|
|
93
|
+
|
|
94
|
+
include_examples "sets cookies correctly"
|
|
95
|
+
|
|
96
|
+
it "puts multiple experiments in a single cookie" do
|
|
97
|
+
subject["foo"] = "FOO"
|
|
98
|
+
subject["bar"] = "BAR"
|
|
99
|
+
expect(subject.keys).to eq(["foo", "bar"])
|
|
100
|
+
expect(subject["foo"]).to eq("FOO")
|
|
101
|
+
expect(subject["bar"]).to eq("BAR")
|
|
102
|
+
cookie_jar = context.request.env["action_dispatch.cookies"]
|
|
103
|
+
expect(cookie_jar['split']).to eq("{\"foo\":\"FOO\",\"bar\":\"BAR\"}")
|
|
104
|
+
end
|
|
105
|
+
end
|
|
39
106
|
end
|
|
@@ -47,7 +47,7 @@ describe Split::Persistence::DualAdapter do
|
|
|
47
47
|
context "when logged in" do
|
|
48
48
|
subject {
|
|
49
49
|
described_class.with_config(
|
|
50
|
-
logged_in:
|
|
50
|
+
logged_in: lambda { |context| true },
|
|
51
51
|
logged_in_adapter: selected_adapter,
|
|
52
52
|
logged_out_adapter: not_selected_adapter
|
|
53
53
|
).new(context)
|
|
@@ -59,7 +59,7 @@ describe Split::Persistence::DualAdapter do
|
|
|
59
59
|
context "when not logged in" do
|
|
60
60
|
subject {
|
|
61
61
|
described_class.with_config(
|
|
62
|
-
logged_in:
|
|
62
|
+
logged_in: lambda { |context| false },
|
|
63
63
|
logged_in_adapter: not_selected_adapter,
|
|
64
64
|
logged_out_adapter: selected_adapter
|
|
65
65
|
).new(context)
|
data/spec/split_spec.rb
CHANGED
|
@@ -15,19 +15,19 @@ RSpec.describe Split do
|
|
|
15
15
|
Split.redis = 'redis://localhost:6379'
|
|
16
16
|
expect(Split.redis).to be_a(Redis)
|
|
17
17
|
|
|
18
|
-
client = Split.redis.
|
|
19
|
-
expect(client
|
|
20
|
-
expect(client
|
|
18
|
+
client = Split.redis.connection
|
|
19
|
+
expect(client[:host]).to eq("localhost")
|
|
20
|
+
expect(client[:port]).to eq(6379)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it 'accepts an options hash' do
|
|
24
24
|
Split.redis = {host: 'localhost', port: 6379, db: 12}
|
|
25
25
|
expect(Split.redis).to be_a(Redis)
|
|
26
26
|
|
|
27
|
-
client = Split.redis.
|
|
28
|
-
expect(client
|
|
29
|
-
expect(client
|
|
30
|
-
expect(client
|
|
27
|
+
client = Split.redis.connection
|
|
28
|
+
expect(client[:host]).to eq("localhost")
|
|
29
|
+
expect(client[:port]).to eq(6379)
|
|
30
|
+
expect(client[:db]).to eq(12)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it 'accepts a valid Redis instance' do
|
data/split.gemspec
CHANGED
|
@@ -12,7 +12,17 @@ Gem::Specification.new do |s|
|
|
|
12
12
|
s.homepage = "https://github.com/splitrb/split"
|
|
13
13
|
s.summary = "Rack based split testing framework"
|
|
14
14
|
|
|
15
|
-
s.
|
|
15
|
+
s.metadata = {
|
|
16
|
+
"homepage_uri" => "https://github.com/splitrb/split",
|
|
17
|
+
"changelog_uri" => "https://github.com/splitrb/split/blob/master/CHANGELOG.md",
|
|
18
|
+
"source_code_uri" => "https://github.com/splitrb/split",
|
|
19
|
+
"bug_tracker_uri" => "https://github.com/splitrb/split/issues",
|
|
20
|
+
"wiki_uri" => "https://github.com/splitrb/split/wiki",
|
|
21
|
+
"mailing_list_uri" => "https://groups.google.com/d/forum/split-ruby"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
s.required_ruby_version = '>= 1.9.3'
|
|
25
|
+
s.required_rubygems_version = '>= 2.0.0'
|
|
16
26
|
|
|
17
27
|
s.rubyforge_project = "split"
|
|
18
28
|
|
|
@@ -24,11 +34,11 @@ Gem::Specification.new do |s|
|
|
|
24
34
|
s.add_dependency 'sinatra', '>= 1.2.6'
|
|
25
35
|
s.add_dependency 'simple-random', '>= 0.9.3'
|
|
26
36
|
|
|
27
|
-
s.add_development_dependency 'bundler', '~> 1.
|
|
28
|
-
s.add_development_dependency 'simplecov', '~> 0.
|
|
37
|
+
s.add_development_dependency 'bundler', '~> 1.14'
|
|
38
|
+
s.add_development_dependency 'simplecov', '~> 0.15'
|
|
29
39
|
s.add_development_dependency 'rack-test', '~> 0.6'
|
|
30
|
-
s.add_development_dependency 'rake', '~>
|
|
31
|
-
s.add_development_dependency 'rspec', '~> 3.
|
|
40
|
+
s.add_development_dependency 'rake', '~> 12'
|
|
41
|
+
s.add_development_dependency 'rspec', '~> 3.7'
|
|
32
42
|
s.add_development_dependency 'pry', '~> 0.10'
|
|
33
|
-
s.add_development_dependency 'fakeredis', '~> 0.
|
|
43
|
+
s.add_development_dependency 'fakeredis', '~> 0.7'
|
|
34
44
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: split
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Nesbitt
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-08-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: redis
|
|
@@ -58,28 +58,28 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '1.
|
|
61
|
+
version: '1.14'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '1.
|
|
68
|
+
version: '1.14'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: simplecov
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0.
|
|
75
|
+
version: '0.15'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0.
|
|
82
|
+
version: '0.15'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: rack-test
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,28 +100,28 @@ dependencies:
|
|
|
100
100
|
requirements:
|
|
101
101
|
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '
|
|
103
|
+
version: '12'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '
|
|
110
|
+
version: '12'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: rspec
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
115
|
- - "~>"
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '3.
|
|
117
|
+
version: '3.7'
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '3.
|
|
124
|
+
version: '3.7'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: pry
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -142,14 +142,14 @@ dependencies:
|
|
|
142
142
|
requirements:
|
|
143
143
|
- - "~>"
|
|
144
144
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: 0.
|
|
145
|
+
version: '0.7'
|
|
146
146
|
type: :development
|
|
147
147
|
prerelease: false
|
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
149
|
requirements:
|
|
150
150
|
- - "~>"
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: 0.
|
|
152
|
+
version: '0.7'
|
|
153
153
|
description:
|
|
154
154
|
email:
|
|
155
155
|
- andrewnez@gmail.com
|
|
@@ -174,14 +174,19 @@ files:
|
|
|
174
174
|
- Rakefile
|
|
175
175
|
- gemfiles/4.2.gemfile
|
|
176
176
|
- gemfiles/5.0.gemfile
|
|
177
|
+
- gemfiles/5.1.gemfile
|
|
178
|
+
- gemfiles/5.2.gemfile
|
|
177
179
|
- lib/split.rb
|
|
178
180
|
- lib/split/algorithms/block_randomization.rb
|
|
179
181
|
- lib/split/algorithms/weighted_sample.rb
|
|
180
182
|
- lib/split/algorithms/whiplash.rb
|
|
181
183
|
- lib/split/alternative.rb
|
|
184
|
+
- lib/split/combined_experiments_helper.rb
|
|
182
185
|
- lib/split/configuration.rb
|
|
183
186
|
- lib/split/dashboard.rb
|
|
184
187
|
- lib/split/dashboard/helpers.rb
|
|
188
|
+
- lib/split/dashboard/pagination_helpers.rb
|
|
189
|
+
- lib/split/dashboard/paginator.rb
|
|
185
190
|
- lib/split/dashboard/public/dashboard-filtering.js
|
|
186
191
|
- lib/split/dashboard/public/dashboard.js
|
|
187
192
|
- lib/split/dashboard/public/jquery-1.11.1.min.js
|
|
@@ -215,7 +220,10 @@ files:
|
|
|
215
220
|
- spec/algorithms/weighted_sample_spec.rb
|
|
216
221
|
- spec/algorithms/whiplash_spec.rb
|
|
217
222
|
- spec/alternative_spec.rb
|
|
223
|
+
- spec/combined_experiments_helper_spec.rb
|
|
218
224
|
- spec/configuration_spec.rb
|
|
225
|
+
- spec/dashboard/pagination_helpers_spec.rb
|
|
226
|
+
- spec/dashboard/paginator_spec.rb
|
|
219
227
|
- spec/dashboard_helpers_spec.rb
|
|
220
228
|
- spec/dashboard_spec.rb
|
|
221
229
|
- spec/encapsulated_helper_spec.rb
|
|
@@ -239,7 +247,13 @@ files:
|
|
|
239
247
|
homepage: https://github.com/splitrb/split
|
|
240
248
|
licenses:
|
|
241
249
|
- MIT
|
|
242
|
-
metadata:
|
|
250
|
+
metadata:
|
|
251
|
+
homepage_uri: https://github.com/splitrb/split
|
|
252
|
+
changelog_uri: https://github.com/splitrb/split/blob/master/CHANGELOG.md
|
|
253
|
+
source_code_uri: https://github.com/splitrb/split
|
|
254
|
+
bug_tracker_uri: https://github.com/splitrb/split/issues
|
|
255
|
+
wiki_uri: https://github.com/splitrb/split/wiki
|
|
256
|
+
mailing_list_uri: https://groups.google.com/d/forum/split-ruby
|
|
243
257
|
post_install_message:
|
|
244
258
|
rdoc_options: []
|
|
245
259
|
require_paths:
|
|
@@ -248,15 +262,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
248
262
|
requirements:
|
|
249
263
|
- - ">="
|
|
250
264
|
- !ruby/object:Gem::Version
|
|
251
|
-
version: 1.9.
|
|
265
|
+
version: 1.9.3
|
|
252
266
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
253
267
|
requirements:
|
|
254
268
|
- - ">="
|
|
255
269
|
- !ruby/object:Gem::Version
|
|
256
|
-
version:
|
|
270
|
+
version: 2.0.0
|
|
257
271
|
requirements: []
|
|
258
272
|
rubyforge_project: split
|
|
259
|
-
rubygems_version: 2.
|
|
273
|
+
rubygems_version: 2.7.3
|
|
260
274
|
signing_key:
|
|
261
275
|
specification_version: 4
|
|
262
276
|
summary: Rack based split testing framework
|
|
@@ -265,7 +279,10 @@ test_files:
|
|
|
265
279
|
- spec/algorithms/weighted_sample_spec.rb
|
|
266
280
|
- spec/algorithms/whiplash_spec.rb
|
|
267
281
|
- spec/alternative_spec.rb
|
|
282
|
+
- spec/combined_experiments_helper_spec.rb
|
|
268
283
|
- spec/configuration_spec.rb
|
|
284
|
+
- spec/dashboard/pagination_helpers_spec.rb
|
|
285
|
+
- spec/dashboard/paginator_spec.rb
|
|
269
286
|
- spec/dashboard_helpers_spec.rb
|
|
270
287
|
- spec/dashboard_spec.rb
|
|
271
288
|
- spec/encapsulated_helper_spec.rb
|