catwalk 0.0.1
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.
- data/.autotest +17 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/catwalk.gemspec +27 -0
- data/cucumber.yml +3 -0
- data/features/active_model_compatibility.feature +11 -0
- data/features/basic_fields.feature +11 -0
- data/features/specifying_model_accessor.feature +10 -0
- data/features/step_definitions/model_steps.rb +9 -0
- data/features/step_definitions/presenter_steps.rb +46 -0
- data/features/support/active_model_example.rb +23 -0
- data/features/support/env.rb +2 -0
- data/lib/catwalk.rb +1 -0
- data/lib/catwalk/presenter.rb +35 -0
- data/lib/catwalk/version.rb +3 -0
- data/spec/catwalk/presenter_spec.rb +74 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/active_model_lint.rb +33 -0
- data/spec/support/active_model_proxy_shared_examples.rb +17 -0
- metadata +173 -0
data/.autotest
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'autotest/fsevent'
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
|
6
|
+
Autotest.add_hook :initialize do |at|
|
7
|
+
|
8
|
+
at.add_exception /^(?:\.\/)?\.git/
|
9
|
+
at.add_exception /^(?:\.\/)?\.bundle/
|
10
|
+
at.add_exception /^(?:\.\/)?tmp/
|
11
|
+
|
12
|
+
at.add_mapping(/^.autotest$/,true) { |_,_|
|
13
|
+
Dir["spec/**/*_spec.rb"]
|
14
|
+
}
|
15
|
+
|
16
|
+
nil
|
17
|
+
end
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/catwalk.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "catwalk/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "catwalk"
|
7
|
+
s.version = Catwalk::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Jon Rowe"]
|
10
|
+
s.email = ["hello@jonrowe.co.uk"]
|
11
|
+
s.homepage = "http://github.com/jonrowe/catwalk"
|
12
|
+
s.summary = %q{Catwalk is a gem for showing off models. It allows you to seperate presentation logic from data models.}
|
13
|
+
s.description = %q{Catwalk is a gem for showing off models. It allows you to seperate presentation logic from data models.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {spec,features}/* .autotest`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_development_dependency 'rspec'
|
21
|
+
s.add_development_dependency 'cucumber'
|
22
|
+
s.add_development_dependency 'ruby-debug19'
|
23
|
+
s.add_development_dependency 'autotest-standalone'
|
24
|
+
s.add_development_dependency 'autotest-fsevent' if RUBY_PLATFORM =~ /darwin/
|
25
|
+
|
26
|
+
s.add_development_dependency 'activemodel'
|
27
|
+
end
|
data/cucumber.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Active Model compatibility
|
2
|
+
In order to use presenters interchangably with active models
|
3
|
+
As a developer
|
4
|
+
I wish to use catwalk to present my models whilst adhering to ActiveModel::Lint
|
5
|
+
|
6
|
+
Scenario: Basic Active Model functionality
|
7
|
+
Given I have an ActiveModel based model
|
8
|
+
And I have a presenter class
|
9
|
+
When I include Catwalk
|
10
|
+
And I setup my presenter to represent my model
|
11
|
+
Then my presenter should expose the models ActiveModel functionality
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Presenting basic fields from an active model compatible model
|
2
|
+
In order to seperate my presentation logic from my persistance models
|
3
|
+
As a developer
|
4
|
+
I want to wrap my models in a catwalk presenter
|
5
|
+
|
6
|
+
Scenario: Basic usage
|
7
|
+
Given I have an ActiveModel based model
|
8
|
+
And my model has a attribute named "title"
|
9
|
+
And I have a Catwalk presenter class for my model
|
10
|
+
When I define a field "title"
|
11
|
+
Then my presenter should present "title" from my model
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Feature: Specifying model accessor
|
2
|
+
In order to access the underlying model in my presenter methods
|
3
|
+
As a developer
|
4
|
+
I want to specify an accessor I will use to access the undelying model
|
5
|
+
|
6
|
+
Scenario: Specifiying accessor
|
7
|
+
Given I have an ActiveModel based model
|
8
|
+
And I have a Catwalk presenter class for my model
|
9
|
+
When I set access_as to "my_model"
|
10
|
+
Then my presenter should expose the model via "my_model"
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Given "I have a presenter class" do
|
2
|
+
@presenter_klass = Class.new
|
3
|
+
end
|
4
|
+
|
5
|
+
Given "I have a Catwalk presenter class for my model" do
|
6
|
+
klass = Class.new
|
7
|
+
klass.send :include, Catwalk::Presenter
|
8
|
+
@presenter = klass.new @model
|
9
|
+
end
|
10
|
+
|
11
|
+
When "I include Catwalk" do
|
12
|
+
@presenter_klass.send :include, Catwalk::Presenter
|
13
|
+
end
|
14
|
+
|
15
|
+
When "I setup my presenter to represent my model" do
|
16
|
+
@presenter = @presenter_klass.new(@model)
|
17
|
+
end
|
18
|
+
|
19
|
+
When /^I define a field "([^"]*)"$/ do |field_name|
|
20
|
+
@presenter.class.class_eval do
|
21
|
+
field field_name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
When /^I set access_as to "([^"]*)"$/ do |accessor|
|
26
|
+
@presenter.class.class_eval do
|
27
|
+
access_as accessor
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Then "my presenter should expose the models ActiveModel functionality" do
|
32
|
+
@presenter.to_key.should == @model.to_key
|
33
|
+
@presenter.to_param.should == @model.to_param
|
34
|
+
@presenter.valid?.should == @model.valid?
|
35
|
+
@presenter.persisted?.should == @model.persisted?
|
36
|
+
@presenter.errors.should == @model.errors
|
37
|
+
@presenter.to_model.should == @model
|
38
|
+
end
|
39
|
+
|
40
|
+
Then /^my presenter should present "([^"]*)" from my model$/ do |field_name|
|
41
|
+
@presenter.send(field_name).should == @model.send(field_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
Then /^my presenter should expose the model via "([^"]*)"$/ do |field_name|
|
45
|
+
@presenter.send(field_name).should == @model
|
46
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
class ActiveModelExample
|
4
|
+
extend ActiveModel::Naming
|
5
|
+
|
6
|
+
attr_reader :errors
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@errors = ActiveModel::Errors.new(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_model
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_key; {}; end
|
17
|
+
def to_param; {}; end
|
18
|
+
def valid?; true; end
|
19
|
+
def new_record?; true; end
|
20
|
+
def destroyed?; true; end
|
21
|
+
def persisted?; true; end
|
22
|
+
end
|
23
|
+
|
data/lib/catwalk.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'catwalk/presenter'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Catwalk
|
2
|
+
module Presenter
|
3
|
+
def self.included(base)
|
4
|
+
base.send :extend, ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(model)
|
8
|
+
@model = model
|
9
|
+
end
|
10
|
+
|
11
|
+
define_method(:to_model) { @model }
|
12
|
+
define_method(:to_param) { @model.to_param if persisted? }
|
13
|
+
define_method(:to_key) { @model.to_key if persisted? }
|
14
|
+
define_method(:persisted?) { @model.persisted? }
|
15
|
+
define_method(:valid?) { @model.valid? }
|
16
|
+
define_method(:model_name) { @model.model_name }
|
17
|
+
define_method(:errors) { @model.errors }
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
def field(field_name)
|
22
|
+
define_method field_name do
|
23
|
+
@model.send field_name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def access_as(accessor)
|
28
|
+
define_method accessor do
|
29
|
+
@model
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Catwalk
|
4
|
+
describe Presenter do
|
5
|
+
|
6
|
+
let(:model) { mock "model" }
|
7
|
+
let(:klass) { Class.new }
|
8
|
+
let(:presenter) { klass.new(model) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
klass.class_eval { include Catwalk::Presenter }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "initialization" do
|
15
|
+
subject { presenter }
|
16
|
+
|
17
|
+
it "should assign an the model to an instance variable accessible via to_model" do
|
18
|
+
subject.to_model.should == model
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "active model compliance" do
|
23
|
+
let(:model_name) { mock 'model_name', human: "Model Name", singular: "model_name", plural: "Model Names", partial_path: '/model' }
|
24
|
+
let(:active_model_errors) { mock "errors", full_messages: [], :[] => [] }
|
25
|
+
let(:model) { mock "model", to_key: {}, to_param: {}, valid?: true, persisted?: true, model_name: model_name, errors: active_model_errors }
|
26
|
+
|
27
|
+
before do
|
28
|
+
model_name.stub(:kind_of?).with(String).and_return(true)
|
29
|
+
end
|
30
|
+
subject { presenter }
|
31
|
+
|
32
|
+
it_should_behave_like "ActiveModel"
|
33
|
+
it_should_behave_like "proxy active_model method", :to_key, from: :model
|
34
|
+
it_should_behave_like "proxy active_model method", :to_param, from: :model
|
35
|
+
it_should_behave_like "proxy active_model method", :valid?, from: :model
|
36
|
+
it_should_behave_like "proxy active_model method", :persisted?, from: :model
|
37
|
+
it_should_behave_like "proxy active_model method", :model_name, from: :model
|
38
|
+
it_should_behave_like "proxy active_model method", :errors, from: :model
|
39
|
+
its(:to_model) { should == model }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "access_as" do
|
43
|
+
subject do
|
44
|
+
klass.class_eval do
|
45
|
+
access_as :model_accessor
|
46
|
+
end
|
47
|
+
presenter
|
48
|
+
end
|
49
|
+
|
50
|
+
its(:model_accessor) { should == model }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "field" do
|
54
|
+
let(:model_value) { "a value" }
|
55
|
+
|
56
|
+
before do
|
57
|
+
model.stub(:a_field).and_return(model_value)
|
58
|
+
end
|
59
|
+
|
60
|
+
subject do
|
61
|
+
klass.class_eval do
|
62
|
+
field :a_field
|
63
|
+
end
|
64
|
+
presenter.a_field
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should proxy field to model" do
|
68
|
+
model.should_receive(:a_field).and_return(model_value)
|
69
|
+
subject
|
70
|
+
end
|
71
|
+
it { should == model_value }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# spec/support/active_model_lint.rb
|
2
|
+
# adapted from rspec-rails: http://github.com/rspec/rspec-rails/blob/master/spec/rspec/rails/mocks/mock_model_spec.rb
|
3
|
+
|
4
|
+
shared_examples_for "ActiveModel" do
|
5
|
+
|
6
|
+
it { should respond_to :to_key }
|
7
|
+
it { should respond_to :to_param }
|
8
|
+
it { should respond_to :valid? }
|
9
|
+
it { should respond_to :persisted? }
|
10
|
+
it { should respond_to :model_name }
|
11
|
+
it { should respond_to :errors }
|
12
|
+
it { should respond_to :to_model }
|
13
|
+
|
14
|
+
its(:"model_name") { should be_a String }
|
15
|
+
its(:"model_name.human") { should be_a String }
|
16
|
+
its(:"model_name.partial_path") { should be_a String }
|
17
|
+
its(:"model_name.singular") { should be_a String }
|
18
|
+
its(:"model_name.plural") { should be_a String }
|
19
|
+
|
20
|
+
its(:"errors.full_messages") { should be_a Array }
|
21
|
+
it "should have blank arrays for keys" do
|
22
|
+
subject.errors[:hello].should == []
|
23
|
+
end
|
24
|
+
|
25
|
+
context "where not persisted" do
|
26
|
+
before do
|
27
|
+
subject.stub(:persisted?).and_return(false)
|
28
|
+
end
|
29
|
+
|
30
|
+
its(:to_key) { should be_nil }
|
31
|
+
its(:to_param) { should be_nil }
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
shared_examples_for "proxy active_model method" do |method,opts|
|
2
|
+
let(:target) { send opts[:from] }
|
3
|
+
let(:target_value) { mock "value" }
|
4
|
+
|
5
|
+
before do
|
6
|
+
target.stub(method).and_return(target_value)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should proxy #{method} to #{opts[:from]}" do
|
10
|
+
target.should_receive(method).and_return(target_value)
|
11
|
+
subject.send(method)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "#{method} should == #{opts[:from]}.value" do
|
15
|
+
subject.send(method).should == target_value
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: catwalk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jon Rowe
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-23 00:00:00 +00:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: cucumber
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: ruby-debug19
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: autotest-standalone
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
type: :development
|
71
|
+
version_requirements: *id004
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: autotest-fsevent
|
74
|
+
prerelease: false
|
75
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id005
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: activemodel
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
type: :development
|
97
|
+
version_requirements: *id006
|
98
|
+
description: Catwalk is a gem for showing off models. It allows you to seperate presentation logic from data models.
|
99
|
+
email:
|
100
|
+
- hello@jonrowe.co.uk
|
101
|
+
executables: []
|
102
|
+
|
103
|
+
extensions: []
|
104
|
+
|
105
|
+
extra_rdoc_files: []
|
106
|
+
|
107
|
+
files:
|
108
|
+
- .autotest
|
109
|
+
- .gitignore
|
110
|
+
- .rspec
|
111
|
+
- Gemfile
|
112
|
+
- Rakefile
|
113
|
+
- catwalk.gemspec
|
114
|
+
- cucumber.yml
|
115
|
+
- features/active_model_compatibility.feature
|
116
|
+
- features/basic_fields.feature
|
117
|
+
- features/specifying_model_accessor.feature
|
118
|
+
- features/step_definitions/model_steps.rb
|
119
|
+
- features/step_definitions/presenter_steps.rb
|
120
|
+
- features/support/active_model_example.rb
|
121
|
+
- features/support/env.rb
|
122
|
+
- lib/catwalk.rb
|
123
|
+
- lib/catwalk/presenter.rb
|
124
|
+
- lib/catwalk/version.rb
|
125
|
+
- spec/catwalk/presenter_spec.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
- spec/support/active_model_lint.rb
|
128
|
+
- spec/support/active_model_proxy_shared_examples.rb
|
129
|
+
has_rdoc: true
|
130
|
+
homepage: http://github.com/jonrowe/catwalk
|
131
|
+
licenses: []
|
132
|
+
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
|
136
|
+
require_paths:
|
137
|
+
- lib
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
version: "0"
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
segments:
|
152
|
+
- 0
|
153
|
+
version: "0"
|
154
|
+
requirements: []
|
155
|
+
|
156
|
+
rubyforge_project:
|
157
|
+
rubygems_version: 1.3.7
|
158
|
+
signing_key:
|
159
|
+
specification_version: 3
|
160
|
+
summary: Catwalk is a gem for showing off models. It allows you to seperate presentation logic from data models.
|
161
|
+
test_files:
|
162
|
+
- .autotest
|
163
|
+
- features/active_model_compatibility.feature
|
164
|
+
- features/basic_fields.feature
|
165
|
+
- features/specifying_model_accessor.feature
|
166
|
+
- features/step_definitions/model_steps.rb
|
167
|
+
- features/step_definitions/presenter_steps.rb
|
168
|
+
- features/support/active_model_example.rb
|
169
|
+
- features/support/env.rb
|
170
|
+
- spec/catwalk/presenter_spec.rb
|
171
|
+
- spec/spec_helper.rb
|
172
|
+
- spec/support/active_model_lint.rb
|
173
|
+
- spec/support/active_model_proxy_shared_examples.rb
|