resubject 0.0.4 → 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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # 0.1.0
2
+
3
+ - enhancements
4
+ - Add time_ago helper
5
+ - Add percentage helper
6
+ - Add date_format helper
7
+
1
8
  # 0.0.4
2
9
 
3
10
  - bugfixes
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '~> 3.2.10'
3
+ gem 'actionpack', '~> 3.2'
4
4
  gem 'redcarpet'
5
5
 
6
6
  # Specify your gem's dependencies in resubject.gemspec
data/README.md CHANGED
@@ -10,7 +10,7 @@ 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.4'
13
+ gem 'resubject', '~> 0.1.0'
14
14
  ```
15
15
 
16
16
  And then execute:
@@ -21,9 +21,56 @@ And then execute:
21
21
 
22
22
  Checkout the documentation in [rdoc.info/resubject](http://rdoc.info/github/felipeelias/resubject/master/frames)
23
23
 
24
+ ## Introduction
25
+
26
+ Resubject uses Ruby's [SimpleDelegator](http://apidock.com/ruby/SimpleDelegator) class to create its presenters.
27
+
28
+ SimpleDelegator is a concrete implemenation of the Delegator class. Basically, it delegates any method calls to the object passed into the constructor:
29
+
30
+ ```ruby
31
+ require 'delegate'
32
+
33
+ array = SimpleDelegator.new([1, 2, 3])
34
+
35
+ array.count # => 3
36
+ array.map # => #<Enumerator: ...>
37
+ ```
38
+
39
+ It doesn't override the class name, but you still can access the original object.
40
+
41
+ ```ruby
42
+ array.class
43
+ # => SimpleDelegator
44
+ array.__getobj__.class
45
+ # => Array
46
+ ```
47
+
48
+ This means you can create a class that inherits from SimpleDelegator and customize its behaviour:
49
+
50
+ ```ruby
51
+ class ForeverZeroArray < SimpleDelegator
52
+ def omg!
53
+ "OMG!"
54
+ end
55
+
56
+ def count
57
+ 0
58
+ end
59
+ end
60
+ ```
61
+
62
+ You can define new methods or override existing ones:
63
+
64
+ ```ruby
65
+ ForeverZeroArray.new([1,2,3]).count
66
+ # => 0
67
+ ForeverZeroArray.new([1,2,3]).omg!
68
+ # => OMG!
69
+ ```
70
+
24
71
  ## Usage
25
72
 
26
- Resubject works on top of `SimpleDelegator` which simply delegates every method call to the delegated object. Example:
73
+ Using the `Resubject::Presenter` class, you can create Presenters from it. Example:
27
74
 
28
75
  ```ruby
29
76
  class Box < Struct.new(:name, :items)
@@ -136,7 +183,18 @@ product.price
136
183
  # => $10.00
137
184
  ```
138
185
 
139
- Check out [the extensions file](https://github.com/felipeelias/resubject/blob/master/lib/resubject/rails/extensions.rb) for other attribute helpers.
186
+ #### Available helpers
187
+
188
+ ```text
189
+ Presenter Maps to Class/Module
190
+
191
+ currency number_to_currency ActionView::Helpers::NumberHelper
192
+ percentage number_to_percentage ActionView::Helpers::NumberHelper
193
+ time_ago time_ago_in_words ActionView::Helpers::DateHelper
194
+ date_format to_s ActiveSupport::TimeWithZone
195
+ ```
196
+
197
+ More helpers will be added. Feel free to contribute with yours! Also, Check out [the extensions file](https://github.com/felipeelias/resubject/blob/master/lib/resubject/rails/extensions.rb).
140
198
 
141
199
  ## Maintainers
142
200
 
@@ -28,6 +28,88 @@ module Resubject
28
28
  template.number_to_currency to_model.send(attribute), options
29
29
  end
30
30
  end
31
+
32
+ # Generates an attribute using `time_ago_in_words` helper from rails
33
+ #
34
+ # @example
35
+ #
36
+ # class ProductPresenter < Resubject::Presenter
37
+ # time_ago :posted_at
38
+ # end
39
+ #
40
+ # # Will redefine the `posted_at` attribute using `time_ago_in_words`
41
+ #
42
+ # product.posted_at
43
+ # # => 'about 1 hour'
44
+ #
45
+ # @param [Symbol] attribute the name of the attribute to be generated
46
+ # @see http://apidock.com/rails/ActionView/Helpers/DateHelper/time_ago_in_words
47
+ def time_ago(attribute, include_seconds = false)
48
+ define_method attribute do
49
+ return if to_model.send(attribute).nil?
50
+ template.time_ago_in_words to_model.send(attribute), include_seconds
51
+ end
52
+ end
53
+
54
+ # Generates an attribute using `number_to_percentage` helper from rails
55
+ #
56
+ # @example
57
+ #
58
+ # class ProductPresenter < Resubject::Presenter
59
+ # percentage :rating
60
+ # end
61
+ #
62
+ # # Will create a `rating` attribute using `number_to_percentage`
63
+ #
64
+ # product.rating
65
+ # # => '95.000%'
66
+ #
67
+ # @example Also, any number_to_percentage options are accepted
68
+ #
69
+ # currency :rating, precision: 0 # => '95%'
70
+ # currency :rating, locale: :fr # => '1 000,000%'
71
+ #
72
+ # @param [Symbol] attribute the name of the presented attribute to be generated
73
+ # @param [Hash] options the options for `number_to_percentage` method
74
+ # @see http://apidock.com/rails/ActionView/Helpers/NumberHelper/number_to_percentage
75
+ def percentage(attribute, options = {})
76
+ define_method attribute do
77
+ template.number_to_percentage to_model.send(attribute), options
78
+ end
79
+ end
80
+
81
+ # Formats a date/time attribtue using `to_s` helper from ActiveSupport::TimeWithZone
82
+ #
83
+ # @example
84
+ #
85
+ # class PostPresenter < Resubject::Presenter
86
+ # date_format :created_at, :short
87
+ # end
88
+ #
89
+ # # Will generate a `created_at` method in the presenter
90
+ #
91
+ # post.created_at
92
+ # # => '13 Jan 14:10'
93
+ #
94
+ # @example Other accepted formats
95
+ #
96
+ # :db # => 2008-12-25 14:35:05
97
+ # :number # => 20081225143505
98
+ # :time # => 14:35
99
+ # :short # => 25 Dec 14:35
100
+ # :long # => December 25, 2008 14:35
101
+ # :long_ordinal # => December 25th, 2008 14:35
102
+ # :rfc822 # => Thu, 25 Dec 2008 14:35:05 +0000
103
+ #
104
+ # @param [Symbol] attribute the name of the presented attribute to be generated
105
+ # @param [Symbol] format the format defined in Time::DATE_FORMATS
106
+ # @see http://apidock.com/rails/ActiveSupport/TimeWithZone/to_s
107
+ def date_format(attribute, format = :default)
108
+ define_method attribute do
109
+ return if to_model.send(attribute).nil?
110
+ to_model.send(attribute).to_s(format)
111
+ end
112
+ end
31
113
  end
32
114
  end
33
115
  end
@@ -1,3 +1,3 @@
1
1
  module Resubject
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,13 +1,18 @@
1
1
  require 'spec_helper'
2
- require 'rails/all'
3
- require 'resubject/rails'
2
+ require 'action_view'
3
+ require 'resubject/rails/extensions'
4
4
 
5
5
  describe Resubject::Presenter, 'extensions' do
6
6
  let(:model) { mock :model }
7
7
 
8
8
  let(:presenter) do
9
9
  Class.new(Resubject::Presenter) do
10
+ extend Resubject::Rails::Extensions
11
+
10
12
  currency :price
13
+ time_ago :posted_at
14
+ percentage :rating, precision: 0
15
+ date_format :created_at, :short
11
16
  end
12
17
  end
13
18
 
@@ -21,4 +26,35 @@ describe Resubject::Presenter, 'extensions' do
21
26
  expect(subject.price).to eq "$10.00"
22
27
  end
23
28
  end
29
+
30
+ describe '.time_ago' do
31
+ it 'returns time ago in words' do
32
+ model.stub(:posted_at).and_return(Time.now - 60 * 60)
33
+ expect(subject.posted_at).to eq "about 1 hour"
34
+ end
35
+
36
+ it 'returns nothing if value is nil' do
37
+ model.stub(:posted_at).and_return(nil)
38
+ expect(subject.posted_at).to eq nil
39
+ end
40
+ end
41
+
42
+ describe '.percentage' do
43
+ it 'returns formatted percentage' do
44
+ model.stub(:rating).and_return(95.123)
45
+ expect(subject.rating).to eq "95%"
46
+ end
47
+ end
48
+
49
+ describe '.date_format' do
50
+ it 'returns formatted date' do
51
+ model.stub(:created_at).and_return(Time.at(1358082653).utc)
52
+ expect(subject.created_at).to eq "13 Jan 13:10"
53
+ end
54
+
55
+ it 'returns nothing if value is nil' do
56
+ model.stub(:created_at).and_return(nil)
57
+ expect(subject.created_at).to eq nil
58
+ end
59
+ end
24
60
  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
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-07 00:00:00.000000000 Z
13
+ date: 2013-01-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  type: :runtime
@@ -124,7 +124,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
124
  segments:
125
125
  - 0
126
126
  version: '0'
127
- hash: -3489835523721177517
127
+ hash: 1859410703920262887
128
128
  required_rubygems_version: !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  segments:
134
134
  - 0
135
135
  version: '0'
136
- hash: -3489835523721177517
136
+ hash: 1859410703920262887
137
137
  requirements: []
138
138
  rubyforge_project:
139
139
  rubygems_version: 1.8.24