resubject 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/IDEAS.md +51 -0
- data/README.md +56 -2
- data/lib/resubject/builder.rb +65 -0
- data/lib/resubject/naming.rb +20 -0
- data/lib/resubject/presenter.rb +41 -22
- data/lib/resubject/rails/engine.rb +10 -0
- data/lib/resubject/rails/extensions.rb +30 -0
- data/lib/resubject/rails/helpers.rb +4 -14
- data/lib/resubject/rails.rb +29 -6
- data/lib/resubject/version.rb +1 -1
- data/lib/resubject.rb +2 -0
- data/resubject.gemspec +2 -0
- data/spec/resubject/builder_spec.rb +65 -0
- data/spec/resubject/naming_spec.rb +26 -0
- data/spec/resubject/presenter_spec.rb +52 -2
- data/spec/resubject/rails/extensions_spec.rb +24 -0
- metadata +31 -4
data/Gemfile
CHANGED
data/IDEAS.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Present a object with a symbol
|
2
|
+
|
3
|
+
present user, context: :public
|
4
|
+
# => present user, PublicUserPresenter
|
5
|
+
|
6
|
+
present user, :public, :crazy
|
7
|
+
# => present user, PublicPresenter, CrazyPresenter
|
8
|
+
|
9
|
+
# best way to handle this?
|
10
|
+
present user, :public, :user
|
11
|
+
# => present user, PublicPresenter, UserPresenter
|
12
|
+
|
13
|
+
Helper class methods
|
14
|
+
|
15
|
+
class UserPresenter < Resubject::Presenter
|
16
|
+
# formats to default (to_s), only if present
|
17
|
+
# object.created_at
|
18
|
+
timestamp :created_at
|
19
|
+
|
20
|
+
# formats to long (to_s(:long))
|
21
|
+
timestamp :created_at, format: :long
|
22
|
+
|
23
|
+
# multiple
|
24
|
+
timestamps :created_at, :updated_at
|
25
|
+
|
26
|
+
autolink!
|
27
|
+
# create object.link
|
28
|
+
|
29
|
+
# currency format
|
30
|
+
currency :price
|
31
|
+
|
32
|
+
# change options
|
33
|
+
currency :price, format: 'whatever'
|
34
|
+
end
|
35
|
+
|
36
|
+
Test helpers
|
37
|
+
|
38
|
+
describe UserPresenter do
|
39
|
+
it 'has currency' do
|
40
|
+
user = stub price: 200.0
|
41
|
+
presented(user).currency.should == '$200.00'
|
42
|
+
end
|
43
|
+
|
44
|
+
# or
|
45
|
+
|
46
|
+
subject { UserPresenter.new(stub(price: 200.0)) }
|
47
|
+
|
48
|
+
it 'has currency' do
|
49
|
+
presented.currency.should == '$200'
|
50
|
+
end
|
51
|
+
end
|
data/README.md
CHANGED
@@ -10,13 +10,17 @@ Uber simple presenters using Ruby's SimpleDelegator.
|
|
10
10
|
Add this line to your application's Gemfile:
|
11
11
|
|
12
12
|
```ruby
|
13
|
-
gem 'resubject', '~> 0.0.
|
13
|
+
gem 'resubject', '~> 0.0.2'
|
14
14
|
```
|
15
15
|
|
16
16
|
And then execute:
|
17
17
|
|
18
18
|
$ bundle
|
19
19
|
|
20
|
+
## Documentation
|
21
|
+
|
22
|
+
Checkout the documentation in [rdoc.info/resubject](http://rdoc.info/github/felipeelias/resubject/master/frames)
|
23
|
+
|
20
24
|
## Usage
|
21
25
|
|
22
26
|
Resubject works on top of `SimpleDelegator` which simply delegates every method call to the delegated object. Example:
|
@@ -37,7 +41,7 @@ Then use the delegator:
|
|
37
41
|
```ruby
|
38
42
|
box = Box.new('Awkward Package', ['platypus', 'sloth', 'anteater'])
|
39
43
|
|
40
|
-
presentable = BoxPresenter.new(box
|
44
|
+
presentable = BoxPresenter.new(box)
|
41
45
|
presentable.contents
|
42
46
|
# => platypus, sloth, anteater
|
43
47
|
```
|
@@ -84,6 +88,56 @@ Or if you prefer, you can use the `#present` method directly into your views
|
|
84
88
|
<%= present(@box).contents %>
|
85
89
|
```
|
86
90
|
|
91
|
+
## Helpers
|
92
|
+
|
93
|
+
You can define presentable attributes:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
class PostPresenter < Resubject::Presenter
|
97
|
+
presents :title
|
98
|
+
presents :comments # or => presents :comments, CommentPresenter
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
Then the attributes will return an instance of those presenters:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
post.title
|
106
|
+
# => <TitlePresenter>
|
107
|
+
|
108
|
+
post.comments
|
109
|
+
# => [<CommentPresenter>, <CommentPresenter>, <CommentPresenter>]
|
110
|
+
```
|
111
|
+
|
112
|
+
Or if you wish, you can use the `present` method inside your class
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class PostPresenter < Resubject::Presenter
|
116
|
+
def comments
|
117
|
+
present(to_model.comments, SomePresenter)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
### Helpers on Rails
|
123
|
+
|
124
|
+
`Resubject` can generate some rails helpers for your attributes:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
class ProductPresenter < Resubject::Presenter
|
128
|
+
currency :price, precision: 2
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
Will generate:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
product.price
|
136
|
+
# => $10.00
|
137
|
+
```
|
138
|
+
|
139
|
+
Check out [the extensions file](https://github.com/felipeelias/resubject/blob/master/lib/resubject/rails/extensions.rb) for other attribute helpers.
|
140
|
+
|
87
141
|
## Maintainers
|
88
142
|
|
89
143
|
- Felipe Elias Philipp - [coderwall.com/felipeelias](http://coderwall.com/felipeelias)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Resubject
|
2
|
+
module Builder
|
3
|
+
class InvalidPresenterArgument < StandardError #:nodoc:
|
4
|
+
end
|
5
|
+
|
6
|
+
# Presents a object or a collection of objects
|
7
|
+
#
|
8
|
+
# Examples:
|
9
|
+
#
|
10
|
+
# Builder.present box, template
|
11
|
+
# => <BoxPresenter>
|
12
|
+
#
|
13
|
+
# # Using a custom presenter
|
14
|
+
# Builder.present box, template, CustomPresenter
|
15
|
+
# => <CustomPresenter>
|
16
|
+
#
|
17
|
+
# # Using multiple presenters
|
18
|
+
# Builder.present box, template, OnePresenter, CustomPresenter
|
19
|
+
# => <OnePresenter<CustomPresenter>>
|
20
|
+
#
|
21
|
+
# # Using a collection
|
22
|
+
# Builder.present [box, box], template
|
23
|
+
# => [<BoxPresenter>, <BoxPresenter>]
|
24
|
+
#
|
25
|
+
def self.present(objects, template, *presenters)
|
26
|
+
if objects.respond_to?(:each)
|
27
|
+
Builder.present_all(objects, template, *presenters)
|
28
|
+
else
|
29
|
+
Builder.present_one(objects, template, *presenters)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Presents a single object (see .present)
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
#
|
37
|
+
# Builder.present box, template
|
38
|
+
# => <BoxPresenter>
|
39
|
+
#
|
40
|
+
def self.present_one(object, template, *presenters)
|
41
|
+
presenters = [Naming.presenter_for(object)] unless presenters.any?
|
42
|
+
|
43
|
+
unless presenters.all? { |p| p.is_a?(Class) && p.ancestors.include?(Resubject::Presenter) }
|
44
|
+
raise InvalidPresenterArgument.new("Expected a presenter in #{presenters.inspect}")
|
45
|
+
end
|
46
|
+
|
47
|
+
presenters.inject(object) do |presented, klass|
|
48
|
+
klass.new(presented, template)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Presents a collection of objects (see .present)
|
53
|
+
#
|
54
|
+
# Example:
|
55
|
+
#
|
56
|
+
# Builder.present [box, box], template
|
57
|
+
# => [<BoxPresenter>, <BoxPresenter>]
|
58
|
+
#
|
59
|
+
def self.present_all(objects, template, *presenters)
|
60
|
+
objects.map do |o|
|
61
|
+
Builder.present_one(o, template, *presenters)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
|
3
|
+
module Resubject
|
4
|
+
module Naming
|
5
|
+
def self.presenter_for(presentable)
|
6
|
+
klass = case presentable
|
7
|
+
when Symbol
|
8
|
+
presentable.to_s
|
9
|
+
when String
|
10
|
+
presentable
|
11
|
+
else
|
12
|
+
presentable.class.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
presenter = "#{klass.camelize}Presenter"
|
16
|
+
|
17
|
+
Object.const_get presenter
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/resubject/presenter.rb
CHANGED
@@ -2,36 +2,55 @@ require 'delegate'
|
|
2
2
|
|
3
3
|
module Resubject
|
4
4
|
class Presenter < SimpleDelegator
|
5
|
-
attr_reader
|
6
|
-
|
5
|
+
attr_reader :context
|
6
|
+
alias_method :template, :context
|
7
7
|
|
8
|
-
def initialize(model,
|
9
|
-
@
|
8
|
+
def initialize(model, context = nil)
|
9
|
+
@context = context
|
10
10
|
super(model)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
alias_method :to_model, :__getobj__
|
14
|
+
|
15
|
+
# Builds a collection of presenters given an array of objects
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
#
|
19
|
+
# boxes = [box1, box2, box3]
|
20
|
+
# BoxPresenter.all boxes
|
21
|
+
# # => [<BoxPresenter>, <BoxPresenter>, <BoxPresenter>]
|
22
|
+
#
|
23
|
+
def self.all(collection, context = nil)
|
24
|
+
collection.map { |c| new(c, context) }
|
15
25
|
end
|
16
26
|
|
17
|
-
|
18
|
-
|
27
|
+
# Creates a presenter from object or collection of objects
|
28
|
+
# See Builder.present for more details
|
29
|
+
# Example:
|
30
|
+
#
|
31
|
+
# present box
|
32
|
+
# => <BoxPresenter>
|
33
|
+
#
|
34
|
+
def present(objects, *presenters)
|
35
|
+
Builder.present objects, context, *presenters
|
19
36
|
end
|
20
37
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
# Generates a instance method with the attribute presented
|
39
|
+
#
|
40
|
+
# Example:
|
41
|
+
#
|
42
|
+
# class BoxPresenter < Resubject::Presenter
|
43
|
+
# presents :name
|
44
|
+
# # or
|
45
|
+
# # presents :name, CustomPresenter
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# BoxPresenter.new(box).name
|
49
|
+
# => <NamePresenter>
|
50
|
+
#
|
51
|
+
def self.presents(attribute, *presenters)
|
52
|
+
define_method attribute do
|
53
|
+
present to_model.send(attribute), *presenters
|
35
54
|
end
|
36
55
|
end
|
37
56
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Resubject
|
2
|
+
module Rails #:nodoc:
|
3
|
+
module Extensions
|
4
|
+
# Generates an attribute using `number_to_currency` helper from rails
|
5
|
+
#
|
6
|
+
# Examples:
|
7
|
+
#
|
8
|
+
# class ProductPresenter < Resubject::Presenter
|
9
|
+
# currency :price
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# # Will create a `price` attribute using `number_to_currency`
|
13
|
+
#
|
14
|
+
# product.price
|
15
|
+
# # => '$10.00'
|
16
|
+
#
|
17
|
+
# Options:
|
18
|
+
#
|
19
|
+
# currency :price, precision: 3 # => '$123.456'
|
20
|
+
# currency :price, locale: :fr # => '123,51 €'
|
21
|
+
#
|
22
|
+
# See ActionView::Helpers::NumberHelper#number_to_currency[http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_currency] for other options
|
23
|
+
def currency(attribute, options = {})
|
24
|
+
define_method attribute do
|
25
|
+
template.number_to_currency to_model.send(attribute), options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,27 +1,17 @@
|
|
1
1
|
module Resubject
|
2
2
|
module Helpers
|
3
|
-
def self.included(base)
|
3
|
+
def self.included(base) #:nodoc:
|
4
4
|
base.send(:helper_method, :present)
|
5
|
-
base.send(:private, :present_object)
|
6
5
|
end
|
7
6
|
|
8
|
-
def present(
|
9
|
-
|
10
|
-
object.map { |o| present_object(o, presenter_classes) }
|
11
|
-
else
|
12
|
-
present_object(object, presenter_classes)
|
13
|
-
end
|
7
|
+
def present(objects, *presenters)
|
8
|
+
presenters = Builder.present(objects, view_context, *presenters)
|
14
9
|
|
15
|
-
|
10
|
+
presenters.tap do |p|
|
16
11
|
if block_given?
|
17
12
|
yield p
|
18
13
|
end
|
19
14
|
end
|
20
15
|
end
|
21
|
-
|
22
|
-
def present_object(object, presenter_classes)
|
23
|
-
presenter_classes = ["#{object.class}Presenter".constantize] if presenter_classes.empty?
|
24
|
-
presenter_classes.inject(object) { |o, klass| klass.new(o, view_context) }
|
25
|
-
end
|
26
16
|
end
|
27
17
|
end
|
data/lib/resubject/rails.rb
CHANGED
@@ -1,11 +1,34 @@
|
|
1
|
-
require 'resubject/rails/
|
1
|
+
require 'resubject/rails/engine'
|
2
|
+
require 'resubject/rails/extensions'
|
2
3
|
|
3
4
|
module Resubject
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
class Presenter
|
6
|
+
extend Resubject::Rails::Extensions
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def translate(*args, &block)
|
11
|
+
context.t(*args, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :t, :translate
|
15
|
+
|
16
|
+
def localize(*args, &block)
|
17
|
+
context.l(*args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :l, :localize
|
21
|
+
|
22
|
+
def routes
|
23
|
+
::Rails.application.routes.url_helpers
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :r, :routes
|
27
|
+
|
28
|
+
def helpers
|
29
|
+
context
|
9
30
|
end
|
31
|
+
|
32
|
+
alias_method :h, :helpers
|
10
33
|
end
|
11
34
|
end
|
data/lib/resubject/version.rb
CHANGED
data/lib/resubject.rb
CHANGED
data/resubject.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
+
gem.add_dependency 'activesupport', '~> 3.2'
|
22
|
+
|
21
23
|
gem.add_development_dependency "rake"
|
22
24
|
gem.add_development_dependency "rspec", "~> 2.12.0"
|
23
25
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Resubject::Builder do
|
4
|
+
let(:template) { stub }
|
5
|
+
|
6
|
+
before do
|
7
|
+
stub_const 'Box', Class.new
|
8
|
+
stub_const 'BoxPresenter', Class.new(Resubject::Presenter)
|
9
|
+
stub_const 'OtherBoxPresenter', Class.new(Resubject::Presenter)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.present_one' do
|
13
|
+
it 'presents the object with related class' do
|
14
|
+
presented = Resubject::Builder.present_one Box.new, template
|
15
|
+
expect(presented).to be_a BoxPresenter
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'presents the object with custom class' do
|
19
|
+
presented = Resubject::Builder.present_one Box.new, template, OtherBoxPresenter
|
20
|
+
expect(presented).to be_a OtherBoxPresenter
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'presents the object with multiple classes' do
|
24
|
+
OtherBoxPresenter.should_receive(:new).twice
|
25
|
+
presenters = [OtherBoxPresenter, OtherBoxPresenter]
|
26
|
+
presented = Resubject::Builder.present_one Box.new, template, *presenters
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'raises an error if custom presenter is not a presenter' do
|
30
|
+
expect do
|
31
|
+
Resubject::Builder.present_one Box.new, template, *[nil, Class.new]
|
32
|
+
end.to raise_error(Resubject::Builder::InvalidPresenterArgument)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '.present_all' do
|
37
|
+
it 'presents multiple objects' do
|
38
|
+
box = Box.new
|
39
|
+
presented = Resubject::Builder.present_all [box, box], template
|
40
|
+
|
41
|
+
expect(presented.map(&:class)).to eq [BoxPresenter, BoxPresenter]
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'presents multiple objects with custom presenters' do
|
45
|
+
box = Box.new
|
46
|
+
presented = Resubject::Builder.present_all [box, box], template, OtherBoxPresenter
|
47
|
+
|
48
|
+
expect(presented.map(&:class)).to eq [OtherBoxPresenter, OtherBoxPresenter]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '.present' do
|
53
|
+
it 'presents single object' do
|
54
|
+
presented = Resubject::Builder.present Box.new, template
|
55
|
+
expect(presented).to be_a BoxPresenter
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'presents multiple objects' do
|
59
|
+
box = Box.new
|
60
|
+
presented = Resubject::Builder.present [box, box], template
|
61
|
+
|
62
|
+
expect(presented.map(&:class)).to eq [BoxPresenter, BoxPresenter]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Resubject::Naming do
|
4
|
+
before do
|
5
|
+
stub_const 'Box', Class.new
|
6
|
+
stub_const 'BoxPresenter', Class.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'gets the presenter class from an object' do
|
10
|
+
presenter = Resubject::Naming.presenter_for Box.new
|
11
|
+
|
12
|
+
expect(presenter).to eq BoxPresenter
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'gets the presenter class from a symbol' do
|
16
|
+
presenter = Resubject::Naming.presenter_for :box
|
17
|
+
|
18
|
+
expect(presenter).to eq BoxPresenter
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'gets the presenter class from a string' do
|
22
|
+
presenter = Resubject::Naming.presenter_for 'box'
|
23
|
+
|
24
|
+
expect(presenter).to eq BoxPresenter
|
25
|
+
end
|
26
|
+
end
|
@@ -2,12 +2,62 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Resubject::Presenter do
|
4
4
|
let(:object) { mock :object }
|
5
|
-
let(:template) { mock :template }
|
6
5
|
|
7
|
-
subject { Resubject::Presenter.new(object
|
6
|
+
subject { Resubject::Presenter.new(object) }
|
8
7
|
|
9
8
|
it 'delegate methods to object' do
|
10
9
|
object.should_receive(:pretty)
|
11
10
|
subject.pretty
|
12
11
|
end
|
12
|
+
|
13
|
+
describe :to_model do
|
14
|
+
it 'returns the delegated object' do
|
15
|
+
expect(subject.to_model).to eq object
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.all' do
|
20
|
+
it 'creates various instances of the presenter' do
|
21
|
+
presented = Resubject::Presenter.all([object, object])
|
22
|
+
|
23
|
+
expect(presented.map(&:class)).to eq [Resubject::Presenter,
|
24
|
+
Resubject::Presenter]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe :present do
|
29
|
+
it 'creates a presenter' do
|
30
|
+
stub_const 'Box', Class.new
|
31
|
+
stub_const 'BoxPresenter', Class.new(Resubject::Presenter)
|
32
|
+
|
33
|
+
presented = subject.present Box.new
|
34
|
+
expect(presented).to be_a BoxPresenter
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '.presents' do
|
39
|
+
let :presenter do
|
40
|
+
Class.new(Resubject::Presenter) do
|
41
|
+
presents :item
|
42
|
+
presents :other_item, ItemPresenter
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
before do
|
47
|
+
stub_const 'Item', Class.new
|
48
|
+
stub_const 'ItemPresenter', Class.new(Resubject::Presenter)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'generates a method preseting the attribute' do
|
52
|
+
box = stub :box, :item => Item.new
|
53
|
+
|
54
|
+
expect(presenter.new(box).item).to be_a ItemPresenter
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'presents the attributes with custom presenter' do
|
58
|
+
box = stub :box, :other_item => stub
|
59
|
+
|
60
|
+
expect(presenter.new(box).other_item).to be_a ItemPresenter
|
61
|
+
end
|
62
|
+
end
|
13
63
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rails/all'
|
3
|
+
require 'resubject/rails'
|
4
|
+
|
5
|
+
describe Resubject::Presenter, 'extensions' do
|
6
|
+
let(:model) { mock :model }
|
7
|
+
|
8
|
+
let(:presenter) do
|
9
|
+
Class.new(Resubject::Presenter) do
|
10
|
+
currency :price
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
subject do
|
15
|
+
presenter.new(model, ActionView::Base.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.currency' do
|
19
|
+
it 'returns currency format' do
|
20
|
+
model.should_receive(:price).and_return(10.0)
|
21
|
+
expect(subject.price).to eq "$10.00"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resubject
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,8 +10,24 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-01-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
type: :runtime
|
17
|
+
version_requirements: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.2'
|
23
|
+
name: activesupport
|
24
|
+
prerelease: false
|
25
|
+
requirement: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '3.2'
|
15
31
|
- !ruby/object:Gem::Dependency
|
16
32
|
type: :development
|
17
33
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -56,16 +72,24 @@ files:
|
|
56
72
|
- .rspec
|
57
73
|
- .travis.yml
|
58
74
|
- Gemfile
|
75
|
+
- IDEAS.md
|
59
76
|
- LICENSE.txt
|
60
77
|
- README.md
|
61
78
|
- Rakefile
|
62
79
|
- lib/resubject.rb
|
80
|
+
- lib/resubject/builder.rb
|
81
|
+
- lib/resubject/naming.rb
|
63
82
|
- lib/resubject/presenter.rb
|
64
83
|
- lib/resubject/rails.rb
|
84
|
+
- lib/resubject/rails/engine.rb
|
85
|
+
- lib/resubject/rails/extensions.rb
|
65
86
|
- lib/resubject/rails/helpers.rb
|
66
87
|
- lib/resubject/version.rb
|
67
88
|
- resubject.gemspec
|
89
|
+
- spec/resubject/builder_spec.rb
|
90
|
+
- spec/resubject/naming_spec.rb
|
68
91
|
- spec/resubject/presenter_spec.rb
|
92
|
+
- spec/resubject/rails/extensions_spec.rb
|
69
93
|
- spec/spec_helper.rb
|
70
94
|
homepage: https://github.com/felipeelias/resubject
|
71
95
|
licenses:
|
@@ -82,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
106
|
segments:
|
83
107
|
- 0
|
84
108
|
version: '0'
|
85
|
-
hash:
|
109
|
+
hash: 134183276947229850
|
86
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
111
|
none: false
|
88
112
|
requirements:
|
@@ -91,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
115
|
segments:
|
92
116
|
- 0
|
93
117
|
version: '0'
|
94
|
-
hash:
|
118
|
+
hash: 134183276947229850
|
95
119
|
requirements: []
|
96
120
|
rubyforge_project:
|
97
121
|
rubygems_version: 1.8.24
|
@@ -99,5 +123,8 @@ signing_key:
|
|
99
123
|
specification_version: 3
|
100
124
|
summary: Uber simple presenters using Ruby's SimpleDelegator
|
101
125
|
test_files:
|
126
|
+
- spec/resubject/builder_spec.rb
|
127
|
+
- spec/resubject/naming_spec.rb
|
102
128
|
- spec/resubject/presenter_spec.rb
|
129
|
+
- spec/resubject/rails/extensions_spec.rb
|
103
130
|
- spec/spec_helper.rb
|