giraffesoft-attribute_fu 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/MIT-LICENSE +20 -0
- data/README +115 -0
- data/Rakefile +22 -0
- data/init.rb +2 -0
- data/lib/attribute_fu.rb +2 -0
- data/lib/attribute_fu/associated_form_helper.rb +139 -0
- data/lib/attribute_fu/associations.rb +124 -0
- data/tasks/attribute_fu_tasks.rake +4 -0
- data/test/Rakefile +10 -0
- data/test/app/controllers/application.rb +10 -0
- data/test/app/helpers/application_helper.rb +3 -0
- data/test/app/models/comment.rb +8 -0
- data/test/app/models/photo.rb +3 -0
- data/test/config/boot.rb +97 -0
- data/test/config/database.yml +15 -0
- data/test/config/environment.rb +15 -0
- data/test/config/environments/development.rb +18 -0
- data/test/config/environments/test.rb +22 -0
- data/test/config/routes.rb +35 -0
- data/test/db/migrate/001_create_photos.rb +14 -0
- data/test/db/migrate/002_create_comments.rb +15 -0
- data/test/db/schema.rb +29 -0
- data/test/script/console +3 -0
- data/test/script/destroy +3 -0
- data/test/script/generate +3 -0
- data/test/script/server +3 -0
- data/test/test/test_helper.rb +6 -0
- data/test/test/unit/associated_form_helper_test.rb +376 -0
- data/test/test/unit/comment_test.rb +6 -0
- data/test/test/unit/photo_test.rb +149 -0
- data/test/vendor/plugins/shoulda/init.rb +3 -0
- data/test/vendor/plugins/shoulda/lib/shoulda.rb +20 -0
- data/test/vendor/plugins/shoulda/lib/shoulda/active_record_helpers.rb +338 -0
- data/test/vendor/plugins/shoulda/lib/shoulda/context.rb +143 -0
- data/test/vendor/plugins/shoulda/lib/shoulda/general.rb +119 -0
- data/test/vendor/plugins/shoulda/lib/shoulda/private_helpers.rb +17 -0
- data/uninstall.rb +1 -0
- metadata +110 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
# Filters added to this controller apply to all controllers in the application.
|
2
|
+
# Likewise, all the methods added will be available for all controllers.
|
3
|
+
|
4
|
+
class ApplicationController < ActionController::Base
|
5
|
+
helper :all # include all helpers, all the time
|
6
|
+
|
7
|
+
# See ActionController::RequestForgeryProtection for details
|
8
|
+
# Uncomment the :secret if you're not using the cookie session store
|
9
|
+
protect_from_forgery # :secret => '012cbaf0c3d36504f3b1bc397b838d24'
|
10
|
+
end
|
data/test/config/boot.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Don't change this file!
|
2
|
+
# Configure your app in config/environment.rb and config/environments/*.rb
|
3
|
+
|
4
|
+
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
|
5
|
+
|
6
|
+
module Rails
|
7
|
+
class << self
|
8
|
+
def boot!
|
9
|
+
pick_boot.run unless booted?
|
10
|
+
end
|
11
|
+
|
12
|
+
def booted?
|
13
|
+
defined? Rails::Initializer
|
14
|
+
end
|
15
|
+
|
16
|
+
def pick_boot
|
17
|
+
(vendor_rails? ? VendorBoot : GemBoot).new
|
18
|
+
end
|
19
|
+
|
20
|
+
def vendor_rails?
|
21
|
+
File.exist?("#{RAILS_ROOT}/vendor/rails")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Boot
|
26
|
+
def run
|
27
|
+
load_initializer
|
28
|
+
Rails::Initializer.run(:set_load_path)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class VendorBoot < Boot
|
33
|
+
def load_initializer
|
34
|
+
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class GemBoot < Boot
|
39
|
+
def load_initializer
|
40
|
+
self.class.load_rubygems
|
41
|
+
load_rails_gem
|
42
|
+
require 'initializer'
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_rails_gem
|
46
|
+
if version = self.class.gem_version
|
47
|
+
gem 'rails', "=#{version}"
|
48
|
+
else
|
49
|
+
gem 'rails'
|
50
|
+
end
|
51
|
+
rescue Gem::LoadError => load_error
|
52
|
+
$stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
|
53
|
+
exit 1
|
54
|
+
end
|
55
|
+
|
56
|
+
class << self
|
57
|
+
def rubygems_version
|
58
|
+
Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
|
59
|
+
end
|
60
|
+
|
61
|
+
def gem_version
|
62
|
+
if defined? RAILS_GEM_VERSION
|
63
|
+
RAILS_GEM_VERSION
|
64
|
+
elsif ENV.include?('RAILS_GEM_VERSION')
|
65
|
+
ENV['RAILS_GEM_VERSION']
|
66
|
+
else
|
67
|
+
parse_gem_version(read_environment_rb)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def load_rubygems
|
72
|
+
require 'rubygems'
|
73
|
+
|
74
|
+
unless rubygems_version >= '0.9.4'
|
75
|
+
$stderr.puts %(Rails requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.)
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
|
79
|
+
rescue LoadError
|
80
|
+
$stderr.puts %(Rails requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org)
|
81
|
+
exit 1
|
82
|
+
end
|
83
|
+
|
84
|
+
def parse_gem_version(text)
|
85
|
+
$1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*'([\d.]+)'/
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def read_environment_rb
|
90
|
+
File.read("#{RAILS_ROOT}/config/environment.rb")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# All that for this:
|
97
|
+
Rails.boot!
|
@@ -0,0 +1,15 @@
|
|
1
|
+
development:
|
2
|
+
adapter: mysql
|
3
|
+
encoding: utf8
|
4
|
+
database: attribute_fu_test
|
5
|
+
username: root
|
6
|
+
password:
|
7
|
+
socket: /tmp/mysql.sock
|
8
|
+
|
9
|
+
test:
|
10
|
+
adapter: mysql
|
11
|
+
encoding: utf8
|
12
|
+
database: attribute_fu_test
|
13
|
+
username: root
|
14
|
+
password:
|
15
|
+
socket: /tmp/mysql.sock
|
@@ -0,0 +1,15 @@
|
|
1
|
+
$:.reject! { |e| e.include? 'TextMate' }
|
2
|
+
RAILS_GEM_VERSION = '2.0.2' unless defined? RAILS_GEM_VERSION
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
5
|
+
|
6
|
+
Rails::Initializer.run do |config|
|
7
|
+
config.action_controller.session = {
|
8
|
+
:session_key => '_test_session',
|
9
|
+
:secret => '012cbaf0c3d36504f3b1bc397b838d24'
|
10
|
+
}
|
11
|
+
|
12
|
+
config.load_paths += %W( #{RAILS_ROOT}/../lib )
|
13
|
+
end
|
14
|
+
|
15
|
+
require "#{RAILS_ROOT}/../init"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
+
|
3
|
+
# In the development environment your application's code is reloaded on
|
4
|
+
# every request. This slows down response time but is perfect for development
|
5
|
+
# since you don't have to restart the webserver when you make code changes.
|
6
|
+
config.cache_classes = false
|
7
|
+
|
8
|
+
# Log error messages when you accidentally call methods on nil.
|
9
|
+
config.whiny_nils = true
|
10
|
+
|
11
|
+
# Show full error reports and disable caching
|
12
|
+
config.action_controller.consider_all_requests_local = true
|
13
|
+
config.action_controller.perform_caching = false
|
14
|
+
config.action_view.cache_template_extensions = false
|
15
|
+
config.action_view.debug_rjs = true
|
16
|
+
|
17
|
+
# Don't care if the mailer can't send
|
18
|
+
config.action_mailer.raise_delivery_errors = false
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
+
|
3
|
+
# The test environment is used exclusively to run your application's
|
4
|
+
# test suite. You never need to work with it otherwise. Remember that
|
5
|
+
# your test database is "scratch space" for the test suite and is wiped
|
6
|
+
# and recreated between test runs. Don't rely on the data there!
|
7
|
+
config.cache_classes = true
|
8
|
+
|
9
|
+
# Log error messages when you accidentally call methods on nil.
|
10
|
+
config.whiny_nils = true
|
11
|
+
|
12
|
+
# Show full error reports and disable caching
|
13
|
+
config.action_controller.consider_all_requests_local = true
|
14
|
+
config.action_controller.perform_caching = false
|
15
|
+
|
16
|
+
# Disable request forgery protection in test environment
|
17
|
+
config.action_controller.allow_forgery_protection = false
|
18
|
+
|
19
|
+
# Tell ActionMailer not to deliver emails to the real world.
|
20
|
+
# The :test delivery method accumulates sent emails in the
|
21
|
+
# ActionMailer::Base.deliveries array.
|
22
|
+
config.action_mailer.delivery_method = :test
|
@@ -0,0 +1,35 @@
|
|
1
|
+
ActionController::Routing::Routes.draw do |map|
|
2
|
+
# The priority is based upon order of creation: first created -> highest priority.
|
3
|
+
|
4
|
+
# Sample of regular route:
|
5
|
+
# map.connect 'products/:id', :controller => 'catalog', :action => 'view'
|
6
|
+
# Keep in mind you can assign values other than :controller and :action
|
7
|
+
|
8
|
+
# Sample of named route:
|
9
|
+
# map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
|
10
|
+
# This route can be invoked with purchase_url(:id => product.id)
|
11
|
+
|
12
|
+
# Sample resource route (maps HTTP verbs to controller actions automatically):
|
13
|
+
# map.resources :products
|
14
|
+
|
15
|
+
# Sample resource route with options:
|
16
|
+
# map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
|
17
|
+
|
18
|
+
# Sample resource route with sub-resources:
|
19
|
+
# map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
|
20
|
+
|
21
|
+
# Sample resource route within a namespace:
|
22
|
+
# map.namespace :admin do |admin|
|
23
|
+
# # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
|
24
|
+
# admin.resources :products
|
25
|
+
# end
|
26
|
+
|
27
|
+
# You can have the root of your site routed with map.root -- just remember to delete public/index.html.
|
28
|
+
# map.root :controller => "welcome"
|
29
|
+
|
30
|
+
# See how all your routes lay out with "rake routes"
|
31
|
+
|
32
|
+
# Install the default routes as the lowest priority.
|
33
|
+
map.connect ':controller/:action/:id'
|
34
|
+
map.connect ':controller/:action/:id.:format'
|
35
|
+
end
|
data/test/db/schema.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead of editing this file,
|
2
|
+
# please use the migrations feature of ActiveRecord to incrementally modify your database, and
|
3
|
+
# then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your database schema. If you need
|
6
|
+
# to create the application database on another system, you should be using db:schema:load, not running
|
7
|
+
# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
8
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
9
|
+
#
|
10
|
+
# It's strongly recommended to check this file into your version control system.
|
11
|
+
|
12
|
+
ActiveRecord::Schema.define(:version => 2) do
|
13
|
+
|
14
|
+
create_table "comments", :force => true do |t|
|
15
|
+
t.integer "photo_id"
|
16
|
+
t.string "author"
|
17
|
+
t.text "body"
|
18
|
+
t.datetime "created_at"
|
19
|
+
t.datetime "updated_at"
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table "photos", :force => true do |t|
|
23
|
+
t.string "title"
|
24
|
+
t.text "description"
|
25
|
+
t.datetime "created_at"
|
26
|
+
t.datetime "updated_at"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/test/script/console
ADDED
data/test/script/destroy
ADDED
data/test/script/server
ADDED
@@ -0,0 +1,376 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../test_helper'
|
2
|
+
|
3
|
+
class AssociatedFormHelperTest < Test::Unit::TestCase
|
4
|
+
include ActionView::Helpers::FormHelper
|
5
|
+
include ActionView::Helpers::FormTagHelper
|
6
|
+
include ActionView::Helpers::UrlHelper
|
7
|
+
include ActionView::Helpers::TagHelper
|
8
|
+
include ActionView::Helpers::TextHelper
|
9
|
+
include AttributeFu::AssociatedFormHelper
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@photo = Photo.create
|
13
|
+
@controller = mock()
|
14
|
+
@controller.stubs(:url_for).returns 'asdf'
|
15
|
+
@controller.stubs(:protect_against_forgery?).returns false
|
16
|
+
stubs(:protect_against_forgery?).returns false
|
17
|
+
end
|
18
|
+
|
19
|
+
context "fields for associated" do
|
20
|
+
context "with existing object" do
|
21
|
+
setup do
|
22
|
+
@photo.comments.create :author => "Barry", :body => "Oooh I did good today..."
|
23
|
+
|
24
|
+
@erbout = assoc_output @photo.comments.first
|
25
|
+
end
|
26
|
+
|
27
|
+
should "name field with attribute_fu naming conventions" do
|
28
|
+
assert_match "photo[comment_attributes][#{@photo.comments.first.id}]", @erbout
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with non-existent object" do
|
33
|
+
setup do
|
34
|
+
@erbout = assoc_output(@photo.comments.build) do |f|
|
35
|
+
f.fields_for_associated(@photo.comments.build) do |comment|
|
36
|
+
comment.text_field(:author)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
should "name field with attribute_fu naming conventions" do
|
42
|
+
assert_match "photo[comment_attributes][new][0]", @erbout
|
43
|
+
end
|
44
|
+
|
45
|
+
should "maintain the numbering of the new object if called again" do
|
46
|
+
assert_match "photo[comment_attributes][new][1]", @erbout
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with overridden name" do
|
51
|
+
setup do
|
52
|
+
_erbout = ''
|
53
|
+
fields_for(:photo) do |f|
|
54
|
+
f.fields_for_associated(@photo.comments.build, :name => :something_else) do |comment|
|
55
|
+
_erbout.concat comment.text_field(:author)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@erbout = _erbout
|
60
|
+
end
|
61
|
+
|
62
|
+
should "use override name" do
|
63
|
+
assert_dom_equal "<input name='photo[something_else_attributes][new][0][author]' size='30' type='text' id='photo_something_else_attributes__new__0_author' />", @erbout
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "remove link" do
|
69
|
+
context "with just a name" do
|
70
|
+
setup do
|
71
|
+
remove_link "remove"
|
72
|
+
end
|
73
|
+
|
74
|
+
should "create a link" do
|
75
|
+
assert_match ">remove</a>", @erbout
|
76
|
+
end
|
77
|
+
|
78
|
+
should "infer the name of the current @object in fields_for" do
|
79
|
+
assert_match "$(this).up('.comment').remove()", @erbout
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "with an alternate CSS selector" do
|
84
|
+
setup do
|
85
|
+
remove_link "remove", :selector => '.blah'
|
86
|
+
end
|
87
|
+
|
88
|
+
should "use the alternate selector" do
|
89
|
+
assert_match "$(this).up('.blah').remove()", @erbout
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "with an extra function" do
|
94
|
+
setup do
|
95
|
+
@other_function = "$('asdf').blah();"
|
96
|
+
remove_link "remove", :function => @other_function
|
97
|
+
end
|
98
|
+
|
99
|
+
should "still infer the name of the current @object in fields_for, and create the function as usual" do
|
100
|
+
assert_match "$(this).up('.comment').remove()", @erbout
|
101
|
+
end
|
102
|
+
|
103
|
+
should "append the secondary function" do
|
104
|
+
assert_match @other_function, @erbout
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "with javascript flag" do
|
110
|
+
setup do
|
111
|
+
_erbout = ''
|
112
|
+
fields_for(:photo) do |f|
|
113
|
+
_erbout.concat(f.fields_for_associated(@photo.comments.build, :javascript => true) do |comment|
|
114
|
+
comment.text_field(:author)
|
115
|
+
end)
|
116
|
+
end
|
117
|
+
|
118
|
+
@erbout = _erbout
|
119
|
+
end
|
120
|
+
|
121
|
+
should "use placeholders instead of numbers" do
|
122
|
+
assert_match 'photo[comment_attributes][new][#{number}]', @erbout
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "add_associated_link " do
|
127
|
+
setup do
|
128
|
+
comment = @photo.comments.build
|
129
|
+
|
130
|
+
_erbout = ''
|
131
|
+
fields_for(:photo) do |f|
|
132
|
+
f.stubs(:render_associated_form).with(comment, :fields_for => {:javascript => true}, :partial => 'comment')
|
133
|
+
_erbout.concat f.add_associated_link("Add Comment", comment, :class => 'something')
|
134
|
+
end
|
135
|
+
|
136
|
+
@erbout = _erbout
|
137
|
+
end
|
138
|
+
|
139
|
+
should "create link" do
|
140
|
+
assert_match ">Add Comment</a>", @erbout
|
141
|
+
end
|
142
|
+
|
143
|
+
should "insert into the bottom of the parent container by default" do
|
144
|
+
assert_match "Insertion.Bottom('comments'", @erbout
|
145
|
+
end
|
146
|
+
|
147
|
+
should "wrap the partial in a prototype template" do
|
148
|
+
assert_match "new Template", @erbout
|
149
|
+
assert_match "evaluate", @erbout
|
150
|
+
end
|
151
|
+
|
152
|
+
should "name the variable correctly" do
|
153
|
+
assert_match "attribute_fu_comment_count", @erbout
|
154
|
+
end
|
155
|
+
|
156
|
+
should "pass along the additional options to the link_to_function call" do
|
157
|
+
assert_match 'class="something"', @erbout
|
158
|
+
end
|
159
|
+
|
160
|
+
should "produce the following link" do
|
161
|
+
# this is a way of testing the whole link
|
162
|
+
assert_equal %{
|
163
|
+
<a class=\"something\" href=\"#\" onclick=\"if (typeof attribute_fu_comment_count == 'undefined') attribute_fu_comment_count = 0;\nnew Insertion.Bottom('comments', new Template(null).evaluate({'number': --attribute_fu_comment_count})); return false;\">Add Comment</a>
|
164
|
+
}.strip, @erbout
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "add_associated_link with parameters" do
|
169
|
+
setup do
|
170
|
+
comment = @photo.comments.build
|
171
|
+
|
172
|
+
_erbout = ''
|
173
|
+
fields_for(:photo) do |f|
|
174
|
+
f.stubs(:render_associated_form).with(comment, :fields_for => {:javascript => true}, :partial => 'some_other_partial')
|
175
|
+
_erbout.concat f.add_associated_link("Add Comment", comment, :container => 'something_comments', :partial => 'some_other_partial')
|
176
|
+
end
|
177
|
+
|
178
|
+
@erbout = _erbout
|
179
|
+
end
|
180
|
+
|
181
|
+
should "create link" do
|
182
|
+
assert_match ">Add Comment</a>", @erbout
|
183
|
+
end
|
184
|
+
|
185
|
+
should "insert into the bottom of the container specified" do
|
186
|
+
assert_match "Insertion.Bottom('something_comments'", @erbout
|
187
|
+
end
|
188
|
+
|
189
|
+
should "wrap the partial in a prototype template" do
|
190
|
+
assert_match "new Template", @erbout
|
191
|
+
assert_match "evaluate", @erbout
|
192
|
+
end
|
193
|
+
|
194
|
+
should "name the variable correctly" do
|
195
|
+
assert_match "attribute_fu_comment_count", @erbout
|
196
|
+
end
|
197
|
+
|
198
|
+
should "produce the following link" do
|
199
|
+
# this is a way of testing the whole link
|
200
|
+
assert_equal %{
|
201
|
+
<a href=\"#\" onclick=\"if (typeof attribute_fu_comment_count == 'undefined') attribute_fu_comment_count = 0;\nnew Insertion.Bottom('something_comments', new Template(null).evaluate({'number': --attribute_fu_comment_count})); return false;\">Add Comment</a>
|
202
|
+
}.strip, @erbout
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "add associated link with expression parameter" do
|
207
|
+
setup do
|
208
|
+
comment = @photo.comments.build
|
209
|
+
|
210
|
+
_erbout = ''
|
211
|
+
fields_for(:photo) do |f|
|
212
|
+
f.stubs(:render_associated_form).with(comment, :fields_for => {:javascript => true}, :partial => 'some_other_partial')
|
213
|
+
_erbout.concat f.add_associated_link("Add Comment", comment, :expression => '$(this).up(".something_comments")', :partial => 'some_other_partial')
|
214
|
+
end
|
215
|
+
|
216
|
+
@erbout = _erbout
|
217
|
+
end
|
218
|
+
|
219
|
+
should "create link" do
|
220
|
+
assert_match ">Add Comment</a>", @erbout
|
221
|
+
end
|
222
|
+
|
223
|
+
should "use the javascript expression provided instead of passing the ID in" do
|
224
|
+
assert_match "Insertion.Bottom($(this).up(".something_comments")", @erbout
|
225
|
+
end
|
226
|
+
|
227
|
+
should "wrap the partial in a prototype template" do
|
228
|
+
assert_match "new Template", @erbout
|
229
|
+
assert_match "evaluate", @erbout
|
230
|
+
end
|
231
|
+
|
232
|
+
should "name the variable correctly" do
|
233
|
+
assert_match "attribute_fu_comment_count", @erbout
|
234
|
+
end
|
235
|
+
|
236
|
+
should "produce the following link" do
|
237
|
+
# this is a way of testing the whole link
|
238
|
+
assert_equal %{
|
239
|
+
<a href=\"#\" onclick=\"if (typeof attribute_fu_comment_count == 'undefined') attribute_fu_comment_count = 0;\nnew Insertion.Bottom($(this).up(".something_comments"), new Template(null).evaluate({'number': --attribute_fu_comment_count})); return false;\">Add Comment</a>
|
240
|
+
}.strip, @erbout
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "render_associated_form" do
|
245
|
+
setup do
|
246
|
+
comment = @photo.comments.build
|
247
|
+
|
248
|
+
associated_form_builder = mock()
|
249
|
+
|
250
|
+
_erbout = ''
|
251
|
+
fields_for(:photo) do |f|
|
252
|
+
f.stubs(:fields_for_associated).yields(associated_form_builder)
|
253
|
+
expects(:render).with(:partial => "comment", :locals => { :comment => comment, :f => associated_form_builder })
|
254
|
+
_erbout.concat f.render_associated_form(comment).to_s
|
255
|
+
end
|
256
|
+
|
257
|
+
@erbout = _erbout
|
258
|
+
end
|
259
|
+
|
260
|
+
should "extract the correct parameters for render" do
|
261
|
+
# assertions in mock
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context "render_associated_form with specified partial name" do
|
266
|
+
setup do
|
267
|
+
comment = @photo.comments.build
|
268
|
+
|
269
|
+
associated_form_builder = mock()
|
270
|
+
|
271
|
+
_erbout = ''
|
272
|
+
fields_for(:photo) do |f|
|
273
|
+
f.stubs(:fields_for_associated).yields(associated_form_builder)
|
274
|
+
expects(:render).with(:partial => "somewhere/something.html.erb", :locals => { :something => comment, :f => associated_form_builder })
|
275
|
+
_erbout.concat f.render_associated_form(comment, :partial => "somewhere/something.html.erb").to_s
|
276
|
+
end
|
277
|
+
|
278
|
+
@erbout = _erbout
|
279
|
+
end
|
280
|
+
|
281
|
+
should "extract the correct parameters for render" do
|
282
|
+
# assertions in mock
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context "render_associated_form with collection" do
|
287
|
+
setup do
|
288
|
+
associated_form_builder = mock()
|
289
|
+
new_comment = Comment.new
|
290
|
+
@photo.comments.expects(:build).returns(new_comment).times(3)
|
291
|
+
@photo.comments.stubs(:empty?).returns(false)
|
292
|
+
@photo.comments.stubs(:first).returns(new_comment)
|
293
|
+
@photo.comments.stubs(:map).yields(new_comment)
|
294
|
+
|
295
|
+
_erbout = ''
|
296
|
+
fields_for(:photo) do |f|
|
297
|
+
f.stubs(:fields_for_associated).yields(associated_form_builder)
|
298
|
+
expects(:render).with(:partial => "comment", :locals => { :comment => new_comment, :f => associated_form_builder })
|
299
|
+
_erbout.concat f.render_associated_form(@photo.comments, :new => 3).to_s
|
300
|
+
end
|
301
|
+
|
302
|
+
@erbout = _erbout
|
303
|
+
end
|
304
|
+
|
305
|
+
should "extract the correct parameters for render" do
|
306
|
+
# assertions in mock
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context "render_associated_form with collection that already has a couple of new objects in it" do
|
311
|
+
setup do
|
312
|
+
associated_form_builder = mock()
|
313
|
+
2.times { @photo.comments.build }
|
314
|
+
new_comment = Comment.new
|
315
|
+
@photo.comments.expects(:build).returns(new_comment)
|
316
|
+
@photo.comments.stubs(:empty?).returns(false)
|
317
|
+
@photo.comments.stubs(:first).returns(new_comment)
|
318
|
+
@photo.comments.stubs(:map).yields(new_comment)
|
319
|
+
|
320
|
+
_erbout = ''
|
321
|
+
fields_for(:photo) do |f|
|
322
|
+
f.stubs(:fields_for_associated).yields(associated_form_builder)
|
323
|
+
expects(:render).with(:partial => "comment", :locals => { :comment => new_comment, :f => associated_form_builder })
|
324
|
+
_erbout.concat f.render_associated_form(@photo.comments, :new => 3).to_s
|
325
|
+
end
|
326
|
+
|
327
|
+
@erbout = _erbout
|
328
|
+
end
|
329
|
+
|
330
|
+
should "extract the correct parameters for render" do
|
331
|
+
# assertions in mock
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context "render_associated_form with overridden name" do
|
336
|
+
setup do
|
337
|
+
associated_form_builder = mock()
|
338
|
+
comment = @photo.comments.build
|
339
|
+
|
340
|
+
_erbout = ''
|
341
|
+
fields_for(:photo) do |f|
|
342
|
+
f.stubs(:fields_for_associated).with(comment, :name => 'something_else').yields(associated_form_builder)
|
343
|
+
expects(:render).with(:partial => "something_else", :locals => { :something_else => comment, :f => associated_form_builder })
|
344
|
+
_erbout.concat f.render_associated_form(@photo.comments, :name => :something_else).to_s
|
345
|
+
end
|
346
|
+
|
347
|
+
@erbout = _erbout
|
348
|
+
end
|
349
|
+
|
350
|
+
should "render with correct parameters" do
|
351
|
+
# assertions in mock
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
private
|
356
|
+
def assoc_output(comment, &block)
|
357
|
+
_erbout = ''
|
358
|
+
fields_for(:photo) do |f|
|
359
|
+
_erbout.concat(f.fields_for_associated(comment) do |comment|
|
360
|
+
comment.text_field(:author)
|
361
|
+
end)
|
362
|
+
|
363
|
+
_erbout.concat yield(f) if block_given?
|
364
|
+
end
|
365
|
+
|
366
|
+
_erbout
|
367
|
+
end
|
368
|
+
|
369
|
+
def remove_link(*args)
|
370
|
+
@erbout = assoc_output(@photo.comments.build) do |f|
|
371
|
+
f.fields_for_associated(@photo.comments.build) do |comment|
|
372
|
+
comment.remove_link *args
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|