snusnu-dm-accepts_nested_attributes 0.0.1

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.
@@ -0,0 +1,181 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
+
4
+ describe DataMapper::NestedAttributes do
5
+
6
+ describe "every accessible has(n) association with a valid reject_if proc", :shared => true do
7
+
8
+ it "should not allow to create a new task via Project#tasks_attributes" do
9
+ @project.save
10
+ Project.all.size.should == 1
11
+ Task.all.size.should == 0
12
+
13
+ @project.tasks_attributes = { 'new_1' => { :name => 'write specs' } }
14
+ @project.tasks.should be_empty
15
+ @project.save
16
+ Project.all.size.should == 1
17
+ Task.all.size.should == 0
18
+ end
19
+
20
+ end
21
+
22
+ describe "every accessible has(n) association with no reject_if proc", :shared => true do
23
+
24
+ it "should allow to create a new task via Project#tasks_attributes" do
25
+ @project.save
26
+ Project.all.size.should == 1
27
+ Task.all.size.should == 0
28
+
29
+ @project.tasks_attributes = { 'new_1' => { :name => 'write specs' } }
30
+ @project.tasks.should_not be_empty
31
+ @project.tasks.first.name.should == 'write specs'
32
+ @project.save
33
+ @project.tasks.first.should == Task.first
34
+ Project.all.size.should == 1
35
+ Task.all.size.should == 1
36
+ Task.first.name.should == 'write specs'
37
+ end
38
+
39
+ it "should allow to update an existing task via Project#tasks_attributes" do
40
+ @project.save
41
+ task = Task.create(:project => @project, :name => 'write specs')
42
+ Project.all.size.should == 1
43
+ Task.all.size.should == 1
44
+
45
+ @project.tasks_attributes = { task.id.to_s => { :id => task.id, :name => 'write more specs' } }
46
+ @project.tasks.should_not be_empty
47
+ @project.tasks.first.name.should == 'write more specs'
48
+ @project.save
49
+
50
+ Project.all.size.should == 1
51
+ Task.all.size.should == 1
52
+ Task.first.name.should == 'write more specs'
53
+ end
54
+
55
+ end
56
+
57
+ describe "every accessible has(n) association with :allow_destroy => false", :shared => true do
58
+
59
+ it "should not allow to delete an existing task via Profile#tasks_attributes" do
60
+ @project.save
61
+ task = Task.create(:project => @project, :name => 'write specs')
62
+
63
+ Project.all.size.should == 1
64
+ Task.all.size.should == 1
65
+
66
+ @project.reload
67
+ @project.tasks_attributes = { '1' => { :id => task.id, :_delete => true } }
68
+ @project.save
69
+
70
+ Project.all.size.should == 1
71
+ Task.all.size.should == 1
72
+ end
73
+
74
+ end
75
+
76
+ describe "every accessible has(n) association with :allow_destroy => true", :shared => true do
77
+
78
+ it "should allow to delete an existing task via Profile#tasks_attributes" do
79
+ @project.save
80
+ task = Task.create(:project => @project, :name => 'write specs')
81
+
82
+ Project.all.size.should == 1
83
+ Task.all.size.should == 1
84
+
85
+ @project.reload
86
+ @project.tasks_attributes = { '1' => { :id => task.id, :_delete => true } }
87
+ @project.save
88
+
89
+ Project.all.size.should == 1
90
+ Task.all.size.should == 0
91
+ end
92
+
93
+ end
94
+
95
+ describe "Project.has(n, :tasks)" do
96
+
97
+ describe "accepts_nested_attributes_for(:tasks)" do
98
+
99
+ before(:each) do
100
+ DataMapper.auto_migrate!
101
+ Project.accepts_nested_attributes_for :tasks
102
+ @project = Project.new :name => 'trippings'
103
+ end
104
+
105
+ it_should_behave_like "every accessible has(n) association with no reject_if proc"
106
+ it_should_behave_like "every accessible has(n) association with :allow_destroy => false"
107
+
108
+ end
109
+
110
+ describe "accepts_nested_attributes_for(:tasks, :allow_destroy => false)" do
111
+
112
+ before(:each) do
113
+ DataMapper.auto_migrate!
114
+ Project.accepts_nested_attributes_for :tasks, :allow_destroy => false
115
+ @project = Project.new :name => 'trippings'
116
+ end
117
+
118
+ it_should_behave_like "every accessible has(n) association with no reject_if proc"
119
+ it_should_behave_like "every accessible has(n) association with :allow_destroy => false"
120
+
121
+ end
122
+
123
+ describe "accepts_nested_attributes_for(:tasks, :allow_destroy => true)" do
124
+
125
+ before(:each) do
126
+ DataMapper.auto_migrate!
127
+ Project.accepts_nested_attributes_for :tasks, :allow_destroy => true
128
+ @project = Project.new :name => 'trippings'
129
+ end
130
+
131
+ it_should_behave_like "every accessible has(n) association with no reject_if proc"
132
+ it_should_behave_like "every accessible has(n) association with :allow_destroy => true"
133
+
134
+ end
135
+
136
+ describe "accepts_nested_attributes_for :tasks, " do
137
+
138
+ describe ":reject_if => :foo" do
139
+
140
+ before(:each) do
141
+ DataMapper.auto_migrate!
142
+ Project.accepts_nested_attributes_for :tasks, :reject_if => :foo
143
+ @project = Project.new :name => 'trippings'
144
+ end
145
+
146
+ it_should_behave_like "every accessible has(n) association with no reject_if proc"
147
+ it_should_behave_like "every accessible has(n) association with :allow_destroy => false"
148
+
149
+ end
150
+
151
+ describe ":reject_if => lambda { |attrs| true }" do
152
+
153
+ before(:each) do
154
+ DataMapper.auto_migrate!
155
+ Project.accepts_nested_attributes_for :tasks, :reject_if => lambda { |attrs| true }
156
+ @project = Project.new :name => 'trippings'
157
+ end
158
+
159
+ it_should_behave_like "every accessible has(n) association with a valid reject_if proc"
160
+ it_should_behave_like "every accessible has(n) association with :allow_destroy => false"
161
+
162
+ end
163
+
164
+ describe ":reject_if => lambda { |attrs| false }" do
165
+
166
+ before(:each) do
167
+ DataMapper.auto_migrate!
168
+ Project.accepts_nested_attributes_for :tasks, :reject_if => lambda { |attrs| false }
169
+ @project = Project.new :name => 'trippings'
170
+ end
171
+
172
+ it_should_behave_like "every accessible has(n) association with no reject_if proc"
173
+ it_should_behave_like "every accessible has(n) association with :allow_destroy => false"
174
+
175
+ end
176
+
177
+ end
178
+
179
+ end
180
+
181
+ end
@@ -0,0 +1,200 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
+
4
+ describe DataMapper::NestedAttributes do
5
+
6
+ describe "every accessible has(n, :through) association with a valid reject_if proc", :shared => true do
7
+
8
+ it "should not allow to create a new project via Person#projects_attributes" do
9
+ @person.save
10
+ Person.all.size.should == 1
11
+ ProjectMembership.all.size.should == 0
12
+ Project.all.size.should == 0
13
+
14
+ @person.projects_attributes = { 'new_1' => { :name => 'dm-accepts_nested_attributes' } }
15
+ @person.projects.should be_empty
16
+ @person.save
17
+
18
+ Person.all.size.should == 1
19
+ ProjectMembership.all.size.should == 0
20
+ Project.all.size.should == 0
21
+ end
22
+
23
+ end
24
+
25
+ describe "every accessible has(n, :through) association with no reject_if proc", :shared => true do
26
+
27
+ it "should allow to create a new project via Person#projects_attributes" do
28
+ @person.save
29
+ Person.all.size.should == 1
30
+ ProjectMembership.all.size.should == 0
31
+ Project.all.size.should == 0
32
+
33
+ @person.projects_attributes = { 'new_1' => { :name => 'dm-accepts_nested_attributes' } }
34
+ @person.projects.should_not be_empty
35
+ @person.projects.first.name.should == 'dm-accepts_nested_attributes'
36
+ @person.save
37
+ @person.projects.first.should == Project.first
38
+
39
+ Person.all.size.should == 1
40
+ ProjectMembership.all.size.should == 1
41
+ Project.all.size.should == 1
42
+
43
+ Project.first.name.should == 'dm-accepts_nested_attributes'
44
+ end
45
+
46
+ it "should allow to update an existing project via Person#projects_attributes" do
47
+ @person.save
48
+ project = Project.create(:name => 'dm-accepts_nested_attributes')
49
+ project_membership = ProjectMembership.create(:person => @person, :project => project)
50
+ Person.all.size.should == 1
51
+ Project.all.size.should == 1
52
+ ProjectMembership.all.size.should == 1
53
+
54
+ @person.reload
55
+
56
+ @person.projects_attributes = { project.id.to_s => { :id => project.id, :name => 'still dm-accepts_nested_attributes' } }
57
+ @person.projects.should_not be_empty
58
+ @person.projects.first.name.should == 'still dm-accepts_nested_attributes'
59
+ @person.save
60
+
61
+ Person.all.size.should == 1
62
+ ProjectMembership.all.size.should == 1
63
+ Project.all.size.should == 1
64
+
65
+ Project.first.name.should == 'still dm-accepts_nested_attributes'
66
+ end
67
+
68
+ end
69
+
70
+ describe "every accessible has(n, :through) association with :allow_destroy => false", :shared => true do
71
+
72
+ it "should not allow to delete an existing project via Person#projects_attributes" do
73
+ @person.save
74
+ project = Project.create(:name => 'dm-accepts_nested_attributes')
75
+ project_membership = ProjectMembership.create(:person => @person, :project => project)
76
+
77
+ Person.all.size.should == 1
78
+ ProjectMembership.all.size.should == 1
79
+ Project.all.size.should == 1
80
+
81
+ @person.reload
82
+ @person.projects_attributes = { '1' => { :id => project.id, :_delete => true } }
83
+ @person.save
84
+
85
+ Person.all.size.should == 1
86
+ ProjectMembership.all.size.should == 1
87
+ Project.all.size.should == 1
88
+ end
89
+
90
+ end
91
+
92
+ describe "every accessible has(n, :through) association with :allow_destroy => true", :shared => true do
93
+
94
+ it "should allow to delete an existing project via Person#projects_attributes" do
95
+ @person.save
96
+ project = Project.create(:name => 'dm-accepts_nested_attributes')
97
+ project_membership = ProjectMembership.create(:person => @person, :project => project)
98
+
99
+ Person.all.size.should == 1
100
+ ProjectMembership.all.size.should == 1
101
+ Project.all.size.should == 1
102
+
103
+ @person.reload
104
+ @person.projects_attributes = { '1' => { :id => project.id, :_delete => true } }
105
+ @person.save
106
+
107
+ Person.all.size.should == 1
108
+ ProjectMembership.all.size.should == 0
109
+ Project.all.size.should == 0
110
+ end
111
+
112
+ end
113
+
114
+ describe "Person.has(n, :projects, :through => :project_memberships)" do
115
+
116
+ describe "accepts_nested_attributes_for(:projects)" do
117
+
118
+ before(:each) do
119
+ DataMapper.auto_migrate!
120
+ Person.accepts_nested_attributes_for :projects
121
+ @person = Person.new :name => 'snusnu'
122
+ end
123
+
124
+ it_should_behave_like "every accessible has(n, :through) association with no reject_if proc"
125
+ it_should_behave_like "every accessible has(n, :through) association with :allow_destroy => false"
126
+
127
+ end
128
+
129
+ describe "accepts_nested_attributes_for(:projects, :allow_destroy => false)" do
130
+
131
+ before(:each) do
132
+ DataMapper.auto_migrate!
133
+ Person.accepts_nested_attributes_for :projects, :allow_destroy => false
134
+ @person = Person.new :name => 'snusnu'
135
+ end
136
+
137
+ it_should_behave_like "every accessible has(n, :through) association with no reject_if proc"
138
+ it_should_behave_like "every accessible has(n, :through) association with :allow_destroy => false"
139
+
140
+ end
141
+
142
+ describe "accepts_nested_attributes_for(:projects, :allow_destroy = true)" do
143
+
144
+ before(:each) do
145
+ DataMapper.auto_migrate!
146
+ Person.accepts_nested_attributes_for :projects, :allow_destroy => true
147
+ @person = Person.new :name => 'snusnu'
148
+ end
149
+
150
+ it_should_behave_like "every accessible has(n, :through) association with no reject_if proc"
151
+ it_should_behave_like "every accessible has(n, :through) association with :allow_destroy => true"
152
+
153
+ end
154
+
155
+ describe "accepts_nested_attributes_for :projects, " do
156
+
157
+ describe ":reject_if => :foo" do
158
+
159
+ before(:each) do
160
+ DataMapper.auto_migrate!
161
+ Person.accepts_nested_attributes_for :projects, :reject_if => :foo
162
+ @person = Person.new :name => 'snusnu'
163
+ end
164
+
165
+ it_should_behave_like "every accessible has(n, :through) association with no reject_if proc"
166
+ it_should_behave_like "every accessible has(n, :through) association with :allow_destroy => false"
167
+
168
+ end
169
+
170
+ describe ":reject_if => lambda { |attrs| true }" do
171
+
172
+ before(:each) do
173
+ DataMapper.auto_migrate!
174
+ Person.accepts_nested_attributes_for :projects, :reject_if => lambda { |attrs| true }
175
+ @person = Person.new :name => 'snusnu'
176
+ end
177
+
178
+ it_should_behave_like "every accessible has(n, :through) association with a valid reject_if proc"
179
+ it_should_behave_like "every accessible has(n, :through) association with :allow_destroy => false"
180
+
181
+ end
182
+
183
+ describe ":reject_if => lambda { |attrs| false }" do
184
+
185
+ before(:each) do
186
+ DataMapper.auto_migrate!
187
+ Person.accepts_nested_attributes_for :projects, :reject_if => lambda { |attrs| false }
188
+ @person = Person.new :name => 'snusnu'
189
+ end
190
+
191
+ it_should_behave_like "every accessible has(n, :through) association with no reject_if proc"
192
+ it_should_behave_like "every accessible has(n, :through) association with :allow_destroy => false"
193
+
194
+ end
195
+
196
+ end
197
+
198
+ end
199
+
200
+ end
@@ -0,0 +1,35 @@
1
+ # -----------------------------------------------
2
+ # support for nice html output in rspec tmbundle
3
+ # -----------------------------------------------
4
+
5
+ module RSpecTmBundleHelpers
6
+
7
+ class TextmateRspecLogger < DataMapper::Logger
8
+ def prep_msg(message, level)
9
+ "#{super}<br />"
10
+ end
11
+ end
12
+
13
+ def with_dm_logger(level = :debug)
14
+ DataMapper.logger.level = level
15
+ yield
16
+ ensure
17
+ DataMapper.logger.level = :off
18
+ end
19
+
20
+ def print_call_stack(from = 2, to = nil, html = true)
21
+ (from..(to ? to : caller.length)).each do |idx|
22
+ p "[#{idx}]: #{caller[idx]}#{html ? '<br />' : ''}"
23
+ end
24
+ end
25
+
26
+ def puth(html)
27
+ print "#{h(html)}<br />"
28
+ end
29
+
30
+ ESCAPE_TABLE = { '&'=>'&amp;', '<'=>'&lt;', '>'=>'&gt;', '"'=>'&quot;', "'"=>'&#039;', }
31
+ def h(value)
32
+ value.to_s.gsub(/[&<>"]/) {|s| ESCAPE_TABLE[s] }
33
+ end
34
+
35
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --format specdoc
2
+ --colour
@@ -0,0 +1,58 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+
4
+ gem 'rspec', '>=1.1.12'
5
+ require 'spec'
6
+
7
+ gem 'dm-core', '0.9.11'
8
+ require 'dm-core'
9
+
10
+ gem 'dm-validations', '0.9.11'
11
+ require 'dm-validations'
12
+
13
+ require Pathname(__FILE__).dirname.parent.expand_path + 'lib/dm-accepts_nested_attributes'
14
+
15
+ ENV["SQLITE3_SPEC_URI"] ||= 'sqlite3::memory:'
16
+ ENV["MYSQL_SPEC_URI"] ||= 'mysql://localhost/dm_core_test'
17
+ ENV["POSTGRES_SPEC_URI"] ||= 'postgres://postgres@localhost/dm_more_test'
18
+
19
+
20
+ def setup_adapter(name, default_uri = nil)
21
+ begin
22
+ DataMapper.setup(name, ENV["#{ENV['ADAPTER'].to_s.upcase}_SPEC_URI"] || default_uri)
23
+ Object.const_set('ADAPTER', ENV['ADAPTER'].to_sym) if name.to_s == ENV['ADAPTER']
24
+ true
25
+ rescue Exception => e
26
+ if name.to_s == ENV['ADAPTER']
27
+ Object.const_set('ADAPTER', nil)
28
+ warn "Could not load do_#{name}: #{e}"
29
+ end
30
+ false
31
+ end
32
+ end
33
+
34
+ ENV['ADAPTER'] ||= 'sqlite3'
35
+
36
+
37
+ setup_adapter(:default)
38
+ Dir[Pathname(__FILE__).dirname.to_s + "/fixtures/**/*.rb"].each { |rb| require(rb) }
39
+
40
+
41
+ # -----------------------------------------------
42
+ # support for nice html output in rspec tmbundle
43
+ # -----------------------------------------------
44
+
45
+ USE_TEXTMATE_RSPEC_BUNDLE = true # set to false if not using textmate
46
+
47
+ if USE_TEXTMATE_RSPEC_BUNDLE
48
+
49
+ require Pathname(__FILE__).dirname.expand_path + 'shared/rspec_tmbundle_support'
50
+
51
+ # use the tmbundle logger
52
+ RSpecTmBundleHelpers::TextmateRspecLogger.new(STDOUT, :off)
53
+
54
+ class Object
55
+ include RSpecTmBundleHelpers
56
+ end
57
+
58
+ end