strong_presenter 0.0.1 → 0.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.
- checksums.yaml +7 -0
- data/.gitignore +5 -2
- data/.rspec +2 -0
- data/.travis.yml +18 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile +22 -2
- data/Guardfile +26 -0
- data/README.md +210 -52
- data/Rakefile +77 -1
- data/gemfiles/3.0.gemfile +2 -0
- data/gemfiles/3.1.gemfile +2 -0
- data/gemfiles/3.2.gemfile +2 -0
- data/gemfiles/4.0.gemfile +2 -0
- data/gemfiles/4.1.gemfile +2 -0
- data/lib/generators/controller_override.rb +15 -0
- data/lib/generators/mini_test/presenter_generator.rb +20 -0
- data/lib/generators/mini_test/templates/presenter_spec.rb +4 -0
- data/lib/generators/mini_test/templates/presenter_test.rb +4 -0
- data/lib/generators/rails/presenter_generator.rb +36 -0
- data/lib/generators/rails/templates/presenter.rb +19 -0
- data/lib/generators/rspec/presenter_generator.rb +9 -0
- data/lib/generators/rspec/templates/presenter_spec.rb +4 -0
- data/lib/generators/test_unit/presenter_generator.rb +9 -0
- data/lib/generators/test_unit/templates/presenter_test.rb +4 -0
- data/lib/strong_presenter/associable.rb +78 -0
- data/lib/strong_presenter/collection_presenter.rb +90 -0
- data/lib/strong_presenter/controller_additions.rb +50 -0
- data/lib/strong_presenter/delegation.rb +18 -0
- data/lib/strong_presenter/factory.rb +74 -0
- data/lib/strong_presenter/helper_proxy.rb +29 -11
- data/lib/strong_presenter/inferrer.rb +54 -0
- data/lib/strong_presenter/permissible.rb +73 -0
- data/lib/strong_presenter/permissions.rb +138 -0
- data/lib/strong_presenter/presenter.rb +191 -0
- data/lib/strong_presenter/presenter_association.rb +29 -0
- data/lib/strong_presenter/presenter_helper_constructor.rb +60 -0
- data/lib/strong_presenter/railtie.rb +27 -3
- data/lib/strong_presenter/tasks/test.rake +22 -0
- data/lib/strong_presenter/test/devise_helper.rb +30 -0
- data/lib/strong_presenter/test/minitest_integration.rb +6 -0
- data/lib/strong_presenter/test/rspec_integration.rb +16 -0
- data/lib/strong_presenter/test_case.rb +53 -0
- data/lib/strong_presenter/version.rb +1 -1
- data/lib/strong_presenter/view_context/build_strategy.rb +48 -0
- data/lib/strong_presenter/view_context.rb +84 -0
- data/lib/strong_presenter/view_helpers.rb +39 -0
- data/lib/strong_presenter.rb +64 -2
- data/spec/dummy/.rspec +2 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/controllers/localized_urls.rb +5 -0
- data/spec/dummy/app/controllers/posts_controller.rb +25 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/mailers/application_mailer.rb +3 -0
- data/spec/dummy/app/mailers/post_mailer.rb +19 -0
- data/spec/dummy/app/models/admin.rb +5 -0
- data/spec/dummy/app/models/post.rb +3 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/presenters/post_presenter.rb +69 -0
- data/spec/dummy/app/presenters/special_post_presenter.rb +5 -0
- data/spec/dummy/app/presenters/special_posts_presenter.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +11 -0
- data/spec/dummy/app/views/post_mailer/presented_email.html.erb +1 -0
- data/spec/dummy/app/views/posts/_post.html.erb +50 -0
- data/spec/dummy/app/views/posts/show.html.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/config/application.rb +70 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +33 -0
- data/spec/dummy/config/environments/production.rb +57 -0
- data/spec/dummy/config/environments/test.rb +31 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +8 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +9 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20121019115657_create_posts.rb +8 -0
- data/spec/dummy/db/schema.rb +21 -0
- data/spec/dummy/db/seeds.rb +2 -0
- data/spec/dummy/fast_spec/post_presenter_spec.rb +37 -0
- data/spec/dummy/lib/tasks/test.rake +16 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/spec/fast_spec_helper.rb +13 -0
- data/spec/dummy/spec/mailers/post_mailer_spec.rb +33 -0
- data/spec/dummy/spec/models/post_spec.rb +4 -0
- data/spec/dummy/spec/presenters/active_model_serializers_spec.rb +11 -0
- data/spec/dummy/spec/presenters/devise_spec.rb +64 -0
- data/spec/dummy/spec/presenters/helpers_spec.rb +21 -0
- data/spec/dummy/spec/presenters/post_presenter_spec.rb +66 -0
- data/spec/dummy/spec/presenters/spec_type_spec.rb +7 -0
- data/spec/dummy/spec/presenters/special_post_presenter_spec.rb +11 -0
- data/spec/dummy/spec/presenters/view_context_spec.rb +22 -0
- data/spec/dummy/spec/spec_helper.rb +19 -0
- data/spec/dummy/test/minitest_helper.rb +2 -0
- data/spec/dummy/test/presenters/minitest/devise_test.rb +64 -0
- data/spec/dummy/test/presenters/minitest/helpers_test.rb +21 -0
- data/spec/dummy/test/presenters/minitest/spec_type_test.rb +52 -0
- data/spec/dummy/test/presenters/minitest/view_context_test.rb +24 -0
- data/spec/dummy/test/presenters/test_unit/devise_test.rb +64 -0
- data/spec/dummy/test/presenters/test_unit/helpers_test.rb +21 -0
- data/spec/dummy/test/presenters/test_unit/view_context_test.rb +24 -0
- data/spec/dummy/test/test_helper.rb +13 -0
- data/spec/generators/presenters/presenter_generator_spec.rb +131 -0
- data/spec/generators/simplecov_spec.rb +5 -0
- data/spec/integration/integration_spec.rb +81 -0
- data/spec/integration/simplecov_spec.rb +4 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/strong_presenter/associable_spec.rb +122 -0
- data/spec/strong_presenter/collection_presenter_spec.rb +34 -0
- data/spec/strong_presenter/delegation_spec.rb +20 -0
- data/spec/strong_presenter/permissible_spec.rb +24 -0
- data/spec/strong_presenter/permissions_spec.rb +188 -0
- data/spec/strong_presenter/presenter_spec.rb +43 -0
- data/spec/strong_presenter/simplecov_spec.rb +4 -0
- data/spec/support/dummy_app.rb +85 -0
- data/spec/support/matchers/have_text.rb +50 -0
- data/spec/support/models.rb +14 -0
- data/spec/support/schema.rb +12 -0
- data/strong_presenter.gemspec +15 -0
- metadata +392 -13
- data/lib/strong_presenter/base.rb +0 -217
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module StrongPresenter
|
|
4
|
+
describe Permissions do
|
|
5
|
+
describe "#complete?" do
|
|
6
|
+
it 'is initially incomplete' do
|
|
7
|
+
expect(Permissions.new.complete?).to be false
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "#permit_all!" do
|
|
12
|
+
it 'completes the object' do
|
|
13
|
+
expect(Permissions.new.permit_all!.complete?).to be true
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#permit" do
|
|
18
|
+
it 'permits an attribute' do
|
|
19
|
+
expect(Permissions.new.permit([], :attr).permitted?([], :attr)).to be true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'permits with prefix' do
|
|
23
|
+
expect(Permissions.new.permit(:prefix, :attr).permitted?(:prefix, :attr)).to be true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'permits with arrays of symbols' do
|
|
27
|
+
expect(Permissions.new.permit([:prefix, :array], [:attr, :array]).permitted?([:prefix, :array], [:attr, :array])).to be true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'permits multiple at once' do
|
|
31
|
+
permissions = Permissions.new.permit([:prefix, :array], [:attr, :array], :attr2, :attr3)
|
|
32
|
+
expect(permissions.permitted?([:prefix, :array], :attr2)).to be true
|
|
33
|
+
expect(permissions.permitted?([:prefix, :array], [:attr, :array])).to be true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'does not mutate arguments' do
|
|
37
|
+
prefix = [:pre, :fix]
|
|
38
|
+
attrpaths = [[:attr, :path], :s]
|
|
39
|
+
Permissions.new.permit(prefixarg = prefix.dup, attrpathsarg = attrpaths.dup)
|
|
40
|
+
|
|
41
|
+
expect(prefixarg).to eq prefix
|
|
42
|
+
expect(attrpathsarg).to eq attrpaths
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "#permitted?" do
|
|
47
|
+
context 'with some attributes permitted' do
|
|
48
|
+
before(:all) do
|
|
49
|
+
@permissions = Permissions.new.permit([:prefix, :array], [:attr, :array], :attr2, :attr3)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'permits more specific paths' do
|
|
53
|
+
expect(@permissions.permitted?([:prefix, :array], [:attr2, :irrelevant])).to be true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'does not permit un-prefixed path' do
|
|
57
|
+
expect(@permissions.permitted?(:attr2)).to be false
|
|
58
|
+
expect(@permissions.permitted?([:attr2, :irrelevant])).to be false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'permits changed prefix boundaries' do
|
|
62
|
+
expect(@permissions.permitted?([:prefix, :array, :attr2], [:irrelevant])).to be true
|
|
63
|
+
expect(@permissions.permitted?(:prefix, [:array, :attr2, :irrelevant])).to be true
|
|
64
|
+
expect(@permissions.permitted?([:prefix], [:array, :attr2, :irrelevant])).to be true
|
|
65
|
+
expect(@permissions.permitted?([], [:prefix, :array, :attr2, :irrelevant])).to be true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'does not permit other attributes' do
|
|
69
|
+
expect(@permissions.permitted?([:prefix, :array], [:attr4, :irrelevant])).to be false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'does not permit shortened paths' do
|
|
73
|
+
expect(@permissions.permitted?([:prefix, :array], :attr)).to be false
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'does not mutate arguments' do
|
|
77
|
+
prefix = [:pre, :fix]
|
|
78
|
+
attrpaths = [[:attr, :path], :s, [:array, :attr2]]
|
|
79
|
+
|
|
80
|
+
@permissions.permitted?(prefixarg = prefix.dup, attrpathsarg = attrpaths.dup)
|
|
81
|
+
expect(prefixarg).to eq prefix
|
|
82
|
+
expect(attrpathsarg).to eq attrpaths
|
|
83
|
+
|
|
84
|
+
prefix = [:prefix]
|
|
85
|
+
@permissions.permitted?(prefixarg = prefix.dup, attrpathsarg = attrpaths.dup)
|
|
86
|
+
expect(prefixarg).to eq prefix
|
|
87
|
+
expect(attrpathsarg).to eq attrpaths
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'with permit all' do
|
|
92
|
+
it 'everything is true' do
|
|
93
|
+
permissions = Permissions.new.permit_all!
|
|
94
|
+
expect(permissions.permitted?(:a)).to be true
|
|
95
|
+
expect(permissions.permitted?([:a])).to be true
|
|
96
|
+
expect(permissions.permitted?([:a,:b])).to be true
|
|
97
|
+
expect(permissions.permitted?(:a,:b)).to be true
|
|
98
|
+
expect(permissions.permitted?([],:a)).to be true
|
|
99
|
+
expect(permissions.permitted?([],[:a])).to be true
|
|
100
|
+
expect(permissions.permitted?([:x,:y],[:a])).to be true
|
|
101
|
+
expect(permissions.permitted?([],[:a,:b])).to be true
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
describe "#select_permitted" do
|
|
106
|
+
context 'with some attributes permitted' do
|
|
107
|
+
before(:all) do
|
|
108
|
+
@permissions = Permissions.new.permit([:prefix, :array], [:attr, :array], :attr2, :attr3)
|
|
109
|
+
@permissions.permit([], [:attr, :array], :attr2, :attr3)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'can select something which is permitted' do
|
|
113
|
+
expect(@permissions.select_permitted([], :attr2)).to eq [[:attr2]]
|
|
114
|
+
expect(@permissions.select_permitted([:prefix], [:array, :attr2, :irrelevant])).to eq [[:array, :attr2, :irrelevant]]
|
|
115
|
+
expect(@permissions.select_permitted([:prefix, :array], [:attr2, :irrelevant])).to eq [[:attr2, :irrelevant]]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'can select multiple permitted attributes' do
|
|
119
|
+
attribute_paths = [:attr2, :attr3, [:attr2, :irrelevant], [:attr, :array]]
|
|
120
|
+
permitted = @permissions.select_permitted([:prefix, :array], *attribute_paths)
|
|
121
|
+
attribute_paths.each do |attribute_path|
|
|
122
|
+
expect(permitted).to include Array(attribute_path)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'selects only permitted attributes in the original order' do
|
|
127
|
+
permitted_paths = [:attr2, :attr3, [:attr2, :irrelevant], [:attr, :array], [:attr3, :ir]]
|
|
128
|
+
unpermitted_paths = [:attr4, :attr5, [:attrk, :irrelevant], [:attr, :ar]]
|
|
129
|
+
attribute_paths = (unpermitted_paths + permitted_paths).shuffle
|
|
130
|
+
expect(@permissions.select_permitted([:prefix, :array], *attribute_paths)).to eq((attribute_paths & permitted_paths).map{|a|Array(a)})
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'does not mutate arguments' do
|
|
134
|
+
prefix = [:pre, :fix]
|
|
135
|
+
attrpaths = [[:attr, :path], :s, [:array, :attr2]]
|
|
136
|
+
|
|
137
|
+
@permissions.select_permitted(prefixarg = prefix.dup, attrpathsarg = attrpaths.dup)
|
|
138
|
+
expect(prefixarg).to eq prefix
|
|
139
|
+
expect(attrpathsarg).to eq attrpaths
|
|
140
|
+
|
|
141
|
+
prefix = [:prefix]
|
|
142
|
+
@permissions.select_permitted(prefixarg = prefix.dup, attrpathsarg = attrpaths.dup)
|
|
143
|
+
expect(prefixarg).to eq prefix
|
|
144
|
+
expect(attrpathsarg).to eq attrpaths
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context 'with permit all' do
|
|
149
|
+
it 'everything is selected' do
|
|
150
|
+
permissions = Permissions.new.permit_all!
|
|
151
|
+
attribute_paths = [:attr2, :attr3, [:attr2, :irrelevant], [:attr, :array]]
|
|
152
|
+
permitted = permissions.select_permitted([:prefix, :array], *attribute_paths)
|
|
153
|
+
expect(permitted).to eq(attribute_paths.map{|a|Array(a)})
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
describe "#reject_permitted" do
|
|
158
|
+
context 'with some attributes permitted' do
|
|
159
|
+
before(:all) do
|
|
160
|
+
@permissions = Permissions.new.permit([:prefix, :array], [:attr, :array], :attr2, :attr3)
|
|
161
|
+
@permissions.permit([], [:attr, :array], :attr2, :attr3)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'selects only unpermitted attributes in the original order' do
|
|
165
|
+
permitted_paths = [:attr2, :attr3, [:attr2, :irrelevant], [:attr, :array], [:attr3, :ir]]
|
|
166
|
+
unpermitted_paths = [:attr4, :attr5, [:attrk, :irrelevant], [:attr, :ar]]
|
|
167
|
+
attribute_paths = (unpermitted_paths + permitted_paths).shuffle
|
|
168
|
+
expect(@permissions.reject_permitted([:prefix, :array], *attribute_paths)).to eq((attribute_paths & unpermitted_paths).map{|a|Array(a)})
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'does not mutate arguments' do
|
|
172
|
+
prefix = [:pre, :fix]
|
|
173
|
+
attrpaths = [[:attr, :path], :s, [:array, :attr2]]
|
|
174
|
+
|
|
175
|
+
@permissions.reject_permitted(prefixarg = prefix.dup, attrpathsarg = attrpaths.dup)
|
|
176
|
+
expect(prefixarg).to eq prefix
|
|
177
|
+
expect(attrpathsarg).to eq attrpaths
|
|
178
|
+
|
|
179
|
+
prefix = [:prefix]
|
|
180
|
+
@permissions.reject_permitted(prefixarg = prefix.dup, attrpathsarg = attrpaths.dup)
|
|
181
|
+
expect(prefixarg).to eq prefix
|
|
182
|
+
expect(attrpathsarg).to eq attrpaths
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module StrongPresenter
|
|
4
|
+
describe Presenter do
|
|
5
|
+
describe "#initialize" do
|
|
6
|
+
it "sets the object" do
|
|
7
|
+
object = Model.new
|
|
8
|
+
presenter = Presenter.new(object)
|
|
9
|
+
|
|
10
|
+
expect(presenter.send :object).to be object
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "takes a block" do
|
|
14
|
+
object = Product.new
|
|
15
|
+
presenter = ProductPresenter.new(object) do |presenter|
|
|
16
|
+
expect(presenter.class).to be ProductPresenter
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
expect(presenter.class).to be ProductPresenter
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "Collection" do
|
|
24
|
+
it "finds corresponding collection presenter" do
|
|
25
|
+
expect(ProductPresenter::Collection).to be ProductsPresenter
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "creates a new collection presenter if one does not exist" do
|
|
29
|
+
expect{OthersPresenter}.to raise_error(NameError)
|
|
30
|
+
expect(OtherPresenter::Collection.superclass).to be StrongPresenter::CollectionPresenter
|
|
31
|
+
expect{OthersPresenter}.to raise_error(NameError)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "sets inferred presenter on default collection presenter" do
|
|
35
|
+
expect(OtherPresenter::Collection.send :presenter_class).to be OtherPresenter
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "infers presenter on collection presenter" do
|
|
39
|
+
expect(ProductPresenter::Collection.send :presenter_class).to be ProductPresenter
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
|
|
4
|
+
# Adapted from code by Jon Leighton
|
|
5
|
+
# https://github.com/jonleighton/focused_controller/blob/ec7ccf1/test/acceptance/app_test.rb
|
|
6
|
+
|
|
7
|
+
class DummyApp
|
|
8
|
+
|
|
9
|
+
def initialize(environment)
|
|
10
|
+
raise ArgumentError, "Environment must be development or production" unless ["development", "production"].include?(environment.to_s)
|
|
11
|
+
@environment = environment
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :environment
|
|
15
|
+
|
|
16
|
+
def url
|
|
17
|
+
"http://#{localhost}:#{port}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def get(path)
|
|
21
|
+
Net::HTTP.get(URI(url + path))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def within_app(&block)
|
|
25
|
+
Dir.chdir(root, &block)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def start_server
|
|
29
|
+
within_app do
|
|
30
|
+
IO.popen("bundle exec rails s -e #{@environment} -p #{port} 2>&1") do |out|
|
|
31
|
+
start = Time.now
|
|
32
|
+
started = false
|
|
33
|
+
output = ""
|
|
34
|
+
timeout = 60.0
|
|
35
|
+
|
|
36
|
+
while !started && !out.eof? && Time.now - start <= timeout
|
|
37
|
+
output << read_output(out)
|
|
38
|
+
sleep 0.1
|
|
39
|
+
|
|
40
|
+
begin
|
|
41
|
+
TCPSocket.new(localhost, port)
|
|
42
|
+
rescue Errno::ECONNREFUSED
|
|
43
|
+
else
|
|
44
|
+
started = true
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
raise "Server failed to start:\n#{output}" unless started
|
|
49
|
+
|
|
50
|
+
yield
|
|
51
|
+
|
|
52
|
+
Process.kill("KILL", out.pid)
|
|
53
|
+
File.delete("tmp/pids/server.pid")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def root
|
|
61
|
+
File.expand_path("../../dummy", __FILE__)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def localhost
|
|
65
|
+
"127.0.0.1"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def port
|
|
69
|
+
@port ||= begin
|
|
70
|
+
server = TCPServer.new(localhost, 0)
|
|
71
|
+
server.addr[1]
|
|
72
|
+
ensure
|
|
73
|
+
server.close if server
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def read_output(stream)
|
|
78
|
+
read = IO.select([stream], [], [stream], 0.1)
|
|
79
|
+
output = ""
|
|
80
|
+
loop { output << stream.read_nonblock(1024) } if read
|
|
81
|
+
output
|
|
82
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, EOFError
|
|
83
|
+
output
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'capybara'
|
|
2
|
+
|
|
3
|
+
module HaveTextMatcher
|
|
4
|
+
def have_text(text)
|
|
5
|
+
HaveText.new(text)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class HaveText
|
|
9
|
+
def initialize(text)
|
|
10
|
+
@text = text
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def in(css)
|
|
14
|
+
@css = css
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def matches?(subject)
|
|
19
|
+
@subject = Capybara.string(subject)
|
|
20
|
+
|
|
21
|
+
@subject.has_css?(@css || "*", text: @text)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def failure_message_for_should
|
|
25
|
+
"expected to find #{@text.inspect} #{within}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def failure_message_for_should_not
|
|
29
|
+
"expected not to find #{@text.inspect} #{within}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def within
|
|
35
|
+
if @css && @subject.has_css?(@css)
|
|
36
|
+
"within\n#{@subject.find(@css).native}"
|
|
37
|
+
else
|
|
38
|
+
"#{inside} within\n#{@subject.native}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def inside
|
|
43
|
+
@css ? "inside #{@css.inspect}" : "anywhere"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
RSpec.configure do |config|
|
|
49
|
+
config.include HaveTextMatcher
|
|
50
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
|
|
3
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
|
4
|
+
|
|
5
|
+
load File.dirname(__FILE__) + '/schema.rb'
|
|
6
|
+
|
|
7
|
+
class Wheel < ActiveRecord::Base
|
|
8
|
+
belongs_to :vehicle, polymorphic: true
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Car < ActiveRecord::Base
|
|
12
|
+
has_many :wheels, as: :vehicle
|
|
13
|
+
end
|
|
14
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
ActiveRecord::Schema.define do
|
|
2
|
+
self.verbose = false
|
|
3
|
+
|
|
4
|
+
create_table :cars, :force => true do |t|
|
|
5
|
+
t.string :license_plate
|
|
6
|
+
t.timestamps
|
|
7
|
+
end
|
|
8
|
+
create_table :wheels, :force => true do |t|
|
|
9
|
+
t.references :vehicle, polymorphic: true
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
end
|
data/strong_presenter.gemspec
CHANGED
|
@@ -16,4 +16,19 @@ Gem::Specification.new do |gem|
|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
18
|
gem.require_paths = ["lib"]
|
|
19
|
+
|
|
20
|
+
gem.add_dependency 'activesupport', '>= 3.0'
|
|
21
|
+
gem.add_dependency 'actionpack', '>= 3.0'
|
|
22
|
+
gem.add_dependency 'request_store', '~> 1.0.3'
|
|
23
|
+
gem.add_dependency 'activemodel', '>= 3.0'
|
|
24
|
+
|
|
25
|
+
gem.add_development_dependency 'ammeter'
|
|
26
|
+
gem.add_development_dependency 'rake', '>= 0.9.2'
|
|
27
|
+
gem.add_development_dependency 'rspec', '~> 2.12'
|
|
28
|
+
gem.add_development_dependency 'rspec-mocks', '>= 2.12.1'
|
|
29
|
+
gem.add_development_dependency 'rspec-rails', '~> 2.12'
|
|
30
|
+
gem.add_development_dependency 'minitest-rails', '~> 0.2'
|
|
31
|
+
gem.add_development_dependency 'capybara'
|
|
32
|
+
gem.add_development_dependency 'active_model_serializers'
|
|
33
|
+
gem.add_development_dependency 'activerecord', '>= 3.0'
|
|
19
34
|
end
|