Skip to content

Commit

Permalink
Added specs for associations.
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Dec 15, 2009
1 parent fa47cdc commit 2d5fe6c
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 18 deletions.
5 changes: 3 additions & 2 deletions lib/show_for.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'show_for/form_helper'
require 'show_for/helper'

module ShowFor
autoload :Builder, 'show_for/builder'
Expand Down Expand Up @@ -28,13 +28,14 @@ module ShowFor
@@i18n_format = :default

mattr_accessor :association_methods
@@label_methods = [ :name, :title, :to_s ]
@@association_methods = [ :name, :title, :to_s ]

# Yield self for configuration block:
#
# ShowFor.setup do |config|
# config.i18n_format = :long
# end
#
def self.setup
yield self
end
Expand Down
8 changes: 4 additions & 4 deletions lib/show_for/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ def attribute(attribute_name, options={}, &block)

def association(association_name, options={}, &block)
apply_default_options!(association_name, options)
association = @object.send(association_name)

# If a block with an iterator was given, no need to calculate the labels
# since we want the collection to be yielded. Otherwise, calculate the values.
@value = if collection_block?(block)
value = if collection_block?(block)
collection_block = block
association
@object.send(association_name)
elsif block
block
else
association = @object.send(association_name)
values = retrieve_values_from_association(association, options)

if options.delete(:to_sentence)
Expand Down Expand Up @@ -91,7 +91,7 @@ def wrap_with(type, content, options, safe=false, concat=false) #:nodoc:
def retrieve_values_from_association(association, options) #:nodoc:
sample = association.is_a?(Array) ? association.first : association
method = options[:method] || ShowFor.association_methods.find { |m| sample.respond_to?(m) }
association.is_a?(Array) ? association.map(&method) : association.send(method)
association.is_a?(Array) ? association.map(&method) : association.try(method)
end
end
end
4 changes: 2 additions & 2 deletions lib/show_for/form_helper.rb → lib/show_for/helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module ShowFor
module FormHelper
module Helper
# Creates a div around the object and yields a builder.
#
# Example:
Expand All @@ -22,4 +22,4 @@ def show_for(object, html_options={}, &block)
end
end

ActionView::Base.send :include, ShowFor::FormHelper
ActionView::Base.send :include, ShowFor::Helper
65 changes: 65 additions & 0 deletions test/builder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ def with_attribute_for(object, attribute, options={}, &block)
end
end

def with_association_for(object, association, options={}, &block)
show_for object do |o|
concat(o.association(association, options, &block))
end
end

def with_label_for(object, attribute, options={})
show_for object do |o|
concat o.label attribute, options
Expand Down Expand Up @@ -226,4 +232,63 @@ def with_content_for(object, value, options={})
with_attribute_for @user, :scopes, :collection_html => { :id => "thecollection", :class => "special" }
assert_select "div.show_for p.wrapper ul#thecollection.special.collection"
end

# ASSOCIATIONS
test "show_for works with belongs_to/has_one associations" do
with_association_for @user, :company
assert_select "div.show_for p.wrapper", /PlataformaTec/
end

test "show_for accepts :method as option to tell how to retrieve association value" do
with_association_for @user, :company, :method => :alternate_name
assert_select "div.show_for p.wrapper", /Alternate PlataformaTec/
end

test "show_for works with has_many/has_and_belongs_to_many associations" do
with_association_for @user, :tags
assert_select "div.show_for p.wrapper ul.collection"
assert_select "div.show_for p.wrapper ul.collection li", "Tag 1"
assert_select "div.show_for p.wrapper ul.collection li", "Tag 2"
assert_select "div.show_for p.wrapper ul.collection li", "Tag 3"
end

test "show_for accepts :method as option to tell how to retrieve association values" do
with_association_for @user, :tags, :method => :alternate_name
assert_select "div.show_for p.wrapper ul.collection"
assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 1"
assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 2"
assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 3"
end

test "show_for accepts :to_sentence as option in collection associations" do
with_association_for @user, :tags, :to_sentence => true
assert_no_select "div.show_for p.wrapper ul.collection"
assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, and Tag 3/
end

test "show_for accepts :join as option in collection associations" do
with_association_for @user, :tags, :join => ", "
assert_no_select "div.show_for p.wrapper ul.collection"
assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, Tag 3/
end

test "show_for accepts a block without argument in collection associations" do
with_association_for @user, :tags do
@user.tags.map(&:name).to_sentence
end
assert_no_select "div.show_for p.wrapper ul.collection"
assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, and Tag 3/
end

test "show_for accepts a block with argument in collection associations" do
with_association_for @user, :tags, :collection_tag => :p do |tag|
assert_kind_of Tag, tag
content_tag(:span, tag.name)
end
assert_no_select "div.show_for p.wrapper ul.collection"
assert_select "div.show_for p.wrapper p.collection"
assert_select "div.show_for p.wrapper p.collection span", "Tag 1"
assert_select "div.show_for p.wrapper p.collection span", "Tag 2"
assert_select "div.show_for p.wrapper p.collection span", "Tag 3"
end
end
31 changes: 31 additions & 0 deletions test/helper_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require "test_helper"

class HelperTest < ActionView::TestCase
test "show for yields an instance of ShowFor::Builder" do
show_for @user do |f|
assert f.instance_of?(ShowFor::Builder)
end
end

test "show for should add default class to form" do
show_for @user do |f| end
assert_select "div.show_for"
end

test "show for should add object class name as css class to form" do
show_for @user do |f| end
assert_select "div.show_for.user"
end

test "show for should pass options" do
show_for @user, :id => "my_div", :class => "common" do |f| end
assert_select "div#my_div.show_for.user.common"
end

test "show for tag should be configurable" do
swap ShowFor, :show_for_tag => :p do
show_for @user do |f| end
assert_select "p.show_for"
end
end
end
24 changes: 15 additions & 9 deletions test/support/models.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
require 'ostruct'

Column = Struct.new(:name, :type, :limit)
Association = Struct.new(:klass, :name, :macro, :options)

class Company < Struct.new(:id, :name)
def self.all(options={})
all = (1..3).map{|i| Company.new(i, "Company #{i}")}
return [all.first] if options[:conditions]
return [all.last] if options[:order]
all
def alternate_name
"Alternate #{self.name}"
end
end

class Tag < Struct.new(:id, :name)
def self.all(options={})
(1..3).map{|i| Tag.new(i, "Tag #{i}")}
(1..3).map{ |i| Tag.new(i, "Tag #{i}") }
end

def alternate_name
"Alternate #{self.name}"
end
end

class User < OpenStruct
# Get rid of deprecation warnings
undef_method :id

def tags
Tag.all
end

def company
Company.new(1, "PlataformaTec")
end

def self.human_attribute_name(attribute)
case attribute
when 'name'
Expand Down
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class ActionView::TestCase
include MiscHelpers

tests ShowFor::FormHelper
tests ShowFor::Helper

setup :setup_new_user

Expand Down

0 comments on commit 2d5fe6c

Please sign in to comment.