present_foo 0.1.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.
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +116 -0
- data/LICENSE +22 -0
- data/README.md +166 -0
- data/Rakefile +2 -0
- data/lib/present_foo.rb +25 -0
- data/lib/present_foo/errors.rb +7 -0
- data/lib/present_foo/presentation.rb +50 -0
- data/lib/present_foo/presenter.rb +22 -0
- data/lib/present_foo/serialization.rb +18 -0
- data/lib/present_foo/version.rb +3 -0
- data/present_foo.gemspec +24 -0
- data/spec/app/views/books/test.html.erb +0 -0
- data/spec/controller_spec.rb +81 -0
- data/spec/fake_app.rb +13 -0
- data/spec/fake_classes.rb +56 -0
- data/spec/presenter_spec.rb +25 -0
- data/spec/serialization_spec.rb +13 -0
- data/spec/spec_helper.rb +15 -0
- metadata +137 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
present_foo (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
actionmailer (3.2.3)
|
10
|
+
actionpack (= 3.2.3)
|
11
|
+
mail (~> 2.4.4)
|
12
|
+
actionpack (3.2.3)
|
13
|
+
activemodel (= 3.2.3)
|
14
|
+
activesupport (= 3.2.3)
|
15
|
+
builder (~> 3.0.0)
|
16
|
+
erubis (~> 2.7.0)
|
17
|
+
journey (~> 1.0.1)
|
18
|
+
rack (~> 1.4.0)
|
19
|
+
rack-cache (~> 1.2)
|
20
|
+
rack-test (~> 0.6.1)
|
21
|
+
sprockets (~> 2.1.2)
|
22
|
+
activemodel (3.2.3)
|
23
|
+
activesupport (= 3.2.3)
|
24
|
+
builder (~> 3.0.0)
|
25
|
+
activerecord (3.2.3)
|
26
|
+
activemodel (= 3.2.3)
|
27
|
+
activesupport (= 3.2.3)
|
28
|
+
arel (~> 3.0.2)
|
29
|
+
tzinfo (~> 0.3.29)
|
30
|
+
activeresource (3.2.3)
|
31
|
+
activemodel (= 3.2.3)
|
32
|
+
activesupport (= 3.2.3)
|
33
|
+
activesupport (3.2.3)
|
34
|
+
i18n (~> 0.6)
|
35
|
+
multi_json (~> 1.0)
|
36
|
+
arel (3.0.2)
|
37
|
+
builder (3.0.0)
|
38
|
+
columnize (0.3.6)
|
39
|
+
debugger (1.1.1)
|
40
|
+
columnize (>= 0.3.1)
|
41
|
+
debugger-linecache (~> 1.1)
|
42
|
+
debugger-ruby_core_source (~> 1.1)
|
43
|
+
debugger-linecache (1.1.1)
|
44
|
+
debugger-ruby_core_source (>= 1.1.1)
|
45
|
+
debugger-ruby_core_source (1.1.2)
|
46
|
+
diff-lcs (1.1.3)
|
47
|
+
erubis (2.7.0)
|
48
|
+
hike (1.2.1)
|
49
|
+
i18n (0.6.0)
|
50
|
+
journey (1.0.3)
|
51
|
+
json (1.6.6)
|
52
|
+
mail (2.4.4)
|
53
|
+
i18n (>= 0.4.0)
|
54
|
+
mime-types (~> 1.16)
|
55
|
+
treetop (~> 1.4.8)
|
56
|
+
mime-types (1.18)
|
57
|
+
multi_json (1.2.0)
|
58
|
+
polyglot (0.3.3)
|
59
|
+
rack (1.4.1)
|
60
|
+
rack-cache (1.2)
|
61
|
+
rack (>= 0.4)
|
62
|
+
rack-ssl (1.3.2)
|
63
|
+
rack
|
64
|
+
rack-test (0.6.1)
|
65
|
+
rack (>= 1.0)
|
66
|
+
rails (3.2.3)
|
67
|
+
actionmailer (= 3.2.3)
|
68
|
+
actionpack (= 3.2.3)
|
69
|
+
activerecord (= 3.2.3)
|
70
|
+
activeresource (= 3.2.3)
|
71
|
+
activesupport (= 3.2.3)
|
72
|
+
bundler (~> 1.0)
|
73
|
+
railties (= 3.2.3)
|
74
|
+
railties (3.2.3)
|
75
|
+
actionpack (= 3.2.3)
|
76
|
+
activesupport (= 3.2.3)
|
77
|
+
rack-ssl (~> 1.3.2)
|
78
|
+
rake (>= 0.8.7)
|
79
|
+
rdoc (~> 3.4)
|
80
|
+
thor (~> 0.14.6)
|
81
|
+
rake (0.9.2.2)
|
82
|
+
rdoc (3.12)
|
83
|
+
json (~> 1.4)
|
84
|
+
rspec (2.9.0)
|
85
|
+
rspec-core (~> 2.9.0)
|
86
|
+
rspec-expectations (~> 2.9.0)
|
87
|
+
rspec-mocks (~> 2.9.0)
|
88
|
+
rspec-core (2.9.0)
|
89
|
+
rspec-expectations (2.9.1)
|
90
|
+
diff-lcs (~> 1.1.3)
|
91
|
+
rspec-mocks (2.9.0)
|
92
|
+
rspec-rails (2.9.0)
|
93
|
+
actionpack (>= 3.0)
|
94
|
+
activesupport (>= 3.0)
|
95
|
+
railties (>= 3.0)
|
96
|
+
rspec (~> 2.9.0)
|
97
|
+
sprockets (2.1.2)
|
98
|
+
hike (~> 1.2)
|
99
|
+
rack (~> 1.0)
|
100
|
+
tilt (~> 1.1, != 1.3.0)
|
101
|
+
thor (0.14.6)
|
102
|
+
tilt (1.3.3)
|
103
|
+
treetop (1.4.10)
|
104
|
+
polyglot
|
105
|
+
polyglot (>= 0.3.1)
|
106
|
+
tzinfo (0.3.33)
|
107
|
+
|
108
|
+
PLATFORMS
|
109
|
+
ruby
|
110
|
+
|
111
|
+
DEPENDENCIES
|
112
|
+
debugger (= 1.1.1)
|
113
|
+
present_foo!
|
114
|
+
rails (~> 3.2.0)
|
115
|
+
rspec (~> 2.9.0)
|
116
|
+
rspec-rails (~> 2.9.0)
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 JC Grubbs
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
[](http://travis-ci.org/devmynd/present_foo)
|
2
|
+
|
3
|
+
# PresentFoo
|
4
|
+
|
5
|
+
PresentFoo is meant to be a very lightweight presenter library for
|
6
|
+
Rails. Presenters are a great way to move logic out of views and
|
7
|
+
controllers into a class which represents the state of a "view" whether
|
8
|
+
that be HTML, JSON, or other. It's also a way to reduce the junk-drawer
|
9
|
+
effect that happens in the `/helpers` directory of many large Rails
|
10
|
+
applications. This is a super basic implementation and I hope to grow
|
11
|
+
it over time. If you have thoughts on things that would be helpful I'd
|
12
|
+
love the feedback.
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
gem 'present_foo'
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install present_foo
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
### Create your Presenters
|
31
|
+
|
32
|
+
Presenters are just classes that inherit from Presenter and have a name
|
33
|
+
which matches the `<Model>Presenter` naming convention (later we'll see
|
34
|
+
how to override this).
|
35
|
+
|
36
|
+
class Book < ActiveRecord::Base
|
37
|
+
def some_model_method
|
38
|
+
"foo"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class BookPresenter < Presenter
|
43
|
+
def some_presenter_method
|
44
|
+
"bar"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
The `Presenter` base class inherits from `SimpleDelegator`, which allows
|
49
|
+
instances of the presenter to mirror the public interface of
|
50
|
+
the object they are presenting. For example, if you have a method on
|
51
|
+
your presented object or model called `some_model_method`, you can call
|
52
|
+
it directly on the presenter and it will be delegated to the wrapped
|
53
|
+
object.
|
54
|
+
|
55
|
+
Presenters also all have a hook back to the controller they were created
|
56
|
+
from. For example, if you need to get access to helpers or url
|
57
|
+
generators you can do so from the `controller` method.
|
58
|
+
|
59
|
+
class BookPresenter < Presenter
|
60
|
+
|
61
|
+
# Access to url generators
|
62
|
+
def edit_url
|
63
|
+
controller.edit_book_url
|
64
|
+
end
|
65
|
+
|
66
|
+
# Access to helper methods
|
67
|
+
def permalink
|
68
|
+
controller.create_permalink(self.title)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
You can also access the `request` or any other contextual data that's
|
74
|
+
available to the controller in this manner.
|
75
|
+
|
76
|
+
### Use Presenters in Controllers
|
77
|
+
|
78
|
+
In a controller action, you simply call `present` or `present_many` which
|
79
|
+
sets an instance variable that can be used in views and also returns
|
80
|
+
an instance of the presenter for use in non-html responses.
|
81
|
+
|
82
|
+
class BooksController < ApplicationController
|
83
|
+
|
84
|
+
def index
|
85
|
+
books = Book.all
|
86
|
+
present_many books
|
87
|
+
end
|
88
|
+
|
89
|
+
def show
|
90
|
+
book = Book.find(params[:id])
|
91
|
+
present book
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
# app/views/books/index.html.haml
|
97
|
+
%ul.books
|
98
|
+
- @book_presenters.each do |book_presenter|
|
99
|
+
%li= book_presenter.title
|
100
|
+
|
101
|
+
# app/views/books/show.html.haml
|
102
|
+
%h1= @book_presenter.title
|
103
|
+
%h3= @book_presenter.author
|
104
|
+
|
105
|
+
### Extending Presenter Initialization
|
106
|
+
|
107
|
+
If you need to override the default behavior of a presenter at
|
108
|
+
construction-time just override the `initialize` or `new_list` methods.
|
109
|
+
|
110
|
+
class BookPresenter < Presenter
|
111
|
+
|
112
|
+
# Maps to present in controllers
|
113
|
+
def initialize(obj, arg1, arg2)
|
114
|
+
# ... do some more stuff
|
115
|
+
super(obj)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Maps to present_many in controllers
|
119
|
+
def self.new_list(objs, arg1, arg2)
|
120
|
+
# ... do some more stuff
|
121
|
+
super(objs)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
In controllers additional arguments passed to `present` or
|
127
|
+
`present_many`
|
128
|
+
will be passed to these overridden constructor methods.
|
129
|
+
|
130
|
+
class BooksController < ApplicationController
|
131
|
+
|
132
|
+
def index
|
133
|
+
books = Books.all
|
134
|
+
present_many books, "foo", "bar"
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
### Changing the Default Presenter Type
|
140
|
+
|
141
|
+
If you want to name your presenter something other than `<Class>Presenter`
|
142
|
+
or, if you have more than one presenter for a given type you can simply
|
143
|
+
pass the class you want to use as the second argument when calling
|
144
|
+
`present` or `present_many`.
|
145
|
+
|
146
|
+
class BooksController < ApplicationController
|
147
|
+
|
148
|
+
def index
|
149
|
+
books = Books.all
|
150
|
+
present_many books, OtherBookPresenter, "foo", "bar"
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
## TODO
|
156
|
+
|
157
|
+
1. Do something to assist with serialization scenarios
|
158
|
+
2. Make PresentFoo work in non-Rails environments
|
159
|
+
|
160
|
+
## Contributing
|
161
|
+
|
162
|
+
1. Fork it
|
163
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
164
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
165
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
166
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/present_foo.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require "delegate"
|
2
|
+
require "present_foo/version"
|
3
|
+
require "present_foo/serialization"
|
4
|
+
require "present_foo/presenter"
|
5
|
+
require "present_foo/presentation"
|
6
|
+
require "present_foo/errors"
|
7
|
+
|
8
|
+
module PresentFoo
|
9
|
+
|
10
|
+
def self.load!
|
11
|
+
hook_rails if defined?(::Rails)
|
12
|
+
# TODO: Figure out how to write hook_sinatra and hook_padrino
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def self.hook_rails
|
18
|
+
ActiveSupport.on_load(:action_controller) do
|
19
|
+
::ActionController::Base.send :include, Presentation
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
PresentFoo.load!
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Presentation
|
2
|
+
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
|
7
|
+
define_method :present do |obj, *args|
|
8
|
+
klass = presenter_klass(obj, args)
|
9
|
+
presenter = create_presenter(klass, obj, self, args)
|
10
|
+
set_instance_variable(klass, self, presenter, obj)
|
11
|
+
presenter
|
12
|
+
end
|
13
|
+
|
14
|
+
define_method :present_many do |objs, *args|
|
15
|
+
klass = presenter_klass(objs.first, args)
|
16
|
+
presenters = create_many_presenters(klass, objs, self, args)
|
17
|
+
set_instance_variable(klass, self, presenters, objs, true)
|
18
|
+
presenters
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_presenter(klass, obj, source, args)
|
26
|
+
presenter = klass.new(obj, *args)
|
27
|
+
presenter.presenting_object = source
|
28
|
+
presenter
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_many_presenters(klass, objs, source, args)
|
32
|
+
objs.map { |o| create_presenter(klass, o, source, args) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_instance_variable(klass, source, value, obj, pluralize = false)
|
36
|
+
var_name = "@#{klass.to_s.underscore}#{"s" if pluralize}".to_sym
|
37
|
+
source.instance_variable_set(var_name, value)
|
38
|
+
end
|
39
|
+
|
40
|
+
def presenter_klass(obj, args)
|
41
|
+
return args.shift if args[0].kind_of?(Class)
|
42
|
+
klass_name = "#{obj.class}Presenter"
|
43
|
+
begin
|
44
|
+
return klass_name.constantize
|
45
|
+
rescue NameError
|
46
|
+
raise PresentFoo::Errors::PresenterNotFound.new("Could not find a presenter for #{obj.class}, looked for #{class_name}.")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Presenter < SimpleDelegator
|
2
|
+
|
3
|
+
def initialize(obj, *args)
|
4
|
+
super(obj)
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :presenting_object
|
8
|
+
alias_method :controller, :presenting_object if defined?(::Rails)
|
9
|
+
|
10
|
+
def self.new_list(objs, *args)
|
11
|
+
objs.map { |o| new(o) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def obj
|
15
|
+
__getobj__
|
16
|
+
end
|
17
|
+
|
18
|
+
def class
|
19
|
+
obj.class
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# TODO: Still thinking about this.
|
2
|
+
#module PresentFoo::Serialization
|
3
|
+
|
4
|
+
#def self.included(base)
|
5
|
+
#base.extend ClassMethods
|
6
|
+
#base.send :class_variable_set, :@@_serializable_attributes, []
|
7
|
+
#end
|
8
|
+
|
9
|
+
#module ClassMethods
|
10
|
+
|
11
|
+
#def serialize_attributes(*attrs)
|
12
|
+
#self._serializable_attributes += attrs
|
13
|
+
#self._serializable_attributes.uniq!
|
14
|
+
#end
|
15
|
+
|
16
|
+
#end
|
17
|
+
|
18
|
+
#end
|
data/present_foo.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/present_foo/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
|
6
|
+
gem.authors = ["JC Grubbs"]
|
7
|
+
gem.email = ["jc.grubbs@devmynd.com"]
|
8
|
+
gem.summary = %q{Very simple presenters for Rails applications.}
|
9
|
+
gem.homepage = "https://github.com/devmynd/present_foo"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "present_foo"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = PresentFoo::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "rails", "~> 3.2.0"
|
19
|
+
|
20
|
+
gem.add_development_dependency "rake"
|
21
|
+
gem.add_development_dependency "rspec", "~> 2.9.0"
|
22
|
+
gem.add_development_dependency "rspec-rails", "~> 2.9.0"
|
23
|
+
|
24
|
+
end
|
File without changes
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Controllers" do
|
4
|
+
|
5
|
+
let(:books_controller) { BooksController.new }
|
6
|
+
let(:products_controller) { ProductsController.new }
|
7
|
+
|
8
|
+
it "should have a present method" do
|
9
|
+
books_controller.respond_to?(:present).should be_true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have a present_many method" do
|
13
|
+
books_controller.respond_to?(:present_many).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#present_many" do
|
17
|
+
|
18
|
+
before do
|
19
|
+
books_controller.index
|
20
|
+
@presenters = books_controller.instance_variable_get(:@book_presenters)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "assigns @book_presenters" do
|
24
|
+
@presenters.should_not be_nil
|
25
|
+
@presenters.should be_kind_of(Array)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#present" do
|
31
|
+
|
32
|
+
before do
|
33
|
+
books_controller.show
|
34
|
+
@presenter = books_controller.instance_variable_get(:@book_presenter)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "assigns @book_presenter" do
|
38
|
+
@presenter.should_not be_nil
|
39
|
+
@presenter.should be_kind_of(BookPresenter)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "@book_presenter has a presenting_object property" do
|
43
|
+
@presenter.presenting_object.should == books_controller
|
44
|
+
end
|
45
|
+
|
46
|
+
it "@book_presenter has a books_controller property (alias for presenting_object in Rails)" do
|
47
|
+
@presenter.controller.should == books_controller
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#present with specified presenter type" do
|
53
|
+
|
54
|
+
before do
|
55
|
+
books_controller.edit
|
56
|
+
@presenter = books_controller.instance_variable_get(:@alt_book_presenter)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "assigns @alt_book_presenter (and is the correct type)" do
|
60
|
+
@presenter.should_not be_nil
|
61
|
+
@presenter.should be_kind_of(AltBookPresenter)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#present with arguments" do
|
67
|
+
|
68
|
+
before do
|
69
|
+
products_controller.show
|
70
|
+
@presenter = products_controller.instance_variable_get(:@product_presenter)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "passes arguments to the presenter's initialize method" do
|
74
|
+
@presenter.attr1.should == "foo"
|
75
|
+
@presenter.attr2.should == "bar"
|
76
|
+
@presenter.attr3.should == "baz"
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
data/spec/fake_app.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "action_controller/railtie"
|
2
|
+
|
3
|
+
# Config
|
4
|
+
app = Class.new(Rails::Application)
|
5
|
+
app.config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
|
6
|
+
app.config.session_store :cookie_store, :key => "_myapp_session"
|
7
|
+
app.config.active_support.deprecation = :log
|
8
|
+
app.initialize!
|
9
|
+
|
10
|
+
# Routes
|
11
|
+
app.routes.draw do
|
12
|
+
resources :books
|
13
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Book
|
2
|
+
|
3
|
+
attr_accessor :title, :author, :isbn, :publish_date
|
4
|
+
|
5
|
+
def initialize(*attrs)
|
6
|
+
attrs.each { |k,v| self.send("#{k}=".to_sym, v) }
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class AltBookPresenter < Presenter; end
|
12
|
+
|
13
|
+
class BookPresenter < Presenter; end
|
14
|
+
|
15
|
+
class BooksController < ActionController::Base
|
16
|
+
|
17
|
+
def index
|
18
|
+
books = [Book.new, Book.new, Book.new]
|
19
|
+
present_many books
|
20
|
+
end
|
21
|
+
|
22
|
+
def show
|
23
|
+
book = Book.new
|
24
|
+
present book
|
25
|
+
end
|
26
|
+
|
27
|
+
def edit
|
28
|
+
book = Book.new
|
29
|
+
present book, AltBookPresenter
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class Product; end
|
35
|
+
|
36
|
+
class ProductPresenter < Presenter
|
37
|
+
|
38
|
+
attr_accessor :attr1, :attr2, :attr3
|
39
|
+
|
40
|
+
def initialize(obj, arg1, arg2, arg3)
|
41
|
+
@attr1 = arg1
|
42
|
+
@attr2 = arg2
|
43
|
+
@attr3 = arg3
|
44
|
+
super(obj)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class ProductsController < ActionController::Base
|
50
|
+
|
51
|
+
def show
|
52
|
+
product = Product.new
|
53
|
+
present product, "foo", "bar", "baz"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Presenter do
|
4
|
+
|
5
|
+
let(:book) { Book.new }
|
6
|
+
let(:presenter) { BookPresenter.new(book) }
|
7
|
+
let(:books) { [Book.new, Book.new, Book.new] }
|
8
|
+
|
9
|
+
it ".obj returns the original object" do
|
10
|
+
presenter.obj.object_id.should == book.object_id
|
11
|
+
end
|
12
|
+
|
13
|
+
it ".class returns the class of the original object" do
|
14
|
+
presenter.class.should == Book
|
15
|
+
end
|
16
|
+
|
17
|
+
it "#new_list maps the given array to a list of presenters" do
|
18
|
+
presenters = BookPresenter.new_list(books)
|
19
|
+
presenters.size.should == 3
|
20
|
+
presenters[0].obj.object_id.should == books[0].object_id
|
21
|
+
presenters[1].obj.object_id.should == books[1].object_id
|
22
|
+
presenters[2].obj.object_id.should == books[2].object_id
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# TODO: Still thinking about this.
|
2
|
+
#require "spec_helper"
|
3
|
+
|
4
|
+
#describe "Serialization" do
|
5
|
+
|
6
|
+
#let(:book) { Book.new(title: "Jack and Jill", author: "Old Guy", isbn: 12345, publish_date: (DateTime.now - 60)) }
|
7
|
+
#let(:presenter) { BookPresenter.new(book) }
|
8
|
+
|
9
|
+
#it "#as_json returns a hash of the serializable attributes" do
|
10
|
+
#presenter.as_json.should == { title: book.title, author: book.author }
|
11
|
+
#end
|
12
|
+
|
13
|
+
#end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
|
+
#$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
require "rails"
|
6
|
+
require "present_foo"
|
7
|
+
require "fake_app"
|
8
|
+
require "fake_classes"
|
9
|
+
require "rspec/rails"
|
10
|
+
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.mock_with :rspec
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: present_foo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- JC Grubbs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.9.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.9.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec-rails
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.9.0
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.9.0
|
78
|
+
description:
|
79
|
+
email:
|
80
|
+
- jc.grubbs@devmynd.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- .travis.yml
|
87
|
+
- Gemfile
|
88
|
+
- Gemfile.lock
|
89
|
+
- LICENSE
|
90
|
+
- README.md
|
91
|
+
- Rakefile
|
92
|
+
- lib/present_foo.rb
|
93
|
+
- lib/present_foo/errors.rb
|
94
|
+
- lib/present_foo/presentation.rb
|
95
|
+
- lib/present_foo/presenter.rb
|
96
|
+
- lib/present_foo/serialization.rb
|
97
|
+
- lib/present_foo/version.rb
|
98
|
+
- present_foo.gemspec
|
99
|
+
- spec/app/views/books/test.html.erb
|
100
|
+
- spec/controller_spec.rb
|
101
|
+
- spec/fake_app.rb
|
102
|
+
- spec/fake_classes.rb
|
103
|
+
- spec/presenter_spec.rb
|
104
|
+
- spec/serialization_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
homepage: https://github.com/devmynd/present_foo
|
107
|
+
licenses: []
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ! '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 1.8.23
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: Very simple presenters for Rails applications.
|
130
|
+
test_files:
|
131
|
+
- spec/app/views/books/test.html.erb
|
132
|
+
- spec/controller_spec.rb
|
133
|
+
- spec/fake_app.rb
|
134
|
+
- spec/fake_classes.rb
|
135
|
+
- spec/presenter_spec.rb
|
136
|
+
- spec/serialization_spec.rb
|
137
|
+
- spec/spec_helper.rb
|