bourgeois 1.0.1 → 1.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.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +6 -6
- data/lib/bourgeois/presenter.rb +30 -0
- data/lib/bourgeois/version.rb +1 -1
- data/lib/bourgeois/view_helper.rb +1 -27
- data/spec/bourgeois/presenter_spec.rb +155 -0
- metadata +2 -4
- data/spec/bourgeois/view_helper_spec.rb +0 -158
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16a4e2d690cff8618070daeeeb403f8bf16724ed
|
4
|
+
data.tar.gz: 3e6bc722e3ea4f211d17caf0a2d0ff144aa47323
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 514b62f8b51c41b6245b879e26feb8e5817d7a0a425db0882619e089e65db4bc2ea7980186e7f8ec5459d7cf83369b9b1a5c23bd8c04eb844bb6cc8b836e3b29
|
7
|
+
data.tar.gz: f8d20acd4122b98a70aa43469a82aaee0d974f1b1e725f802ad3a366d982907fc2ab2bbf4db0b55bc53256202457ac91f732de90ee3ca0a0367231e24f2bbb58
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
<br />
|
6
6
|
Bourgeois is a Ruby library that makes using presenters a very simple thing.
|
7
7
|
<br /><br />
|
8
|
-
<a href="https://rubygems.org/gems/bourgeois"><img src="
|
9
|
-
<a href="https://codeclimate.com/github/mirego/bourgeois"><img src="
|
10
|
-
<a href='https://coveralls.io/r/mirego/bourgeois?branch=master'><img src=
|
11
|
-
<a href='https://gemnasium.com/mirego/bourgeois'><img src="
|
12
|
-
<a href="https://travis-ci.org/mirego/bourgeois"><img src="
|
8
|
+
<a href="https://rubygems.org/gems/bourgeois"><img src="http://img.shields.io/gem/v/bourgeois.svg" /></a>
|
9
|
+
<a href="https://codeclimate.com/github/mirego/bourgeois"><img src="http://img.shields.io/codeclimate/github/mirego/bourgeois.svg" /></a>
|
10
|
+
<a href='https://coveralls.io/r/mirego/bourgeois?branch=master'><img src="http://img.shields.io/coveralls/mirego/bourgeois.svg" /></a>
|
11
|
+
<a href='https://gemnasium.com/mirego/bourgeois'><img src="http://img.shields.io/gemnasium/mirego/bourgeois.svg" /></a>
|
12
|
+
<a href="https://travis-ci.org/mirego/bourgeois"><img src="http://img.shields.io/travis/mirego/bourgeois.svg" /></a>
|
13
13
|
</p>
|
14
14
|
|
15
15
|
---
|
@@ -94,7 +94,7 @@ Bourgeois was inspired by some code [@rafBM](https://twitter.com/rafBM) wrote fo
|
|
94
94
|
|
95
95
|
## License
|
96
96
|
|
97
|
-
`Bourgeois` is © 2013 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/bourgeois/blob/master/LICENSE.md) file.
|
97
|
+
`Bourgeois` is © 2013-2014 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/bourgeois/blob/master/LICENSE.md) file.
|
98
98
|
|
99
99
|
## About Mirego
|
100
100
|
|
data/lib/bourgeois/presenter.rb
CHANGED
@@ -47,6 +47,29 @@ module Bourgeois
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
# Wrap a resource or a collection into its related presenter
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# present User.new(name: 'Remi') do |user|
|
54
|
+
# puts user.inspect # => #<UserPresenter object=#<User name="Remi>>
|
55
|
+
# puts user.name # => Remi
|
56
|
+
# end
|
57
|
+
def self.present(object, klass = self, &blk)
|
58
|
+
return if object.nil?
|
59
|
+
return object.map { |o| present(o, klass, &blk) } if object.respond_to?(:to_a) && !object.is_a?(Struct)
|
60
|
+
|
61
|
+
if object.is_a?(Bourgeois::Presenter)
|
62
|
+
presenter = object
|
63
|
+
else
|
64
|
+
klass ||= presenter_class(object)
|
65
|
+
end
|
66
|
+
|
67
|
+
presenter ||= klass.new(object, self)
|
68
|
+
yield presenter if block_given?
|
69
|
+
|
70
|
+
presenter
|
71
|
+
end
|
72
|
+
|
50
73
|
private
|
51
74
|
|
52
75
|
# Return the view from where the presenter was created
|
@@ -58,6 +81,13 @@ module Bourgeois
|
|
58
81
|
@klass ||= name.split(/Presenter$/).first.constantize
|
59
82
|
end
|
60
83
|
|
84
|
+
def self.presenter_class(object)
|
85
|
+
klass_name = "#{object.class}Presenter"
|
86
|
+
klass_name.constantize
|
87
|
+
rescue ::NameError
|
88
|
+
raise UnknownPresenter, klass_name
|
89
|
+
end
|
90
|
+
|
61
91
|
# Execute a helper block if it matches conditions
|
62
92
|
def execute_helper(block, opts)
|
63
93
|
if_condition = execute_helper_condition(opts[:if])
|
data/lib/bourgeois/version.rb
CHANGED
@@ -1,33 +1,7 @@
|
|
1
1
|
module Bourgeois
|
2
2
|
module ViewHelper
|
3
|
-
# Wrap a resource or a collection into its related presenter
|
4
|
-
#
|
5
|
-
# @example
|
6
|
-
# present User.new(name: 'Remi') do |user|
|
7
|
-
# puts user.inspect # => #<UserPresenter object=#<User name="Remi>>
|
8
|
-
# puts user.name # => Remi
|
9
|
-
# end
|
10
3
|
def present(object, klass = nil, &blk)
|
11
|
-
|
12
|
-
return object.map { |o| present(o, klass, &blk) } if object.respond_to?(:to_a) && !object.is_a?(Struct)
|
13
|
-
|
14
|
-
if object.is_a?(Bourgeois::Presenter)
|
15
|
-
presenter = object
|
16
|
-
else
|
17
|
-
klass ||= ViewHelper.presenter_class(object)
|
18
|
-
end
|
19
|
-
|
20
|
-
presenter ||= klass.new(object, self)
|
21
|
-
yield presenter if block_given?
|
22
|
-
|
23
|
-
presenter
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.presenter_class(object)
|
27
|
-
klass_name = "#{object.class}Presenter"
|
28
|
-
klass_name.constantize
|
29
|
-
rescue ::NameError
|
30
|
-
raise UnknownPresenter, klass_name
|
4
|
+
Bourgeois::Presenter.present(object, klass, &blk)
|
31
5
|
end
|
32
6
|
end
|
33
7
|
end
|
@@ -257,5 +257,160 @@ describe Bourgeois::Presenter do
|
|
257
257
|
|
258
258
|
it { expect(UserPresenter.human_attribute_name).to eql :foo }
|
259
259
|
end
|
260
|
+
|
261
|
+
describe :present do
|
262
|
+
let(:view) { ActionView::Base.new }
|
263
|
+
|
264
|
+
before do
|
265
|
+
class UserPresenter < Bourgeois::Presenter
|
266
|
+
def formatted_name
|
267
|
+
"#{first_name} #{last_name}".strip
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
class User < OpenStruct; end
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'on a Nil object' do
|
275
|
+
context 'without a block' do
|
276
|
+
it { expect { view.present(nil) }.not_to raise_error }
|
277
|
+
end
|
278
|
+
|
279
|
+
context 'with a block' do
|
280
|
+
before { UserPresenter.any_instance.should_receive(:formatted_name).never }
|
281
|
+
|
282
|
+
specify do
|
283
|
+
expect do
|
284
|
+
view.present(nil) { |obj| obj.formatted_name }
|
285
|
+
end.not_to raise_error
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
context 'on a single resource' do
|
291
|
+
let(:user) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
292
|
+
|
293
|
+
context 'without a block' do
|
294
|
+
it { expect(view.present(user).formatted_name).to eql 'Patrick Bourgeois' }
|
295
|
+
end
|
296
|
+
|
297
|
+
context 'with a block' do
|
298
|
+
specify do
|
299
|
+
view.present(user) do |u|
|
300
|
+
expect(u.formatted_name).to eql 'Patrick Bourgeois'
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'on a single already-presented resource' do
|
307
|
+
let(:user) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
308
|
+
let(:presenter) { UserPresenter.new(user) }
|
309
|
+
|
310
|
+
context 'without a block' do
|
311
|
+
it { expect(view.present(presenter).formatted_name).to eql 'Patrick Bourgeois' }
|
312
|
+
end
|
313
|
+
|
314
|
+
context 'with a block' do
|
315
|
+
specify do
|
316
|
+
view.present(presenter) do |u|
|
317
|
+
expect(u.formatted_name).to eql 'Patrick Bourgeois'
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'on a collection of resources' do
|
324
|
+
let(:user1) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
325
|
+
let(:user2) { User.new first_name: 'Francois', last_name: 'Jean' }
|
326
|
+
let(:user3) { User.new first_name: 'Alain', last_name: 'Lapointe' }
|
327
|
+
let(:users) { [user1, user2, user3] }
|
328
|
+
|
329
|
+
specify do
|
330
|
+
output = []
|
331
|
+
view.present(users) { |u| output << u.formatted_name }
|
332
|
+
|
333
|
+
expect(output).to eql ['Patrick Bourgeois', 'Francois Jean', 'Alain Lapointe']
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
context 'on a collection of already-presented resources' do
|
338
|
+
let(:user1) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
339
|
+
let(:user2) { User.new first_name: 'Francois', last_name: 'Jean' }
|
340
|
+
let(:user3) { User.new first_name: 'Alain', last_name: 'Lapointe' }
|
341
|
+
let(:users) { [UserPresenter.new(user1), UserPresenter.new(user2), UserPresenter.new(user3)] }
|
342
|
+
|
343
|
+
specify do
|
344
|
+
output = []
|
345
|
+
view.present(users) { |u| output << u.formatted_name }
|
346
|
+
|
347
|
+
expect(output).to eql ['Patrick Bourgeois', 'Francois Jean', 'Alain Lapointe']
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
context 'on a resource without a defined presenter class' do
|
352
|
+
before do
|
353
|
+
class Project < OpenStruct; end
|
354
|
+
end
|
355
|
+
|
356
|
+
let(:project) { Project.new name: 'Les B.B.' }
|
357
|
+
it { expect { view.present(project) }.to raise_error(Bourgeois::UnknownPresenter, 'unknown presenter class ProjectPresenter') }
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'on a resource with a custom presenter class' do
|
361
|
+
before do
|
362
|
+
class Article < OpenStruct; end
|
363
|
+
class CustomArticlePresenter < Bourgeois::Presenter
|
364
|
+
def name
|
365
|
+
super.upcase
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
let(:article) { Article.new name: 'Les B.B.' }
|
371
|
+
let(:presented_article) { view.present(article, CustomArticlePresenter) }
|
372
|
+
|
373
|
+
it { expect { presented_article }.not_to raise_error }
|
374
|
+
it { expect(presented_article.name).to eql 'LES B.B.' }
|
375
|
+
end
|
376
|
+
|
377
|
+
context 'on a Struct-based resource' do
|
378
|
+
before do
|
379
|
+
class Band < Struct.new(:name)
|
380
|
+
end
|
381
|
+
|
382
|
+
class BandPresenter < Bourgeois::Presenter
|
383
|
+
def name
|
384
|
+
super.upcase
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
let(:band) { Band.new('Les B.B.') }
|
390
|
+
let(:presented_band) { view.present(band) }
|
391
|
+
|
392
|
+
it { expect(presented_band.name).to eql 'LES B.B.' }
|
393
|
+
end
|
394
|
+
|
395
|
+
context 'on a collection of resources with a custom presenter class' do
|
396
|
+
before do
|
397
|
+
class Article < OpenStruct; end
|
398
|
+
class CustomArticlePresenter < Bourgeois::Presenter
|
399
|
+
def name
|
400
|
+
super.upcase
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
let(:articles) { [Article.new(name: 'Les B.B.'), Article.new(name: 'Rock et Belles Oreilles')] }
|
406
|
+
|
407
|
+
specify do
|
408
|
+
output = []
|
409
|
+
view.present(articles, CustomArticlePresenter) { |u| output << u.name }
|
410
|
+
|
411
|
+
expect(output).to eql ['LES B.B.', 'ROCK ET BELLES OREILLES']
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
260
415
|
end
|
261
416
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bourgeois
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rémi Prévost
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -134,7 +134,6 @@ files:
|
|
134
134
|
- lib/bourgeois/version.rb
|
135
135
|
- lib/bourgeois/view_helper.rb
|
136
136
|
- spec/bourgeois/presenter_spec.rb
|
137
|
-
- spec/bourgeois/view_helper_spec.rb
|
138
137
|
- spec/spec_helper.rb
|
139
138
|
homepage: https://github.com/mirego/bourgeois
|
140
139
|
licenses:
|
@@ -162,5 +161,4 @@ specification_version: 4
|
|
162
161
|
summary: Bourgeois is a Ruby library that makes using presenters a very simple thing.
|
163
162
|
test_files:
|
164
163
|
- spec/bourgeois/presenter_spec.rb
|
165
|
-
- spec/bourgeois/view_helper_spec.rb
|
166
164
|
- spec/spec_helper.rb
|
@@ -1,158 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Bourgeois::ViewHelper do
|
4
|
-
describe :present do
|
5
|
-
let(:view) { ActionView::Base.new }
|
6
|
-
|
7
|
-
before do
|
8
|
-
class UserPresenter < Bourgeois::Presenter
|
9
|
-
def formatted_name
|
10
|
-
"#{first_name} #{last_name}".strip
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class User < OpenStruct; end
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'on a Nil object' do
|
18
|
-
context 'without a block' do
|
19
|
-
it { expect { view.present(nil) }.not_to raise_error }
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'with a block' do
|
23
|
-
before { UserPresenter.any_instance.should_receive(:formatted_name).never }
|
24
|
-
|
25
|
-
specify do
|
26
|
-
expect do
|
27
|
-
view.present(nil) { |obj| obj.formatted_name }
|
28
|
-
end.not_to raise_error
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'on a single resource' do
|
34
|
-
let(:user) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
35
|
-
|
36
|
-
context 'without a block' do
|
37
|
-
it { expect(view.present(user).formatted_name).to eql 'Patrick Bourgeois' }
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'with a block' do
|
41
|
-
specify do
|
42
|
-
view.present(user) do |u|
|
43
|
-
expect(u.formatted_name).to eql 'Patrick Bourgeois'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'on a single already-presented resource' do
|
50
|
-
let(:user) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
51
|
-
let(:presenter) { UserPresenter.new(user) }
|
52
|
-
|
53
|
-
context 'without a block' do
|
54
|
-
it { expect(view.present(presenter).formatted_name).to eql 'Patrick Bourgeois' }
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'with a block' do
|
58
|
-
specify do
|
59
|
-
view.present(presenter) do |u|
|
60
|
-
expect(u.formatted_name).to eql 'Patrick Bourgeois'
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context 'on a collection of resources' do
|
67
|
-
let(:user1) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
68
|
-
let(:user2) { User.new first_name: 'Francois', last_name: 'Jean' }
|
69
|
-
let(:user3) { User.new first_name: 'Alain', last_name: 'Lapointe' }
|
70
|
-
let(:users) { [user1, user2, user3] }
|
71
|
-
|
72
|
-
specify do
|
73
|
-
output = []
|
74
|
-
view.present(users) { |u| output << u.formatted_name }
|
75
|
-
|
76
|
-
expect(output).to eql ['Patrick Bourgeois', 'Francois Jean', 'Alain Lapointe']
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'on a collection of already-presented resources' do
|
81
|
-
let(:user1) { User.new first_name: 'Patrick', last_name: 'Bourgeois' }
|
82
|
-
let(:user2) { User.new first_name: 'Francois', last_name: 'Jean' }
|
83
|
-
let(:user3) { User.new first_name: 'Alain', last_name: 'Lapointe' }
|
84
|
-
let(:users) { [UserPresenter.new(user1), UserPresenter.new(user2), UserPresenter.new(user3)] }
|
85
|
-
|
86
|
-
specify do
|
87
|
-
output = []
|
88
|
-
view.present(users) { |u| output << u.formatted_name }
|
89
|
-
|
90
|
-
expect(output).to eql ['Patrick Bourgeois', 'Francois Jean', 'Alain Lapointe']
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
context 'on a resource without a defined presenter class' do
|
95
|
-
before do
|
96
|
-
class Project < OpenStruct; end
|
97
|
-
end
|
98
|
-
|
99
|
-
let(:project) { Project.new name: 'Les B.B.' }
|
100
|
-
it { expect { view.present(project) }.to raise_error(Bourgeois::UnknownPresenter, 'unknown presenter class ProjectPresenter') }
|
101
|
-
end
|
102
|
-
|
103
|
-
context 'on a resource with a custom presenter class' do
|
104
|
-
before do
|
105
|
-
class Article < OpenStruct; end
|
106
|
-
class CustomArticlePresenter < Bourgeois::Presenter
|
107
|
-
def name
|
108
|
-
super.upcase
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
let(:article) { Article.new name: 'Les B.B.' }
|
114
|
-
let(:presented_article) { view.present(article, CustomArticlePresenter) }
|
115
|
-
|
116
|
-
it { expect { presented_article }.not_to raise_error }
|
117
|
-
it { expect(presented_article.name).to eql 'LES B.B.' }
|
118
|
-
end
|
119
|
-
|
120
|
-
context 'on a Struct-based resource' do
|
121
|
-
before do
|
122
|
-
class Band < Struct.new(:name)
|
123
|
-
end
|
124
|
-
|
125
|
-
class BandPresenter < Bourgeois::Presenter
|
126
|
-
def name
|
127
|
-
super.upcase
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
let(:band) { Band.new('Les B.B.') }
|
133
|
-
let(:presented_band) { view.present(band) }
|
134
|
-
|
135
|
-
it { expect(presented_band.name).to eql 'LES B.B.' }
|
136
|
-
end
|
137
|
-
|
138
|
-
context 'on a collection of resources with a custom presenter class' do
|
139
|
-
before do
|
140
|
-
class Article < OpenStruct; end
|
141
|
-
class CustomArticlePresenter < Bourgeois::Presenter
|
142
|
-
def name
|
143
|
-
super.upcase
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
let(:articles) { [Article.new(name: 'Les B.B.'), Article.new(name: 'Rock et Belles Oreilles')] }
|
149
|
-
|
150
|
-
specify do
|
151
|
-
output = []
|
152
|
-
view.present(articles, CustomArticlePresenter) { |u| output << u.name }
|
153
|
-
|
154
|
-
expect(output).to eql ['LES B.B.', 'ROCK ET BELLES OREILLES']
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|