cocoon 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.2
1
+ 1.2.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cocoon"
8
- s.version = "1.1.2"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nathan Van der Auwera"]
12
- s.date = "2013-01-21"
12
+ s.date = "2013-07-10"
13
13
  s.description = "Unobtrusive nested forms handling, using jQuery. Use this and discover cocoon-heaven."
14
14
  s.email = "nathan@dixis.com"
15
15
  s.extra_rdoc_files = [
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.files = [
19
19
  ".travis.yml",
20
20
  "Gemfile",
21
+ "Gemfile.lock",
21
22
  "History.md",
22
23
  "MIT-LICENSE",
23
24
  "README.markdown",
@@ -25,6 +26,8 @@ Gem::Specification.new do |s|
25
26
  "VERSION",
26
27
  "app/assets/javascripts/cocoon.js",
27
28
  "cocoon.gemspec",
29
+ "gemfiles/Gemfile.rails-3.2.13",
30
+ "gemfiles/Gemfile.rails-3.2.13.lock",
28
31
  "lib/cocoon.rb",
29
32
  "lib/cocoon/view_helpers.rb",
30
33
  "lib/generators/cocoon/install/install_generator.rb",
@@ -48,6 +51,7 @@ Gem::Specification.new do |s|
48
51
  "spec/dummy/config/initializers/backtrace_silencers.rb",
49
52
  "spec/dummy/config/initializers/inflections.rb",
50
53
  "spec/dummy/config/initializers/mime_types.rb",
54
+ "spec/dummy/config/initializers/rails_version_helper.rb",
51
55
  "spec/dummy/config/initializers/secret_token.rb",
52
56
  "spec/dummy/config/initializers/session_store.rb",
53
57
  "spec/dummy/config/locales/en.yml",
@@ -70,48 +74,53 @@ Gem::Specification.new do |s|
70
74
  "spec/dummy/script/rails",
71
75
  "spec/generators/install_generator_spec.rb",
72
76
  "spec/integration/navigation_spec.rb",
73
- "spec/spec_helper.rb"
77
+ "spec/spec_helper.rb",
78
+ "spec/support/rails_version_helper.rb",
79
+ "spec/support/shared_examples.rb"
74
80
  ]
75
81
  s.homepage = "http://github.com/nathanvda/cocoon"
76
82
  s.require_paths = ["lib"]
77
- s.rubygems_version = "1.8.24"
83
+ s.rubygems_version = "1.8.25"
78
84
  s.summary = "gem that enables easier nested forms with standard forms, formtastic and simple-form"
79
85
 
80
86
  if s.respond_to? :specification_version then
81
87
  s.specification_version = 3
82
88
 
83
89
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
84
- s.add_development_dependency(%q<rails>, [">= 3.0.0"])
85
- s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
90
+ s.add_development_dependency(%q<rails>, [">= 4.0.0"])
91
+ s.add_development_dependency(%q<sqlite3>, [">= 0"])
86
92
  s.add_development_dependency(%q<json_pure>, [">= 0"])
87
93
  s.add_development_dependency(%q<jeweler>, [">= 0"])
88
- s.add_development_dependency(%q<rspec-rails>, [">= 2.6.0"])
89
- s.add_development_dependency(%q<rspec>, [">= 2.6.0"])
90
- s.add_development_dependency(%q<actionpack>, [">= 3.0.0"])
94
+ s.add_development_dependency(%q<rspec-rails>, [">= 2.8.0"])
95
+ s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
96
+ s.add_development_dependency(%q<actionpack>, [">= 4.0.0"])
91
97
  s.add_development_dependency(%q<simplecov>, [">= 0"])
98
+ s.add_development_dependency(%q<nokogiri>, [">= 0"])
92
99
  s.add_development_dependency(%q<generator_spec>, [">= 0"])
93
100
  s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
94
101
  else
95
- s.add_dependency(%q<rails>, [">= 3.0.0"])
96
- s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
102
+ s.add_dependency(%q<rails>, [">= 4.0.0"])
103
+ s.add_dependency(%q<sqlite3>, [">= 0"])
97
104
  s.add_dependency(%q<json_pure>, [">= 0"])
98
105
  s.add_dependency(%q<jeweler>, [">= 0"])
99
- s.add_dependency(%q<rspec-rails>, [">= 2.6.0"])
100
- s.add_dependency(%q<rspec>, [">= 2.6.0"])
101
- s.add_dependency(%q<actionpack>, [">= 3.0.0"])
106
+ s.add_dependency(%q<rspec-rails>, [">= 2.8.0"])
107
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
108
+ s.add_dependency(%q<actionpack>, [">= 4.0.0"])
102
109
  s.add_dependency(%q<simplecov>, [">= 0"])
110
+ s.add_dependency(%q<nokogiri>, [">= 0"])
103
111
  s.add_dependency(%q<generator_spec>, [">= 0"])
104
112
  s.add_dependency(%q<rspec>, [">= 2.0.0"])
105
113
  end
106
114
  else
107
- s.add_dependency(%q<rails>, [">= 3.0.0"])
108
- s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
115
+ s.add_dependency(%q<rails>, [">= 4.0.0"])
116
+ s.add_dependency(%q<sqlite3>, [">= 0"])
109
117
  s.add_dependency(%q<json_pure>, [">= 0"])
110
118
  s.add_dependency(%q<jeweler>, [">= 0"])
111
- s.add_dependency(%q<rspec-rails>, [">= 2.6.0"])
112
- s.add_dependency(%q<rspec>, [">= 2.6.0"])
113
- s.add_dependency(%q<actionpack>, [">= 3.0.0"])
119
+ s.add_dependency(%q<rspec-rails>, [">= 2.8.0"])
120
+ s.add_dependency(%q<rspec>, [">= 2.8.0"])
121
+ s.add_dependency(%q<actionpack>, [">= 4.0.0"])
114
122
  s.add_dependency(%q<simplecov>, [">= 0"])
123
+ s.add_dependency(%q<nokogiri>, [">= 0"])
115
124
  s.add_dependency(%q<generator_spec>, [">= 0"])
116
125
  s.add_dependency(%q<rspec>, [">= 2.0.0"])
117
126
  end
@@ -0,0 +1,21 @@
1
+ source "http://rubygems.org"
2
+
3
+
4
+ group :development, :test do
5
+ gem "rails", "~> 3.2.0"
6
+ gem "sqlite3"
7
+ gem "json_pure"
8
+ gem "jeweler"
9
+ gem "rspec-rails", ">= 2.8.0"
10
+ gem "rspec", ">= 2.8.0"
11
+ gem "actionpack", "~> 3.2.0"
12
+ gem "simplecov", :require => false
13
+
14
+ gem 'nokogiri'
15
+
16
+ gem "generator_spec"
17
+ end
18
+
19
+ # To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
20
+ # gem 'ruby-debug'
21
+ # gem 'ruby-debug19'
@@ -0,0 +1,154 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ actionmailer (3.2.13)
5
+ actionpack (= 3.2.13)
6
+ mail (~> 2.5.3)
7
+ actionpack (3.2.13)
8
+ activemodel (= 3.2.13)
9
+ activesupport (= 3.2.13)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ journey (~> 1.0.4)
13
+ rack (~> 1.4.5)
14
+ rack-cache (~> 1.2)
15
+ rack-test (~> 0.6.1)
16
+ sprockets (~> 2.2.1)
17
+ activemodel (3.2.13)
18
+ activesupport (= 3.2.13)
19
+ builder (~> 3.0.0)
20
+ activerecord (3.2.13)
21
+ activemodel (= 3.2.13)
22
+ activesupport (= 3.2.13)
23
+ arel (~> 3.0.2)
24
+ tzinfo (~> 0.3.29)
25
+ activeresource (3.2.13)
26
+ activemodel (= 3.2.13)
27
+ activesupport (= 3.2.13)
28
+ activesupport (3.2.13)
29
+ i18n (= 0.6.1)
30
+ multi_json (~> 1.0)
31
+ addressable (2.3.5)
32
+ arel (3.0.2)
33
+ builder (3.0.4)
34
+ diff-lcs (1.2.4)
35
+ erubis (2.7.0)
36
+ faraday (0.8.7)
37
+ multipart-post (~> 1.1)
38
+ generator_spec (0.9.0)
39
+ activerecord (>= 3.0, <= 4.0)
40
+ railties (>= 3.0, <= 4.0)
41
+ git (1.2.5)
42
+ github_api (0.10.1)
43
+ addressable
44
+ faraday (~> 0.8.1)
45
+ hashie (>= 1.2)
46
+ multi_json (~> 1.4)
47
+ nokogiri (~> 1.5.2)
48
+ oauth2
49
+ hashie (2.0.5)
50
+ highline (1.6.19)
51
+ hike (1.2.3)
52
+ httpauth (0.2.0)
53
+ i18n (0.6.1)
54
+ jeweler (1.8.6)
55
+ builder
56
+ bundler (~> 1.0)
57
+ git (>= 1.2.5)
58
+ github_api (= 0.10.1)
59
+ highline (>= 1.6.15)
60
+ nokogiri (= 1.5.10)
61
+ rake
62
+ rdoc
63
+ journey (1.0.4)
64
+ json (1.8.0)
65
+ json_pure (1.8.0)
66
+ jwt (0.1.8)
67
+ multi_json (>= 1.5)
68
+ mail (2.5.4)
69
+ mime-types (~> 1.16)
70
+ treetop (~> 1.4.8)
71
+ mime-types (1.23)
72
+ multi_json (1.7.7)
73
+ multi_xml (0.5.4)
74
+ multipart-post (1.2.0)
75
+ nokogiri (1.5.10)
76
+ oauth2 (0.9.2)
77
+ faraday (~> 0.8)
78
+ httpauth (~> 0.2)
79
+ jwt (~> 0.1.4)
80
+ multi_json (~> 1.0)
81
+ multi_xml (~> 0.5)
82
+ rack (~> 1.2)
83
+ polyglot (0.3.3)
84
+ rack (1.4.5)
85
+ rack-cache (1.2)
86
+ rack (>= 0.4)
87
+ rack-ssl (1.3.3)
88
+ rack
89
+ rack-test (0.6.2)
90
+ rack (>= 1.0)
91
+ rails (3.2.13)
92
+ actionmailer (= 3.2.13)
93
+ actionpack (= 3.2.13)
94
+ activerecord (= 3.2.13)
95
+ activeresource (= 3.2.13)
96
+ activesupport (= 3.2.13)
97
+ bundler (~> 1.0)
98
+ railties (= 3.2.13)
99
+ railties (3.2.13)
100
+ actionpack (= 3.2.13)
101
+ activesupport (= 3.2.13)
102
+ rack-ssl (~> 1.3.2)
103
+ rake (>= 0.8.7)
104
+ rdoc (~> 3.4)
105
+ thor (>= 0.14.6, < 2.0)
106
+ rake (10.1.0)
107
+ rdoc (3.12.2)
108
+ json (~> 1.4)
109
+ rspec (2.14.0)
110
+ rspec-core (~> 2.14.0)
111
+ rspec-expectations (~> 2.14.0)
112
+ rspec-mocks (~> 2.14.0)
113
+ rspec-core (2.14.2)
114
+ rspec-expectations (2.14.0)
115
+ diff-lcs (>= 1.1.3, < 2.0)
116
+ rspec-mocks (2.14.1)
117
+ rspec-rails (2.14.0)
118
+ actionpack (>= 3.0)
119
+ activesupport (>= 3.0)
120
+ railties (>= 3.0)
121
+ rspec-core (~> 2.14.0)
122
+ rspec-expectations (~> 2.14.0)
123
+ rspec-mocks (~> 2.14.0)
124
+ simplecov (0.7.1)
125
+ multi_json (~> 1.0)
126
+ simplecov-html (~> 0.7.1)
127
+ simplecov-html (0.7.1)
128
+ sprockets (2.2.2)
129
+ hike (~> 1.2)
130
+ multi_json (~> 1.0)
131
+ rack (~> 1.0)
132
+ tilt (~> 1.1, != 1.3.0)
133
+ sqlite3 (1.3.7)
134
+ thor (0.18.1)
135
+ tilt (1.4.1)
136
+ treetop (1.4.14)
137
+ polyglot
138
+ polyglot (>= 0.3.1)
139
+ tzinfo (0.3.37)
140
+
141
+ PLATFORMS
142
+ ruby
143
+
144
+ DEPENDENCIES
145
+ actionpack (~> 3.2.0)
146
+ generator_spec
147
+ jeweler
148
+ json_pure
149
+ nokogiri
150
+ rails (~> 3.2.0)
151
+ rspec (>= 2.8.0)
152
+ rspec-rails (>= 2.8.0)
153
+ simplecov
154
+ sqlite3
@@ -4,7 +4,9 @@ module Cocoon
4
4
  class Engine < ::Rails::Engine
5
5
 
6
6
  config.before_initialize do
7
- config.action_view.javascript_expansions[:cocoon] = %w(cocoon)
7
+ if config.action_view.javascript_expansions
8
+ config.action_view.javascript_expansions[:cocoon] = %w(cocoon)
9
+ end
8
10
  end
9
11
 
10
12
  # configure our plugin on boot
@@ -121,6 +121,10 @@ module Cocoon
121
121
  end
122
122
 
123
123
  def create_object_with_conditions(instance)
124
+ # in rails 4, an association is defined with a proc
125
+ # and I did not find how to extract the conditions from a scope
126
+ # except building from the scope, but then why not just build from the
127
+ # association???
124
128
  conditions = instance.respond_to?(:conditions) ? instance.conditions.flatten : []
125
129
  instance.klass.new(*conditions)
126
130
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'nokogiri'
2
3
 
3
4
  describe Cocoon do
4
5
  class TestClass < ActionView::Base
@@ -13,7 +14,7 @@ describe Cocoon do
13
14
  before(:each) do
14
15
  @tester = TestClass.new
15
16
  @post = Post.new
16
- @form_obj = stub(:object => @post, :object_name => @post.class.name)
17
+ @form_obj = double(:object => @post, :object_name => @post.class.name)
17
18
  end
18
19
 
19
20
 
@@ -23,21 +24,31 @@ describe Cocoon do
23
24
  end
24
25
 
25
26
  context "without a block" do
26
- it "accepts a name" do
27
- result = @tester.link_to_add_association('add something', @form_obj, :comments)
28
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="comment" data-associations="comments">add something</a>'
27
+
28
+ context "and given a name" do
29
+ before do
30
+ @html = @tester.link_to_add_association('add something', @form_obj, :comments)
31
+ end
32
+
33
+ it_behaves_like "a correctly rendered add link", {}
29
34
  end
30
35
 
31
- it "accepts html options and pass them to link_to" do
32
- result = @tester.link_to_add_association('add something', @form_obj, :comments, {:class => 'something silly'})
33
- result.to_s.should == '<a href="#" class="something silly add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="comment" data-associations="comments">add something</a>'
36
+ context "and given html options to pass them to link_to" do
37
+ before do
38
+ @html = @tester.link_to_add_association('add something', @form_obj, :comments, {:class => 'something silly'})
39
+ end
40
+
41
+ it_behaves_like "a correctly rendered add link", {class: 'something silly add_fields' }
34
42
  end
35
43
 
36
- it "allows to explicitly hand the wanted partial" do
37
- @tester.unstub(:render_association)
38
- @tester.should_receive(:render_association).with(anything(), anything(), anything(), anything(), "shared/partial").and_return('partiallll')
39
- result = @tester.link_to_add_association('add something', @form_obj, :comments, :partial => "shared/partial")
40
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="partiallll" data-association="comment" data-associations="comments">add something</a>'
44
+ context "and explicitly specifying the wanted partial" do
45
+ before do
46
+ @tester.unstub(:render_association)
47
+ @tester.should_receive(:render_association).with(anything(), anything(), anything(), anything(), "shared/partial").and_return('partiallll')
48
+ @html = @tester.link_to_add_association('add something', @form_obj, :comments, :partial => "shared/partial")
49
+ end
50
+
51
+ it_behaves_like "a correctly rendered add link", {template: "partiallll"}
41
52
  end
42
53
 
43
54
  it "gives an opportunity to wrap/decorate created objects" do
@@ -47,61 +58,101 @@ describe Cocoon do
47
58
  end
48
59
 
49
60
  context "force non association create" do
50
- it "default it uses the association" do
51
- @tester.should_receive(:create_object).with(anything, :comments , false)
52
- result = @tester.link_to_add_association('add something', @form_obj, :comments)
53
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="comment" data-associations="comments">add something</a>'
54
- end
55
- it "specifying false is the same as default: create object on association" do
56
- @tester.should_receive(:create_object).with(anything, :comments , false)
57
- result = @tester.link_to_add_association('add something', @form_obj, :comments, :force_non_association_create => false)
58
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="comment" data-associations="comments">add something</a>'
61
+ context "default case: create object on association" do
62
+ before do
63
+ @tester.should_receive(:create_object).with(anything, :comments , false)
64
+ @html = @tester.link_to_add_association('add something', @form_obj, :comments)
65
+ end
66
+
67
+ it_behaves_like "a correctly rendered add link", {}
59
68
  end
60
- it "specifying true will not create objects on association but using the conditions" do
61
- @tester.should_receive(:create_object).with(anything, :comments , true)
62
- result = @tester.link_to_add_association('add something', @form_obj, :comments, :force_non_association_create => true)
63
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="comment" data-associations="comments">add something</a>'
69
+
70
+ context "and explicitly specifying false is the same as default" do
71
+ before do
72
+ @tester.should_receive(:create_object).with(anything, :comments , false)
73
+ @html = @tester.link_to_add_association('add something', @form_obj, :comments, :force_non_association_create => false)
74
+ end
75
+ it_behaves_like "a correctly rendered add link", {}
64
76
  end
65
77
 
78
+ context "specifying true will not create objects on association but using the conditions" do
79
+ before do
80
+ @tester.should_receive(:create_object).with(anything, :comments , true)
81
+ @html = @tester.link_to_add_association('add something', @form_obj, :comments, :force_non_association_create => true)
82
+ end
83
+ it_behaves_like "a correctly rendered add link", {}
84
+ end
66
85
  end
67
86
  end
68
87
 
69
88
  context "with a block" do
70
- it "the block gives the link text" do
71
- result = @tester.link_to_add_association(@form_obj, :comments) do
72
- "some long name"
89
+ context "and the block specifies the link text" do
90
+ before do
91
+ @html = @tester.link_to_add_association(@form_obj, :comments) do
92
+ "some long name"
93
+ end
73
94
  end
74
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="comment" data-associations="comments">some long name</a>'
95
+ it_behaves_like "a correctly rendered add link", {text: 'some long name'}
75
96
  end
76
97
 
77
- it "accepts html options and pass them to link_to" do
78
- result = @tester.link_to_add_association(@form_obj, :comments, {:class => 'floppy disk'}) do
79
- "some long name"
98
+ context "accepts html options and pass them to link_to" do
99
+ before do
100
+ @html = @tester.link_to_add_association(@form_obj, :comments, {:class => 'floppy disk'}) do
101
+ "some long name"
102
+ end
80
103
  end
81
- result.to_s.should == '<a href="#" class="floppy disk add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="comment" data-associations="comments">some long name</a>'
104
+ it_behaves_like "a correctly rendered add link", {class: 'floppy disk add_fields', text: 'some long name'}
82
105
  end
83
106
 
84
- it "allows to explicitly hand the wanted partial" do
85
- @tester.unstub(:render_association)
86
- @tester.should_receive(:render_association).with(anything(), anything(), anything(), anything(), "shared/partial").and_return('partiallll')
87
- result = @tester.link_to_add_association( @form_obj, :comments, :class => 'floppy disk', :partial => "shared/partial") do
88
- "some long name"
107
+ context "accepts extra attributes and pass them to link_to" do
108
+ context 'when using the old notation' do
109
+ before do
110
+ @html = @tester.link_to_add_association(@form_obj, :comments, {:class => 'floppy disk', 'data-something' => 'bla'}) do
111
+ "some long name"
112
+ end
113
+ end
114
+ it_behaves_like "a correctly rendered add link", {class: 'floppy disk add_fields', text: 'some long name', :extra_attributes => {'data-something' => 'bla'}}
115
+ end
116
+ if Rails.rails4?
117
+ context 'when using the new notation' do
118
+ before do
119
+ @html = @tester.link_to_add_association(@form_obj, :comments, {:class => 'floppy disk', :data => {:'association-something' => 'foobar'}}) do
120
+ "some long name"
121
+ end
122
+ end
123
+ it_behaves_like "a correctly rendered add link", {class: 'floppy disk add_fields', text: 'some long name', :extra_attributes => {'data-association-something' => 'foobar'}}
124
+ end
89
125
  end
90
- result.to_s.should == '<a href="#" class="floppy disk add_fields" data-association-insertion-template="partiallll" data-association="comment" data-associations="comments">some long name</a>'
126
+ end
127
+
128
+ context "and explicitly specifying the wanted partial" do
129
+ before do
130
+ @tester.unstub(:render_association)
131
+ @tester.should_receive(:render_association).with(anything(), anything(), anything(), anything(), "shared/partial").and_return('partiallll')
132
+ @html = @tester.link_to_add_association( @form_obj, :comments, :class => 'floppy disk', :partial => "shared/partial") do
133
+ "some long name"
134
+ end
135
+ end
136
+
137
+ it_behaves_like "a correctly rendered add link", {class: 'floppy disk add_fields', template: "partiallll", text: 'some long name'}
91
138
  end
92
139
  end
93
140
 
94
141
  context "with an irregular plural" do
95
- it "uses the correct plural" do
96
- result = @tester.link_to_add_association('add something', @form_obj, :people)
97
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="person" data-associations="people">add something</a>'
142
+ context "uses the correct plural" do
143
+ before do
144
+ @html = @tester.link_to_add_association('add something', @form_obj, :people)
145
+ end
146
+ it_behaves_like "a correctly rendered add link", {association: 'person', associations: 'people' }
98
147
  end
99
148
  end
100
149
 
101
150
  context "when using aliased association and class-name" do
102
- it "uses the correct name" do
103
- result = @tester.link_to_add_association('add something', @form_obj, :admin_comments)
104
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="admin_comment" data-associations="admin_comments">add something</a>'
151
+ context "uses the correct name" do
152
+ before do
153
+ @html = @tester.link_to_add_association('add something', @form_obj, :admin_comments)
154
+ end
155
+ it_behaves_like "a correctly rendered add link", {association: 'admin_comment', associations: 'admin_comments'}
105
156
  end
106
157
  end
107
158
 
@@ -110,27 +161,35 @@ describe Cocoon do
110
161
  end
111
162
 
112
163
  context "with extra render-options for rendering the child relation" do
113
- it "uses the correct plural" do
114
- @tester.should_receive(:render_association).with(:people, @form_obj, anything, {:wrapper => 'inline'}, nil)
115
- result = @tester.link_to_add_association('add something', @form_obj, :people, :render_options => {:wrapper => 'inline'})
116
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tag&gt;" data-association="person" data-associations="people">add something</a>'
164
+ context "uses the correct plural" do
165
+ before do
166
+ @tester.should_receive(:render_association).with(:people, @form_obj, anything, {:wrapper => 'inline'}, nil)
167
+ @html = @tester.link_to_add_association('add something', @form_obj, :people, :render_options => {:wrapper => 'inline'})
168
+ end
169
+ it_behaves_like "a correctly rendered add link", {association: 'person', associations: 'people' }
117
170
  end
118
171
  end
119
172
 
120
173
  context "passing locals to the partial" do
121
- it "when given: passes the locals to the partials" do
122
- @tester.unstub(:render_association)
123
- @form_obj.should_receive(:fields_for) { | association, new_object, options_hash, &block| block.call }
124
- @tester.should_receive(:render).with("person_fields", {:f=>nil, :dynamic=>true, :alfred=>"Judoka"}).and_return ("partiallll")
125
- result = @tester.link_to_add_association('add something', @form_obj, :people, :render_options => {:wrapper => 'inline', :locals => {:alfred => 'Judoka'}})
126
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="partiallll" data-association="person" data-associations="people">add something</a>'
174
+ context "when given: passes the locals to the partials" do
175
+ before do
176
+ @tester.unstub(:render_association)
177
+ @form_obj.should_receive(:fields_for) { | association, new_object, options_hash, &block| block.call }
178
+ @tester.should_receive(:render).with("person_fields", {:f=>nil, :dynamic=>true, :alfred=>"Judoka"}).and_return ("partiallll")
179
+ @html = @tester.link_to_add_association('add something', @form_obj, :people, :render_options => {:wrapper => 'inline', :locals => {:alfred => 'Judoka'}})
180
+ end
181
+ it_behaves_like "a correctly rendered add link", {template: 'partiallll', association: 'person', associations: 'people' }
127
182
  end
128
- it "if no locals are given it still works" do
129
- @tester.unstub(:render_association)
130
- @form_obj.should_receive(:fields_for) { | association, new_object, options_hash, &block| block.call }
131
- @tester.should_receive(:render).with("person_fields", {:f=>nil, :dynamic=>true}).and_return ("partiallll")
132
- result = @tester.link_to_add_association('add something', @form_obj, :people, :render_options => {:wrapper => 'inline'})
133
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="partiallll" data-association="person" data-associations="people">add something</a>'
183
+ context "if no locals are given it still works" do
184
+ before do
185
+ @tester.unstub(:render_association)
186
+ @form_obj.should_receive(:fields_for) { | association, new_object, options_hash, &block| block.call }
187
+ @tester.should_receive(:render).with("person_fields", {:f=>nil, :dynamic=>true}).and_return ("partiallll")
188
+ @html = @tester.link_to_add_association('add something', @form_obj, :people, :render_options => {:wrapper => 'inline'})
189
+ end
190
+ it_behaves_like "a correctly rendered add link", {template: 'partiallll', association: 'person', associations: 'people' }
191
+
192
+ #result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="partiallll" data-association="person" data-associations="people">add something</a>'
134
193
  end
135
194
  end
136
195
 
@@ -141,12 +200,13 @@ describe Cocoon do
141
200
  @tester.unstub(:render_association)
142
201
  @form_obj.stub(:semantic_fields_for).and_return('form<tagzzz>')
143
202
  end
144
- it "calls semantic_fields_for and not fields_for" do
145
- @form_obj.should_receive(:semantic_fields_for)
146
- @form_obj.should_receive(:fields_for).never
147
- result = @tester.link_to_add_association('add something', @form_obj, :people)
148
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tagzzz&gt;" data-association="person" data-associations="people">add something</a>'
149
-
203
+ context "calls semantic_fields_for and not fields_for" do
204
+ before do
205
+ @form_obj.should_receive(:semantic_fields_for)
206
+ @form_obj.should_receive(:fields_for).never
207
+ @html = @tester.link_to_add_association('add something', @form_obj, :people)
208
+ end
209
+ it_behaves_like "a correctly rendered add link", {template: 'form<tagzzz>', association: 'person', associations: 'people' }
150
210
  end
151
211
  end
152
212
  context "when using simple_form" do
@@ -157,12 +217,13 @@ describe Cocoon do
157
217
  it "responds_to :simple_fields_for" do
158
218
  @form_obj.should respond_to(:simple_fields_for)
159
219
  end
160
- it "calls simple_fields_for and not fields_for" do
161
- @form_obj.should_receive(:simple_fields_for)
162
- @form_obj.should_receive(:fields_for).never
163
- result = @tester.link_to_add_association('add something', @form_obj, :people)
164
- result.to_s.should == '<a href="#" class="add_fields" data-association-insertion-template="form&lt;tagxxx&gt;" data-association="person" data-associations="people">add something</a>'
165
-
220
+ context "calls simple_fields_for and not fields_for" do
221
+ before do
222
+ @form_obj.should_receive(:simple_fields_for)
223
+ @form_obj.should_receive(:fields_for).never
224
+ @html = @tester.link_to_add_association('add something', @form_obj, :people)
225
+ end
226
+ it_behaves_like "a correctly rendered add link", {template: 'form<tagxxx>', association: 'person', associations: 'people' }
166
227
  end
167
228
  end
168
229
 
@@ -170,31 +231,47 @@ describe Cocoon do
170
231
 
171
232
  context "link_to_remove_association" do
172
233
  context "without a block" do
173
- it "accepts a name" do
174
- result = @tester.link_to_remove_association('remove something', @form_obj)
175
- result.to_s.should == "<input id=\"Post__destroy\" name=\"Post[_destroy]\" type=\"hidden\" /><a href=\"#\" class=\"remove_fields dynamic\">remove something</a>"
234
+ context "accepts a name" do
235
+ before do
236
+ @html = @tester.link_to_remove_association('remove something', @form_obj)
237
+ end
238
+
239
+ it "is rendered inside a input element" do
240
+ doc = Nokogiri::HTML(@html)
241
+ removed = doc.at('input')
242
+ removed.attribute('id').value.should == "Post__destroy"
243
+ removed.attribute('name').value.should == "Post[_destroy]"
244
+ end
245
+
246
+ it_behaves_like "a correctly rendered remove link", {}
176
247
  end
177
248
 
178
- it "accepts html options and pass them to link_to" do
179
- result = @tester.link_to_remove_association('remove something', @form_obj, {:class => 'add_some_class', :'data-something' => 'bla'})
180
- result.to_s.should == "<input id=\"Post__destroy\" name=\"Post[_destroy]\" type=\"hidden\" /><a href=\"#\" class=\"add_some_class remove_fields dynamic\" data-something=\"bla\">remove something</a>"
249
+ context "accepts html options and pass them to link_to" do
250
+ before do
251
+ @html = @tester.link_to_remove_association('remove something', @form_obj, {:class => 'add_some_class', :'data-something' => 'bla'})
252
+ end
253
+ it_behaves_like "a correctly rendered remove link", {class: 'add_some_class remove_fields dynamic', extra_attributes: {'data-something' => 'bla'}}
181
254
  end
182
255
 
183
256
  end
184
257
 
185
258
  context "with a block" do
186
- it "the block gives the name" do
187
- result = @tester.link_to_remove_association(@form_obj) do
188
- "remove some long name"
259
+ context "the block gives the name" do
260
+ before do
261
+ @html = @tester.link_to_remove_association(@form_obj) do
262
+ "remove some long name"
263
+ end
189
264
  end
190
- result.to_s.should == "<input id=\"Post__destroy\" name=\"Post[_destroy]\" type=\"hidden\" /><a href=\"#\" class=\"remove_fields dynamic\">remove some long name</a>"
265
+ it_behaves_like "a correctly rendered remove link", {text: 'remove some long name'}
191
266
  end
192
267
 
193
- it "accepts html options and pass them to link_to" do
194
- result = @tester.link_to_remove_association(@form_obj, {:class => 'add_some_class', :'data-something' => 'bla'}) do
195
- "remove some long name"
268
+ context "accepts html options and pass them to link_to" do
269
+ before do
270
+ @html = @tester.link_to_remove_association(@form_obj, {:class => 'add_some_class', :'data-something' => 'bla'}) do
271
+ "remove some long name"
272
+ end
196
273
  end
197
- result.to_s.should == "<input id=\"Post__destroy\" name=\"Post[_destroy]\" type=\"hidden\" /><a href=\"#\" class=\"add_some_class remove_fields dynamic\" data-something=\"bla\">remove some long name</a>"
274
+ it_behaves_like "a correctly rendered remove link", {text: 'remove some long name', class: 'add_some_class remove_fields dynamic', extra_attributes: {'data-something' => 'bla'}}
198
275
  end
199
276
  end
200
277
  end
@@ -202,29 +279,35 @@ describe Cocoon do
202
279
  context "create_object" do
203
280
  it "creates correct association with conditions" do
204
281
  @tester.should_not_receive(:create_object_with_conditions)
282
+ # in rails4 we cannot create an associated object when the object has not been saved before
283
+ # I submitted a bug for this: https://github.com/rails/rails/issues/11376
284
+ if Rails.rails4?
285
+ @post = Post.create(title: 'Testing')
286
+ @form_obj = double(:object => @post, :object_name => @post.class.name)
287
+ end
205
288
  result = @tester.create_object(@form_obj, :admin_comments)
206
289
  result.author.should == "Admin"
207
290
  end
208
291
 
209
292
  it "creates correct association for belongs_to associations" do
210
- result = @tester.create_object(stub(:object => Comment.new), :post)
293
+ result = @tester.create_object(double(:object => Comment.new), :post)
211
294
  result.should be_a Post
212
295
  end
213
296
 
214
297
  it "raises an error if cannot reflect on association" do
215
- expect { @tester.create_object(stub(:object => Comment.new), :not_existing) }.to raise_error /association/i
298
+ expect { @tester.create_object(double(:object => Comment.new), :not_existing) }.to raise_error /association/i
216
299
  end
217
300
 
218
301
  it "creates an association if object responds to 'build_association' as singular" do
219
302
  object = Comment.new
220
303
  object.should_receive(:build_custom_item).and_return 'custom'
221
- @tester.create_object(stub(:object => object), :custom_item).should == 'custom'
304
+ @tester.create_object(double(:object => object), :custom_item).should == 'custom'
222
305
  end
223
306
 
224
307
  it "creates an association if object responds to 'build_association' as plural" do
225
308
  object = Comment.new
226
309
  object.should_receive(:build_custom_item).and_return 'custom'
227
- @tester.create_object(stub(:object => object), :custom_items).should == 'custom'
310
+ @tester.create_object(double(:object => object), :custom_items).should == 'custom'
228
311
  end
229
312
 
230
313
  it "can create using only conditions not the association" do