snusnu-dm-accepts_nested_attributes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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