Skip to content

Commit 415a064

Browse files
committed
Basic Introspection
Adds a #description method to Curly::Presenter that returns information about the components that the presenter has available. Also adds a #presenter_for? method that looks for a presenter, if it exists, and returns true if it does.
1 parent 8fd0a49 commit 415a064

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

lib/curly/presenter.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ def presenter_for_name(name)
188188
end
189189
end
190190

191+
def presenter_for?(name)
192+
presenter_for_name(name)
193+
true
194+
rescue NameError
195+
false
196+
end
197+
191198
# Whether a component is available to templates rendered with the
192199
# presenter.
193200
#
@@ -215,6 +222,64 @@ def available_components
215222
methods.map(&:to_s)
216223
end
217224

225+
# Gives a description of the presenter. Gives information about its
226+
# components, and what parameters they are allowed.
227+
#
228+
# Returns a Hash.
229+
def description
230+
result = {}
231+
components = result[:components] = []
232+
233+
available_components.each do |component|
234+
data = { name: component,
235+
type: "",
236+
attributes: [],
237+
identifier: nil,
238+
block: false }
239+
240+
if component.end_with?("?")
241+
data[:type] = "conditional"
242+
elsif presenter_for?(component)
243+
data[:type] = "context"
244+
elsif presenter_for?(component.singularize)
245+
data[:type] = "collection"
246+
else
247+
data[:type] = "value"
248+
end
249+
250+
instance_method(component.intern).parameters.each do |param|
251+
add = {}
252+
add[:name] = param[1].to_s
253+
254+
case param[0]
255+
when :keyreq
256+
add[:required] = true
257+
when :key
258+
add[:required] = false
259+
when :req
260+
data[:identifier] = add
261+
add[:required] = true
262+
add = nil
263+
when :opt
264+
data[:identifier] = add
265+
add[:required] = false
266+
add = nil
267+
when :block
268+
data[:block] = add[:name]
269+
add = nil
270+
else
271+
raise ArgumentError, "Unknown parameter #{param[0]}"
272+
end
273+
274+
data[:attributes] << add if add
275+
end
276+
277+
components << data
278+
end
279+
280+
result
281+
end
282+
218283
# The set of view paths that the presenter depends on.
219284
#
220285
# Examples

spec/presenter_spec.rb

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@ def monkey
1313
presents :elephant, default: "Dumbo"
1414

1515
attr_reader :midget, :clown, :elephant
16+
17+
def alpha(name, age: 12)
18+
name
19+
end
20+
21+
def beta(test:, this: "thing")
22+
test + this
23+
end
24+
25+
def charlie(&test)
26+
end
27+
28+
def delta?
29+
false
30+
end
31+
32+
def cats
33+
end
34+
35+
class CatPresenter < Curly::Presenter; end
1636
end
1737

1838
class FrenchCircusPresenter < CircusPresenter
@@ -112,6 +132,72 @@ class CircusPresenter::MonkeyPresenter < Curly::Presenter
112132
end
113133
end
114134

135+
describe ".description" do
136+
it "gives a hash" do
137+
CircusPresenter.description.should be_a Hash
138+
end
139+
140+
it "describes the components" do
141+
description = CircusPresenter.description
142+
143+
description[:components].should have(9).items
144+
description[:components].should == [
145+
{ name: "midget",
146+
type: "value",
147+
attributes: [],
148+
identifier: nil,
149+
block: false },
150+
{ name: "clown",
151+
type: "value",
152+
attributes: [],
153+
identifier: nil,
154+
block: false },
155+
{ name: "elephant",
156+
type: "value",
157+
attributes: [],
158+
identifier: nil,
159+
block: false },
160+
161+
{ name: "alpha",
162+
type: "value",
163+
attributes: [
164+
{ name: "age", required: false }],
165+
identifier: { name: "name", required: true },
166+
block: false },
167+
168+
{ name: "beta",
169+
type: "value",
170+
attributes: [
171+
{ name: "test", required: true },
172+
{ name: "this", required: false }],
173+
identifier: nil,
174+
block: false },
175+
176+
{ name: "charlie",
177+
type: "value",
178+
attributes: [],
179+
identifier: nil,
180+
block: "test" },
181+
182+
{ name: "delta?",
183+
type: "conditional",
184+
attributes: [],
185+
identifier: nil,
186+
block: false },
187+
{ name: "cats",
188+
type: "collection",
189+
attributes: [],
190+
identifier: nil,
191+
block: false },
192+
{ name: "monkey",
193+
type: "context",
194+
attributes: [],
195+
identifier: nil,
196+
block: false }
197+
]
198+
end
199+
end
200+
115201
describe ".version" do
116202
it "sets the version of the presenter" do
117203
presenter1 = Class.new(Curly::Presenter) do

0 commit comments

Comments
 (0)