show_for 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,150 @@
1
+ == ShowFor
2
+
3
+ ShowFor allows you to quickly show a model information with I18n features.
4
+
5
+ <% show_for @user do |u| %>
6
+ <%= u.attribute :name %>
7
+ <%= u.attribute :confirmed? %>
8
+ <%= u.attribute :created_at, :format => :short %>
9
+ <%= u.attribute :last_sign_in_at, :if_blank => "User did not access yet"
10
+ :wrapper_html => { :id => "sign_in_timestamp" } %>
11
+
12
+ <% u.attribute :photo do
13
+ <%= image_url(@user.photo_url) %>
14
+ end %>
15
+
16
+ <%= u.association :company %>
17
+ <%= u.association :tags, :to_sentence => true %>
18
+ <% end %>
19
+
20
+ == Installation
21
+
22
+ Install the gem:
23
+
24
+ sudo gem install show_for
25
+
26
+ Configure simple_form gem inside your app:
27
+
28
+ config.gem 'show_for'
29
+
30
+ Run the generator:
31
+
32
+ ruby script/generate show_for_install
33
+
34
+ And you're ready to go.
35
+
36
+ == Usage
37
+
38
+ ShowFor allows you to quickly show a model information with I18n features.
39
+
40
+ <% show_for @admin do |a| %>
41
+ <%= a.attribute :name %>
42
+ <%= a.attribute :confirmed? %>
43
+ <%= a.attribute :created_at, :format => :short %>
44
+ <%= a.attribute :last_sign_in_at, :if_blank => "Administrator did not access yet"
45
+ :wrapper_html => { :id => "sign_in_timestamp" } %>
46
+
47
+ <% a.attribute :photo do %>
48
+ <%= image_url(@admin.photo_url) %>
49
+ <% end %>
50
+ <% end %>
51
+
52
+ Will generate something like:
53
+
54
+ <div id="admin_1" class="show_for admin">
55
+ <p class="wrapper admin_name">
56
+ <b class="label">Name</b><br />
57
+ José Valim
58
+ </p>
59
+ <p class="wrapper admin_confirmed">
60
+ <b class="label">Confirmed?</b><br />
61
+ Yes
62
+ </p>
63
+ <p class="wrapper admin_created_at">
64
+ <b class="label">Created at</b><br />
65
+ 13/12/2009 - 19h17
66
+ </p>
67
+ <p id="sign_in_timestamp" class="wrapper admin_last_sign_in_at">
68
+ <b class="label">Last sign in at</b><br />
69
+ Administrator did not access yet
70
+ </p>
71
+ <p class="wrapper admin_photo">
72
+ <b class="label">Photo</b><br />
73
+ <img src="path/to/photo" />
74
+ </p>
75
+ </div>
76
+
77
+ == Value lookup
78
+
79
+ To show the proper value, before retrieving the attribute value, show_for first looks if a
80
+ block without argument was given, otherwise checks if a :"human_#{attribute}" method is defined
81
+ and, if not, only then retrieve the attribute.
82
+
83
+ == Options
84
+
85
+ show_for handles a series of options. Those are:
86
+
87
+ * :escape * - When the attribute should be escaped. True by default.
88
+
89
+ * :format * - Sent to I18n.localize when the attribute is a date/time object.
90
+
91
+ * :if_blank * - An object to be used if the value is blank. Not escaped as well.
92
+
93
+ Besides, all containers (:label, :content and :wrapper) can have their html
94
+ options configured through the :label_html, :content_html and :wrapper_html
95
+ options. Containers can have their tags configured on demand as well through
96
+ :label_tag, :content_tag and :wrapper_tag options.
97
+
98
+ == Label
99
+
100
+ show_for also exposes the label method. In case you want to use the default
101
+ human_attribute_name lookup and the default wrapping:
102
+
103
+ a.label :name #=> <b class="label">Name</b>
104
+ a.label "Name", :id => "my_name" #=> <b class="label" id="my_name">Name</b>
105
+
106
+ == Associations
107
+
108
+ show_for also supports associations.
109
+
110
+ <% show_for @artwork do |a| %>
111
+ <%= a.association :artist %>
112
+ <%= a.association :artist, :method => :name_with_title %>
113
+
114
+ <%= a.association :tags %>
115
+ <%= a.association :tags, :to_sentence => true %>
116
+ <% a.association :tags do
117
+ @artwork.tags.map(&:name).to_sentence
118
+ end %>
119
+
120
+ <% a.association :fans, :collection_tag => :ol do |fan| %>
121
+ <li><%= link_to fan.name, fan %></li>
122
+ <% end %>
123
+ <% end %>
124
+
125
+ The first is a has_one or belongs_to association, which works like an attribute
126
+ to show_for, except it will retrieve the artist association and try to find a
127
+ proper method from ShowFor.association_methods to be used. You can pass
128
+ the option :method to tell (and not guess) which method from the association
129
+ to use.
130
+
131
+ :tags is a has_and_belongs_to_many association which will return a collection.
132
+ show_for can handle collections by default by wrapping them in list (<ul> with
133
+ each item wrapped by an <li>). However, it also allows you to give :to_sentence
134
+ or :join it you want to render them inline.
135
+
136
+ You can also pass a block which expects an argument to association. In such cases,
137
+ a wrapper for the collection is still created and the block just iterates over the
138
+ collection objects.
139
+
140
+ == Contributors
141
+
142
+ * José Valim (http://github.com/josevalim)
143
+
144
+ == Bugs and Feedback
145
+
146
+ If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.
147
+
148
+ http://github.com/plataformatec/show_for/issues
149
+
150
+ MIT License. Copyright 2009 Plataforma Tecnologia. http://blog.plataformatec.com.br
@@ -0,0 +1,3 @@
1
+ To copy a ShowFor initializer to your Rails App, with some configuration values, just do:
2
+
3
+ script/generate show_for_install
@@ -0,0 +1,19 @@
1
+ class ShowForInstallGenerator < Rails::Generator::Base
2
+
3
+ def manifest
4
+ record do |m|
5
+ m.directory 'config/initializers'
6
+ m.template 'show_for.rb', 'config/initializers/show_for.rb'
7
+
8
+ m.directory 'config/locales'
9
+ m.template locale_file, 'config/locales/show_for.en.yml'
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def locale_file
16
+ @locale_file ||= '../../../lib/show_for/locale/en.yml'
17
+ end
18
+
19
+ end
@@ -0,0 +1,30 @@
1
+ # Use this setup block to configure all options available in ShowFor.
2
+ ShowFor.setup do |config|
3
+ # The tag which wraps show_for calls.
4
+ # config.show_for_tag = :div
5
+
6
+ # The tag which wraps each attribute/association call. Default is :p.
7
+ # config.wrapper_tag = :dl
8
+
9
+ # The tag used to wrap each label. Default is :strong.
10
+ # config.label_tag = :dt
11
+
12
+ # The tag used to wrap each content (value). Default is nil.
13
+ # config.content_tag = :dd
14
+
15
+ # The separator between label and content. Default is "<br />".
16
+ # config.separator = "<br />"
17
+
18
+ # The tag used to wrap collections. Default is :ul.
19
+ # config.collection_tag = :ul
20
+
21
+ # The default iterator to be used when invoking a collection/association.
22
+ # config.default_collection_proc = lambda { |value| "<li>#{value}</li>" }
23
+
24
+ # The default format to be used in I18n when localizing a Date/Time.
25
+ # config.i18n_format = :default
26
+
27
+ # Whenever a association is given, the first method in association_methods
28
+ # in which the association responds to is used to retrieve the association labels.
29
+ # config.association_methods = [ :name, :title, :to_s ]
30
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'show_for'
@@ -0,0 +1,98 @@
1
+ require 'show_for/content'
2
+ require 'show_for/label'
3
+
4
+ module ShowFor
5
+ class Builder
6
+ include ShowFor::Content
7
+ include ShowFor::Label
8
+
9
+ attr_reader :object, :template
10
+
11
+ def initialize(object, template)
12
+ @object, @template = object, template
13
+ end
14
+
15
+ def attribute(attribute_name, options={}, &block)
16
+ apply_default_options!(attribute_name, options)
17
+ collection_block, block = block, nil if collection_block?(block)
18
+
19
+ value = if block
20
+ block
21
+ elsif @object.respond_to?(:"human_#{attribute_name}")
22
+ @object.send :"human_#{attribute_name}"
23
+ else
24
+ @object.send(attribute_name)
25
+ end
26
+
27
+ wrap_label_and_content(attribute_name, value, options, &collection_block)
28
+ end
29
+
30
+ def association(association_name, options={}, &block)
31
+ apply_default_options!(association_name, options)
32
+
33
+ # If a block with an iterator was given, no need to calculate the labels
34
+ # since we want the collection to be yielded. Otherwise, calculate the values.
35
+ value = if collection_block?(block)
36
+ collection_block = block
37
+ @object.send(association_name)
38
+ elsif block
39
+ block
40
+ else
41
+ association = @object.send(association_name)
42
+ values = retrieve_values_from_association(association, options)
43
+
44
+ if options.delete(:to_sentence)
45
+ values.to_sentence
46
+ elsif joiner = options.delete(:join)
47
+ values.join(joiner)
48
+ else
49
+ values
50
+ end
51
+ end
52
+
53
+ wrap_label_and_content(association_name, value, options, &collection_block)
54
+ end
55
+
56
+ protected
57
+
58
+ def object_name #:nodoc:
59
+ @object_name ||= @object.class.name.underscore
60
+ end
61
+
62
+ def wrap_label_and_content(name, value, options, &block) #:nodoc:
63
+ wrap_with(:wrapper, label(name, options, false) + ShowFor.separator.to_s +
64
+ content(value, options, false, &block), options, true, value.is_a?(Proc))
65
+ end
66
+
67
+ # Set "#{object_name}_#{attribute_name}" as in the wrapper tag.
68
+ def apply_default_options!(name, options) #:nodoc:
69
+ html_class = "#{object_name}_#{name}".gsub(/\W/, '')
70
+ wrapper_html = options[:wrapper_html] ||= {}
71
+ wrapper_html[:class] = "#{html_class} #{wrapper_html[:class]}".strip
72
+ end
73
+
74
+ # Gets the default tag set in ShowFor module and apply (if defined)
75
+ # around the given content. It also check for html_options in @options
76
+ # hash related to the current type.
77
+ def wrap_with(type, content, options, safe=false, concat=false) #:nodoc:
78
+ tag = options.delete(:"#{type}_tag") || ShowFor.send(:"#{type}_tag")
79
+
80
+ html = if tag
81
+ html_options = options.delete(:"#{type}_html") || {}
82
+ html_options[:class] = "#{type} #{html_options[:class]}".strip
83
+ @template.content_tag(tag, content, html_options)
84
+ else
85
+ content
86
+ end
87
+
88
+ html.html_safe! if safe && html.respond_to?(:html_safe!)
89
+ concat ? @template.concat(html) : html
90
+ end
91
+
92
+ def retrieve_values_from_association(association, options) #:nodoc:
93
+ sample = association.is_a?(Array) ? association.first : association
94
+ method = options[:method] || ShowFor.association_methods.find { |m| sample.respond_to?(m) }
95
+ association.is_a?(Array) ? association.map(&method) : association.try(method)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,49 @@
1
+ module ShowFor
2
+ module Content
3
+ def content(value, options={}, apply_options=true, &block)
4
+ value = options.delete(:if_blank) if value.blank? && value != false
5
+
6
+ content = case value
7
+ when Date, Time, DateTime
8
+ I18n.l value, :format => options.delete(:format) || ShowFor.i18n_format
9
+ when TrueClass
10
+ I18n.t :"show_for.yes", :default => "Yes"
11
+ when FalseClass
12
+ I18n.t :"show_for.no", :default => "No"
13
+ when Array, Hash
14
+ options[:escape] = false
15
+ collection_handler(value, options, &block)
16
+ when Proc
17
+ options[:escape] = false
18
+ @template.capture(&value)
19
+ when NilClass
20
+ ""
21
+ else
22
+ value
23
+ end
24
+
25
+ content = @template.send(:h, content) unless options.delete(:escape) == false
26
+ options[:content_html] = options.dup if apply_options
27
+ wrap_with(:content, content, options)
28
+ end
29
+
30
+ protected
31
+
32
+ def collection_handler(value, options, &block) #:nodoc:
33
+ iterator = collection_block?(block) ? block : ShowFor.default_collection_proc
34
+ response = ""
35
+
36
+ value.each do |item|
37
+ response << template.capture(item, &iterator)
38
+ end
39
+
40
+ wrap_with(:collection, response, options)
41
+ end
42
+
43
+ # Returns true if the block is supposed to iterate through a collection,
44
+ # i.e. it has arity equals to one.
45
+ def collection_block?(block) #:nodoc:
46
+ block && block.arity == 1
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,25 @@
1
+ module ShowFor
2
+ module Helper
3
+ # Creates a div around the object and yields a builder.
4
+ #
5
+ # Example:
6
+ #
7
+ # show_for @user do |f|
8
+ # f.attribute :name
9
+ # f.attribute :email
10
+ # end
11
+ #
12
+ def show_for(object, html_options={}, &block)
13
+ tag = html_options.delete(:show_for_tag) || ShowFor.show_for_tag
14
+
15
+ html_options[:id] ||= dom_id(object)
16
+ html_options[:class] = "show_for #{dom_class(object)} #{html_options[:class]}".strip
17
+
18
+ concat(content_tag(tag, html_options) do
19
+ yield ShowFor::Builder.new(object, self)
20
+ end)
21
+ end
22
+ end
23
+ end
24
+
25
+ ActionView::Base.send :include, ShowFor::Helper
@@ -0,0 +1,23 @@
1
+ module ShowFor
2
+ module Label
3
+ def label(text_or_attribute, options={}, apply_options=true)
4
+ label = if text_or_attribute.is_a?(String)
5
+ text_or_attribute
6
+ elsif options.key?(:label)
7
+ options.delete(:label)
8
+ else
9
+ human_attribute_name(text_or_attribute)
10
+ end
11
+
12
+ return "" if label == false
13
+ options[:label_html] = options.dup if apply_options
14
+ wrap_with :label, label, options
15
+ end
16
+
17
+ protected
18
+
19
+ def human_attribute_name(attribute) #:nodoc:
20
+ @object.class.human_attribute_name(attribute.to_s)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ en:
2
+ show_for:
3
+ "yes": 'Yes'
4
+ "no": 'No'
@@ -0,0 +1,3 @@
1
+ module ShowFor
2
+ VERSION = "0.1".freeze
3
+ end
data/lib/show_for.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'show_for/helper'
2
+
3
+ module ShowFor
4
+ autoload :Builder, 'show_for/builder'
5
+
6
+ mattr_accessor :show_for_tag
7
+ @@show_for_tag = :div
8
+
9
+ mattr_accessor :label_tag
10
+ @@label_tag = :strong
11
+
12
+ mattr_accessor :separator
13
+ @@separator = "<br />"
14
+
15
+ mattr_accessor :content_tag
16
+ @@content_tag = nil
17
+
18
+ mattr_accessor :wrapper_tag
19
+ @@wrapper_tag = :p
20
+
21
+ mattr_accessor :collection_tag
22
+ @@collection_tag = :ul
23
+
24
+ mattr_accessor :default_collection_proc
25
+ @@default_collection_proc = lambda { |value| "<li>#{value}</li>" }
26
+
27
+ mattr_accessor :i18n_format
28
+ @@i18n_format = :default
29
+
30
+ mattr_accessor :association_methods
31
+ @@association_methods = [ :name, :title, :to_s ]
32
+
33
+ # Yield self for configuration block:
34
+ #
35
+ # ShowFor.setup do |config|
36
+ # config.i18n_format = :long
37
+ # end
38
+ #
39
+ def self.setup
40
+ yield self
41
+ end
42
+ end
@@ -0,0 +1,305 @@
1
+ require 'test_helper'
2
+
3
+ class BuilderTest < ActionView::TestCase
4
+
5
+ def with_attribute_for(object, attribute, options={}, &block)
6
+ show_for object do |o|
7
+ concat(o.attribute(attribute, options, &block))
8
+ end
9
+ end
10
+
11
+ def with_association_for(object, association, options={}, &block)
12
+ show_for object do |o|
13
+ concat(o.association(association, options, &block))
14
+ end
15
+ end
16
+
17
+ def with_label_for(object, attribute, options={})
18
+ show_for object do |o|
19
+ concat o.label attribute, options
20
+ end
21
+ end
22
+
23
+ def with_content_for(object, value, options={})
24
+ show_for object do |o|
25
+ concat o.content value, options
26
+ end
27
+ end
28
+
29
+ # WRAPPER
30
+ test "show_for attribute wraps each attribute with a label and content" do
31
+ with_attribute_for @user, :name
32
+ assert_select "div.show_for p.user_name.wrapper"
33
+ assert_select "div.show_for p.wrapper strong.label"
34
+ assert_select "div.show_for p.wrapper"
35
+ end
36
+
37
+ test "show_for allows wrapper tag to be changed by attribute" do
38
+ with_attribute_for @user, :name, :wrapper_tag => :span
39
+ assert_select "div.show_for span.user_name.wrapper"
40
+ end
41
+
42
+ test "show_for allows wrapper html to be configured by attribute" do
43
+ with_attribute_for @user, :name, :wrapper_html => { :id => "thewrapper", :class => "special" }
44
+ assert_select "div.show_for p#thewrapper.user_name.wrapper.special"
45
+ end
46
+
47
+ # SEPARATOR
48
+ test "show_for uses a separator if requested" do
49
+ with_attribute_for @user, :name
50
+ assert_select "div.show_for p.wrapper br"
51
+ end
52
+
53
+ test "show_for does not blow if a separator is not set" do
54
+ swap ShowFor, :separator => nil do
55
+ with_attribute_for @user, :name
56
+ assert_select "div.show_for p.wrapper"
57
+ end
58
+ end
59
+
60
+ # LABEL
61
+ test "show_for shows a label using the humanized attribute name from model" do
62
+ with_attribute_for @user, :name
63
+ assert_select "div.show_for p.wrapper strong.label", "Super User Name!"
64
+ end
65
+
66
+ test "show_for skips label if requested" do
67
+ with_attribute_for @user, :name, :label => false
68
+ assert_no_select "div.show_for p.wrapper strong.label"
69
+ end
70
+
71
+ test "show_for allows label to be configured globally" do
72
+ swap ShowFor, :label_tag => :span do
73
+ with_attribute_for @user, :name
74
+ assert_select "div.show_for p.wrapper span.label"
75
+ end
76
+ end
77
+
78
+ test "show_for allows label to be changed by attribute" do
79
+ with_attribute_for @user, :name, :label_tag => :span
80
+ assert_select "div.show_for p.wrapper span.label"
81
+ end
82
+
83
+ test "show_for allows label html to be configured by attribute" do
84
+ with_attribute_for @user, :name, :label_html => { :id => "thelabel", :class => "special" }
85
+ assert_select "div.show_for p.wrapper strong#thelabel.special.label"
86
+ end
87
+
88
+ test "show_for allows label to be set without lookup" do
89
+ with_attribute_for @user, :name, :label => "Special Label"
90
+ assert_select "div.show_for p.wrapper strong.label", "Special Label"
91
+ end
92
+
93
+ test "show_for#label accepts the text" do
94
+ with_label_for @user, "Special Label"
95
+ assert_select "div.show_for strong.label", "Special Label"
96
+ end
97
+
98
+ test "show_for#label accepts an attribute name" do
99
+ with_label_for @user, :name
100
+ assert_select "div.show_for strong.label", "Super User Name!"
101
+ end
102
+
103
+ test "show_for#label accepts html options" do
104
+ with_label_for @user, :name, :id => "thelabel", :class => "special"
105
+ assert_select "div.show_for strong#thelabel.special.label"
106
+ end
107
+
108
+ # CONTENT
109
+ test "show_for allows content tag to be configured globally" do
110
+ swap ShowFor, :content_tag => :span do
111
+ with_attribute_for @user, :name
112
+ assert_select "div.show_for p.wrapper span.content"
113
+ end
114
+ end
115
+
116
+ test "show_for allows content tag to be changed by attribute" do
117
+ with_attribute_for @user, :name, :content_tag => :span
118
+ assert_select "div.show_for p.wrapper span.content"
119
+ end
120
+
121
+ test "show_for allows content tag html to be configured by attribute" do
122
+ with_attribute_for @user, :name, :content_tag => :span, :content_html => { :id => "thecontent", :class => "special" }
123
+ assert_select "div.show_for p.wrapper span#thecontent.special.content"
124
+ end
125
+
126
+ test "show_for accepts an attribute as string" do
127
+ with_attribute_for @user, :name
128
+ assert_select "div.show_for p.wrapper", /ShowFor/
129
+ end
130
+
131
+ test "show_for accepts an attribute as time" do
132
+ with_attribute_for @user, :created_at
133
+ assert_select "div.show_for p.wrapper", /#{Regexp.escape(I18n.l(@user.created_at))}/
134
+ end
135
+
136
+ test "show_for accepts an attribute as date" do
137
+ with_attribute_for @user, :updated_at
138
+ assert_select "div.show_for p.wrapper", /#{Regexp.escape(I18n.l(@user.updated_at))}/
139
+ end
140
+
141
+ test "show_for accepts an attribute as time with format options" do
142
+ with_attribute_for @user, :created_at, :format => :long
143
+ assert_select "div.show_for p.wrapper", /#{Regexp.escape(I18n.l(@user.created_at, :format => :long))}/
144
+ end
145
+
146
+ test "show_for accepts an attribute as true" do
147
+ with_attribute_for @user, :active
148
+ assert_select "div.show_for p.wrapper", /Yes/
149
+ end
150
+
151
+ test "show_for accepts an attribute as true which can be localized" do
152
+ store_translations(:en, :show_for => { :yes => "Hell yeah!" }) do
153
+ with_attribute_for @user, :active
154
+ assert_select "div.show_for p.wrapper", /Hell yeah!/
155
+ end
156
+ end
157
+
158
+ test "show_for accepts an attribute as false" do
159
+ with_attribute_for @user, :invalid
160
+ assert_select "div.show_for p.wrapper", /No/
161
+ end
162
+
163
+ test "show_for accepts an attribute as false which can be localized" do
164
+ store_translations(:en, :show_for => { :no => "Hell no!" }) do
165
+ with_attribute_for @user, :invalid
166
+ assert_select "div.show_for p.wrapper", /Hell no!/
167
+ end
168
+ end
169
+
170
+ test "show_for accepts nil and or blank attributes" do
171
+ with_attribute_for @user, :description
172
+ assert_select "div.show_for p.wrapper", "Description"
173
+ end
174
+
175
+ test "show_for uses :if_blank if attribute is blank" do
176
+ with_attribute_for @user, :description, :if_blank => "No description provided"
177
+ assert_select "div.show_for p.wrapper", /No description provided/
178
+ end
179
+
180
+ test "show_for accepts a block to supply the content" do
181
+ with_attribute_for @user, :description do
182
+ "This description is not blank"
183
+ end
184
+ assert_select "div.show_for p.wrapper", /This description/
185
+ end
186
+
187
+ test "show_for escapes content by default" do
188
+ @user.name = "<b>hack you!</b>"
189
+ with_attribute_for @user, :name
190
+ assert_no_select "div.show_for p.wrapper b"
191
+ assert_select "div.show_for p.wrapper", /&lt;b&gt;/
192
+ end
193
+
194
+ test "show_for does not escape content if chosen" do
195
+ @user.name = "<b>hack you!</b>"
196
+ with_attribute_for @user, :name, :escape => false
197
+ assert_select "div.show_for p.wrapper b", "hack you!"
198
+ end
199
+
200
+ test "show_for#content accepts any object" do
201
+ with_content_for @user, "Special content"
202
+ assert_select "div.show_for", "Special content"
203
+ end
204
+
205
+ test "show_for#content accepts :if_blank as option" do
206
+ with_content_for @user, "", :if_blank => "Got blank"
207
+ assert_select "div.show_for", "Got blank"
208
+ end
209
+
210
+ test "show_for#content accepts html options" do
211
+ with_content_for @user, "Special content", :content_tag => :b, :id => "thecontent", :class => "special"
212
+ assert_select "div.show_for b#thecontent.special.content", "Special content"
213
+ end
214
+
215
+ # COLLECTIONS
216
+ test "show_for accepts an attribute as a collection" do
217
+ with_attribute_for @user, :scopes
218
+ assert_select "div.show_for p.wrapper ul.collection"
219
+ assert_select "div.show_for p.wrapper ul.collection li", :count => 3
220
+ end
221
+
222
+ test "show_for accepts an attribute as a collection with a block to iterate the collection" do
223
+ with_attribute_for @user, :scopes do |scope|
224
+ content_tag :span, scope
225
+ end
226
+ assert_select "div.show_for p.wrapper ul.collection"
227
+ assert_select "div.show_for p.wrapper ul.collection span", :count => 3
228
+ end
229
+
230
+ test "show_for allows collection tag to be configured globally" do
231
+ swap ShowFor, :collection_tag => :ol do
232
+ with_attribute_for @user, :scopes
233
+ assert_select "div.show_for p.wrapper ol.collection"
234
+ end
235
+ end
236
+
237
+ test "show_for allows collection tag to be changed by attribute" do
238
+ with_attribute_for @user, :scopes, :collection_tag => :ol
239
+ assert_select "div.show_for p.wrapper ol.collection"
240
+ end
241
+
242
+ test "show_for allows collection tag html to be configured by attribute" do
243
+ with_attribute_for @user, :scopes, :collection_html => { :id => "thecollection", :class => "special" }
244
+ assert_select "div.show_for p.wrapper ul#thecollection.special.collection"
245
+ end
246
+
247
+ # ASSOCIATIONS
248
+ test "show_for works with belongs_to/has_one associations" do
249
+ with_association_for @user, :company
250
+ assert_select "div.show_for p.wrapper", /PlataformaTec/
251
+ end
252
+
253
+ test "show_for accepts :method as option to tell how to retrieve association value" do
254
+ with_association_for @user, :company, :method => :alternate_name
255
+ assert_select "div.show_for p.wrapper", /Alternate PlataformaTec/
256
+ end
257
+
258
+ test "show_for works with has_many/has_and_belongs_to_many associations" do
259
+ with_association_for @user, :tags
260
+ assert_select "div.show_for p.wrapper ul.collection"
261
+ assert_select "div.show_for p.wrapper ul.collection li", "Tag 1"
262
+ assert_select "div.show_for p.wrapper ul.collection li", "Tag 2"
263
+ assert_select "div.show_for p.wrapper ul.collection li", "Tag 3"
264
+ end
265
+
266
+ test "show_for accepts :method as option to tell how to retrieve association values" do
267
+ with_association_for @user, :tags, :method => :alternate_name
268
+ assert_select "div.show_for p.wrapper ul.collection"
269
+ assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 1"
270
+ assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 2"
271
+ assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 3"
272
+ end
273
+
274
+ test "show_for accepts :to_sentence as option in collection associations" do
275
+ with_association_for @user, :tags, :to_sentence => true
276
+ assert_no_select "div.show_for p.wrapper ul.collection"
277
+ assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, and Tag 3/
278
+ end
279
+
280
+ test "show_for accepts :join as option in collection associations" do
281
+ with_association_for @user, :tags, :join => ", "
282
+ assert_no_select "div.show_for p.wrapper ul.collection"
283
+ assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, Tag 3/
284
+ end
285
+
286
+ test "show_for accepts a block without argument in collection associations" do
287
+ with_association_for @user, :tags do
288
+ @user.tags.map(&:name).to_sentence
289
+ end
290
+ assert_no_select "div.show_for p.wrapper ul.collection"
291
+ assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, and Tag 3/
292
+ end
293
+
294
+ test "show_for accepts a block with argument in collection associations" do
295
+ with_association_for @user, :tags, :collection_tag => :p do |tag|
296
+ assert_kind_of Tag, tag
297
+ content_tag(:span, tag.name)
298
+ end
299
+ assert_no_select "div.show_for p.wrapper ul.collection"
300
+ assert_select "div.show_for p.wrapper p.collection"
301
+ assert_select "div.show_for p.wrapper p.collection span", "Tag 1"
302
+ assert_select "div.show_for p.wrapper p.collection span", "Tag 2"
303
+ assert_select "div.show_for p.wrapper p.collection span", "Tag 3"
304
+ end
305
+ end
@@ -0,0 +1,31 @@
1
+ require "test_helper"
2
+
3
+ class HelperTest < ActionView::TestCase
4
+ test "show for yields an instance of ShowFor::Builder" do
5
+ show_for @user do |f|
6
+ assert f.instance_of?(ShowFor::Builder)
7
+ end
8
+ end
9
+
10
+ test "show for should add default class to form" do
11
+ show_for @user do |f| end
12
+ assert_select "div.show_for"
13
+ end
14
+
15
+ test "show for should add object class name as css class to form" do
16
+ show_for @user do |f| end
17
+ assert_select "div.show_for.user"
18
+ end
19
+
20
+ test "show for should pass options" do
21
+ show_for @user, :id => "my_div", :class => "common" do |f| end
22
+ assert_select "div#my_div.show_for.user.common"
23
+ end
24
+
25
+ test "show for tag should be configurable" do
26
+ swap ShowFor, :show_for_tag => :p do
27
+ show_for @user do |f| end
28
+ assert_select "p.show_for"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module MiscHelpers
2
+ def store_translations(locale, translations, &block)
3
+ begin
4
+ I18n.backend.store_translations locale, translations
5
+ yield
6
+ ensure
7
+ I18n.reload!
8
+ end
9
+ end
10
+
11
+ def assert_no_select(*args)
12
+ assert_raise Test::Unit::AssertionFailedError do
13
+ assert_select(*args)
14
+ end
15
+ end
16
+
17
+ def swap(object, new_values)
18
+ old_values = {}
19
+ new_values.each do |key, value|
20
+ old_values[key] = object.send key
21
+ object.send :"#{key}=", value
22
+ end
23
+ yield
24
+ ensure
25
+ old_values.each do |key, value|
26
+ object.send :"#{key}=", value
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,45 @@
1
+ require 'ostruct'
2
+
3
+ class Company < Struct.new(:id, :name)
4
+ def alternate_name
5
+ "Alternate #{self.name}"
6
+ end
7
+ end
8
+
9
+ class Tag < Struct.new(:id, :name)
10
+ def self.all(options={})
11
+ (1..3).map{ |i| Tag.new(i, "Tag #{i}") }
12
+ end
13
+
14
+ def alternate_name
15
+ "Alternate #{self.name}"
16
+ end
17
+ end
18
+
19
+ class User < OpenStruct
20
+ # Get rid of deprecation warnings
21
+ undef_method :id
22
+
23
+ def tags
24
+ Tag.all
25
+ end
26
+
27
+ def company
28
+ Company.new(1, "PlataformaTec")
29
+ end
30
+
31
+ def self.human_attribute_name(attribute)
32
+ case attribute
33
+ when 'name'
34
+ 'Super User Name!'
35
+ when 'company'
36
+ 'Company Human Name!'
37
+ else
38
+ attribute.humanize
39
+ end
40
+ end
41
+
42
+ def self.human_name
43
+ "User"
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ require 'action_controller'
5
+ require 'action_view/test_case'
6
+
7
+ begin
8
+ require 'ruby-debug'
9
+ rescue LoadError
10
+ end
11
+
12
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib', 'show_for')
13
+ require 'show_for'
14
+
15
+ Dir["#{File.dirname(__FILE__)}/support/*.rb"].each { |f| require f }
16
+ I18n.default_locale = :en
17
+
18
+ class ActionView::TestCase
19
+ include MiscHelpers
20
+
21
+ tests ShowFor::Helper
22
+
23
+ setup :setup_new_user
24
+
25
+ def setup_new_user(options={})
26
+ @user = User.new({
27
+ :id => 1,
28
+ :name => 'ShowFor',
29
+ :description => '',
30
+ :active => true,
31
+ :invalid => false,
32
+ :scopes => ["admin", "manager", "visitor"],
33
+ :created_at => Time.now,
34
+ :updated_at => Date.today
35
+ }.merge(options))
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: show_for
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - "Jos\xC3\xA9 Valim"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-08 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Wrap your objects with a helper to easily show them
17
+ email: contact@plataformatec.com.br
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - generators/show_for_install/USAGE
26
+ - generators/show_for_install/show_for_install_generator.rb
27
+ - generators/show_for_install/templates/show_for.rb
28
+ - init.rb
29
+ - lib/show_for.rb
30
+ - lib/show_for/builder.rb
31
+ - lib/show_for/content.rb
32
+ - lib/show_for/helper.rb
33
+ - lib/show_for/label.rb
34
+ - lib/show_for/locale/en.yml
35
+ - lib/show_for/version.rb
36
+ - README.rdoc
37
+ has_rdoc: true
38
+ homepage: http://github.com/plataformatec/show_for
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Wrap your objects with a helper to easily show them
65
+ test_files:
66
+ - test/builder_test.rb
67
+ - test/helper_test.rb
68
+ - test/support/misc_helpers.rb
69
+ - test/support/models.rb
70
+ - test/test_helper.rb