presentability 0.2.0 → 0.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.md +8 -0
- data/lib/presentability/presenter.rb +39 -29
- data/lib/presentability.rb +1 -1
- data/spec/presentability_spec.rb +63 -4
- data.tar.gz.sig +0 -0
- metadata +7 -7
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff4d9944824eaaa9ef6bc0d5e2b02879e83c481f2db9a39fe6c6ebc6f947dd7f
|
4
|
+
data.tar.gz: 4ccd0e65bdaae2504bf6edad1df4aab25698d5290b740028c5f5dc7c78732302
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cae40ce72cd721000c47cff537ba2a2ac6635fc27205f79d81548471efda66b499c9aadd8eab97049a457dbd1c784e20ec5cd01805a57c511e1da808517c5ab8
|
7
|
+
data.tar.gz: 73ccbe66aeeed78447ae7cb91a0bb9cdbe95325d834e6fcfc6baaa4c96103cfb03efa4ef55f3718098ad021f211c17d5365f2e528b0dc5e846570ff6bec3407d
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
# Release History for presentability
|
2
2
|
|
3
3
|
---
|
4
|
+
## v0.3.0 [2022-12-16] Michael Granger <ged@faeriemud.org>
|
5
|
+
|
6
|
+
Improvements:
|
7
|
+
|
8
|
+
- Rework to use a more flexible exposure mechanism
|
9
|
+
- Allows `nil` and `false` as exposed values
|
10
|
+
- Allows declaring an exposure with a block
|
11
|
+
|
4
12
|
|
5
13
|
## v0.2.0 [2022-12-06] Michael Granger <ged@faeriemud.org>
|
6
14
|
|
@@ -69,14 +69,50 @@ class Presentability::Presenter
|
|
69
69
|
|
70
70
|
### Set up an exposure that will delegate to the attribute of the subject with
|
71
71
|
### the given +name+.
|
72
|
-
def self::expose( name, **options )
|
72
|
+
def self::expose( name, **options, &block )
|
73
|
+
name = name.to_sym
|
73
74
|
options = DEFAULT_EXPOSURE_OPTIONS.merge( options )
|
74
75
|
|
75
|
-
self.
|
76
|
+
self.define_method( name, &block ) if block
|
77
|
+
|
78
|
+
unless self.instance_methods( true ).include?( name )
|
79
|
+
method_body = self.generate_expose_method( name, **options )
|
80
|
+
define_method( name, &method_body )
|
81
|
+
end
|
82
|
+
|
83
|
+
self.log.debug "Setting up exposure %p, options = %p" % [ name, options ]
|
76
84
|
self.exposures[ name ] = options
|
77
85
|
end
|
78
86
|
|
79
87
|
|
88
|
+
### Generate the body an exposure method that delegates to a method with the
|
89
|
+
### same +name+ on its subject.
|
90
|
+
def self::generate_expose_method( name, **options )
|
91
|
+
self.log.debug "Generating a default delegation exposure method for %p" % [ name ]
|
92
|
+
return lambda do
|
93
|
+
return self.subject.send( __method__ )
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
### Method definition hook -- hook up new methods with the same name as an exposure
|
99
|
+
### to its :call option.
|
100
|
+
def self::method_added( method_name )
|
101
|
+
super
|
102
|
+
|
103
|
+
return unless self.exposures
|
104
|
+
|
105
|
+
if self.exposures.key?( method_name )
|
106
|
+
self.log.debug "Exposing %p via a new presenter method." % [ method_name ]
|
107
|
+
self.exposures[ method_name ][ :call ] = self.instance_method( method_name )
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
#
|
113
|
+
# Instance methods
|
114
|
+
#
|
115
|
+
|
80
116
|
### Create a new Presenter for the given +subject+.
|
81
117
|
def initialize( subject, options={} )
|
82
118
|
@subject = subject
|
@@ -104,11 +140,7 @@ class Presentability::Presenter
|
|
104
140
|
|
105
141
|
self.class.exposures.each do |name, exposure_options|
|
106
142
|
next if self.skip_exposure?( name )
|
107
|
-
|
108
|
-
value = self.expose_via_delegation( name, exposure_options ) ||
|
109
|
-
self.expose_via_presenter_method( name, exposure_options ) or
|
110
|
-
raise NoMethodError, "can't expose %p -- no such attribute exists" % [name]
|
111
|
-
|
143
|
+
value = self.method( name ).call
|
112
144
|
result[ name.to_sym ] = value
|
113
145
|
end
|
114
146
|
|
@@ -143,27 +175,5 @@ class Presentability::Presenter
|
|
143
175
|
end
|
144
176
|
|
145
177
|
|
146
|
-
### Attempt to expose the attribute with the given +name+ via delegation to the
|
147
|
-
### subject's method of the same name. Returns +nil+ if no such method exists.
|
148
|
-
def expose_via_delegation( name, options={} )
|
149
|
-
self.log.debug "Trying to expose %p via delegation to %p" % [ name, self.subject ]
|
150
|
-
|
151
|
-
return nil unless self.subject.respond_to?( name )
|
152
|
-
|
153
|
-
return self.subject.send( name )
|
154
|
-
end
|
155
|
-
|
156
|
-
|
157
|
-
### Attempt to expose the attribute with the given +name+ via a method on the presenter
|
158
|
-
### of the same name. Returns +nil+ if no such method exists.
|
159
|
-
def expose_via_presenter_method( name, options={} )
|
160
|
-
self.log.debug "Trying to expose %p via presenter method" % [ name ]
|
161
|
-
|
162
|
-
return nil unless self.respond_to?( name )
|
163
|
-
|
164
|
-
meth = self.method( name )
|
165
|
-
return meth.call
|
166
|
-
end
|
167
|
-
|
168
178
|
end # class Presentability::Presenter
|
169
179
|
|
data/lib/presentability.rb
CHANGED
data/spec/presentability_spec.rb
CHANGED
@@ -37,14 +37,22 @@ RSpec.describe Presentability do
|
|
37
37
|
@lastname = lastname
|
38
38
|
@email = email
|
39
39
|
@password = password
|
40
|
+
@is_admin = false
|
40
41
|
end
|
41
42
|
|
42
|
-
attr_accessor :firstname, :lastname, :email, :password
|
43
|
+
attr_accessor :firstname, :lastname, :email, :password, :is_admin
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
47
|
let( :entity_instance ) { entity_class.new }
|
47
|
-
let( :other_entity_instance )
|
48
|
+
let( :other_entity_instance ) do
|
49
|
+
other_entity_class.new(
|
50
|
+
Faker::Name.first_name,
|
51
|
+
Faker::Name.last_name,
|
52
|
+
Faker::Internet.email,
|
53
|
+
Faker::Internet.password
|
54
|
+
)
|
55
|
+
end
|
48
56
|
|
49
57
|
|
50
58
|
describe "an extended module" do
|
@@ -75,7 +83,7 @@ RSpec.describe Presentability do
|
|
75
83
|
end
|
76
84
|
|
77
85
|
|
78
|
-
it "can
|
86
|
+
it "can define more complex exposures by declaring presenter methods" do
|
79
87
|
extended_module.presenter_for( entity_class ) do
|
80
88
|
expose :foo
|
81
89
|
expose :bar
|
@@ -91,6 +99,56 @@ RSpec.describe Presentability do
|
|
91
99
|
end
|
92
100
|
|
93
101
|
|
102
|
+
it "calls an exposure's block if it has one" do
|
103
|
+
extended_module.presenter_for( entity_class ) do
|
104
|
+
expose :foo
|
105
|
+
expose :bar
|
106
|
+
expose :id do
|
107
|
+
self.subject.object_id
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
expect( extended_module.present(entity_instance) ).
|
112
|
+
to eq({ foo: 1, bar: 'two', id: entity_instance.object_id })
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
it "exposes `false' values correctly" do
|
117
|
+
extended_module.presenter_for( other_entity_class ) do
|
118
|
+
expose :firstname
|
119
|
+
expose :lastname
|
120
|
+
expose :email
|
121
|
+
expose :is_admin
|
122
|
+
end
|
123
|
+
|
124
|
+
other_entity_instance.is_admin = false
|
125
|
+
|
126
|
+
expect( extended_module.present(other_entity_instance) ).to eq({
|
127
|
+
firstname: other_entity_instance.firstname,
|
128
|
+
lastname: other_entity_instance.lastname,
|
129
|
+
email: other_entity_instance.email,
|
130
|
+
is_admin: false
|
131
|
+
})
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
it "exposes `nil' values correctly" do
|
136
|
+
extended_module.presenter_for( other_entity_class ) do
|
137
|
+
expose :firstname
|
138
|
+
expose :lastname
|
139
|
+
expose :email
|
140
|
+
end
|
141
|
+
|
142
|
+
other_entity_instance.email = nil
|
143
|
+
|
144
|
+
expect( extended_module.present(other_entity_instance) ).to eq({
|
145
|
+
firstname: other_entity_instance.firstname,
|
146
|
+
lastname: other_entity_instance.lastname,
|
147
|
+
email: nil
|
148
|
+
})
|
149
|
+
end
|
150
|
+
|
151
|
+
|
94
152
|
it "can be made conditional on an option being set" do
|
95
153
|
extended_module.presenter_for( entity_class ) do
|
96
154
|
expose :foo
|
@@ -119,10 +177,11 @@ RSpec.describe Presentability do
|
|
119
177
|
|
120
178
|
expect {
|
121
179
|
extended_module.present( entity_instance )
|
122
|
-
}.to raise_error( NoMethodError, /
|
180
|
+
}.to raise_error( NoMethodError, /undefined method `id'/i )
|
123
181
|
end
|
124
182
|
|
125
183
|
|
184
|
+
|
126
185
|
describe "collection handling" do
|
127
186
|
|
128
187
|
it "can present a collection" do
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: presentability
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -33,7 +33,7 @@ cert_chain:
|
|
33
33
|
P5YP5BAbNW+gvd3QHRiWTTuhgHrdDnGdXg93N2M5KHn1ug8BtPLQwlcFwEpKnlLn
|
34
34
|
btEP+7EplFuoiMfd
|
35
35
|
-----END CERTIFICATE-----
|
36
|
-
date: 2022-12-
|
36
|
+
date: 2022-12-16 00:00:00.000000000 Z
|
37
37
|
dependencies:
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: loggability
|
@@ -69,28 +69,28 @@ dependencies:
|
|
69
69
|
requirements:
|
70
70
|
- - "~>"
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version: '0.
|
72
|
+
version: '0.21'
|
73
73
|
type: :development
|
74
74
|
prerelease: false
|
75
75
|
version_requirements: !ruby/object:Gem::Requirement
|
76
76
|
requirements:
|
77
77
|
- - "~>"
|
78
78
|
- !ruby/object:Gem::Version
|
79
|
-
version: '0.
|
79
|
+
version: '0.21'
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
|
-
name: rdoc-generator-
|
81
|
+
name: rdoc-generator-sixfish
|
82
82
|
requirement: !ruby/object:Gem::Requirement
|
83
83
|
requirements:
|
84
84
|
- - "~>"
|
85
85
|
- !ruby/object:Gem::Version
|
86
|
-
version: '0.
|
86
|
+
version: '0.2'
|
87
87
|
type: :development
|
88
88
|
prerelease: false
|
89
89
|
version_requirements: !ruby/object:Gem::Requirement
|
90
90
|
requirements:
|
91
91
|
- - "~>"
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '0.
|
93
|
+
version: '0.2'
|
94
94
|
description: Facade-based presenters with minimal assumptions. This library contains
|
95
95
|
utilities for setting up presenters for data classes for things like web services,
|
96
96
|
logging output, etc.
|
metadata.gz.sig
CHANGED
Binary file
|