resubject 0.0.1 → 0.0.2
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/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
|