Skip to content

Commit

Permalink
Basic Introspection
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
teliosdev committed Nov 22, 2014
1 parent 8fd0a49 commit a0aeddd
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 0 deletions.
68 changes: 68 additions & 0 deletions lib/curly/presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ def presenter_for_name(name)
end
end

def presenter_for?(name)
presenter_for_name(name)
true
rescue NameError
false
end

# Whether a component is available to templates rendered with the
# presenter.
#
Expand Down Expand Up @@ -215,6 +222,67 @@ def available_components
methods.map(&:to_s)
end

# Gives a description of the presenter. Gives information about its
# components, and what parameters they are allowed.
#
# Returns a Hash.
def description
result = {}
components = result[:components] = []

available_components.each do |component|
data = { name: component,
type: "",
attributes: [],
identifier: nil,
block: false }

if component.end_with?("?")
data[:type] = "conditional"
elsif presenter_for?(component)
data[:type] = "context"
elsif presenter_for?(component.singularize)
data[:type] = "collection"
else
data[:type] = "value"
end

instance_method(component.intern).parameters.each do |param|
add = {}
add[:name] = param[1].to_s

case param[0]
when :keyreq
add[:type] = "keyword"
add[:required] = true
when :key
add[:type] = "keyword"
add[:required] = false
when :req
data[:identifier] = add
add[:required] = true
add = nil
when :opt
data[:identifier] = add
add[:required] = false
add = nil
when :block
data[:block] = add[:name]
add = nil
else
add[:type] = "unknown"
add[:required] = false
end

data[:attributes] << add if add
end

components << data
end

result
end

# The set of view paths that the presenter depends on.
#
# Examples
Expand Down
86 changes: 86 additions & 0 deletions spec/presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ def monkey
presents :elephant, default: "Dumbo"

attr_reader :midget, :clown, :elephant

def alpha(name, age: 12)
name
end

def beta(test:, this: "thing")
test + this
end

def charlie(&test)
end

def delta?
false
end

def cats
end

class CatPresenter < Curly::Presenter; end
end

class FrenchCircusPresenter < CircusPresenter
Expand Down Expand Up @@ -112,6 +132,72 @@ class CircusPresenter::MonkeyPresenter < Curly::Presenter
end
end

describe ".description" do
it "gives a hash" do
CircusPresenter.description.should be_a Hash
end

it "describes the components" do
description = CircusPresenter.description

description[:components].should have(9).items
description[:components].should == [
{ name: "midget",
type: "value",
attributes: [],
identifier: nil,
block: false },
{ name: "clown",
type: "value",
attributes: [],
identifier: nil,
block: false },
{ name: "elephant",
type: "value",
attributes: [],
identifier: nil,
block: false },

{ name: "alpha",
type: "value",
attributes: [
{ name: "age", type: "keyword", required: false }],
identifier: { name: "name", required: true },
block: false },

{ name: "beta",
type: "value",
attributes: [
{ name: "test", type: "keyword", required: true },
{ name: "this", type: "keyword", required: false }],
identifier: nil,
block: false },

{ name: "charlie",
type: "value",
attributes: [],
identifier: nil,
block: "test" },

{ name: "delta?",
type: "conditional",
attributes: [],
identifier: nil,
block: false },
{ name: "cats",
type: "collection",
attributes: [],
identifier: nil,
block: false },
{ name: "monkey",
type: "context",
attributes: [],
identifier: nil,
block: false }
]
end
end

describe ".version" do
it "sets the version of the presenter" do
presenter1 = Class.new(Curly::Presenter) do
Expand Down

0 comments on commit a0aeddd

Please sign in to comment.