datamapper 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -1
- data/FAQ +96 -0
- data/QUICKLINKS +12 -0
- data/README +57 -155
- data/environment.rb +61 -43
- data/example.rb +30 -12
- data/lib/data_mapper.rb +6 -1
- data/lib/data_mapper/adapters/abstract_adapter.rb +0 -57
- data/lib/data_mapper/adapters/data_object_adapter.rb +203 -97
- data/lib/data_mapper/adapters/mysql_adapter.rb +4 -0
- data/lib/data_mapper/adapters/postgresql_adapter.rb +7 -1
- data/lib/data_mapper/adapters/sql/coersion.rb +3 -2
- data/lib/data_mapper/adapters/sql/commands/load_command.rb +29 -10
- data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +4 -0
- data/lib/data_mapper/adapters/sql/mappings/column.rb +13 -9
- data/lib/data_mapper/adapters/sql/mappings/conditions.rb +172 -0
- data/lib/data_mapper/adapters/sql/mappings/table.rb +43 -17
- data/lib/data_mapper/adapters/sqlite3_adapter.rb +9 -2
- data/lib/data_mapper/associations.rb +75 -3
- data/lib/data_mapper/associations/belongs_to_association.rb +70 -36
- data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +195 -86
- data/lib/data_mapper/associations/has_many_association.rb +168 -61
- data/lib/data_mapper/associations/has_n_association.rb +23 -3
- data/lib/data_mapper/attributes.rb +73 -0
- data/lib/data_mapper/auto_migrations.rb +2 -6
- data/lib/data_mapper/base.rb +5 -9
- data/lib/data_mapper/database.rb +4 -3
- data/lib/data_mapper/embedded_value.rb +66 -30
- data/lib/data_mapper/identity_map.rb +1 -3
- data/lib/data_mapper/is/tree.rb +121 -0
- data/lib/data_mapper/migration.rb +155 -0
- data/lib/data_mapper/persistence.rb +532 -218
- data/lib/data_mapper/property.rb +306 -0
- data/lib/data_mapper/query.rb +164 -0
- data/lib/data_mapper/support/blank.rb +2 -2
- data/lib/data_mapper/support/connection_pool.rb +5 -6
- data/lib/data_mapper/support/enumerable.rb +3 -3
- data/lib/data_mapper/support/errors.rb +10 -1
- data/lib/data_mapper/support/inflector.rb +174 -238
- data/lib/data_mapper/support/object.rb +54 -0
- data/lib/data_mapper/support/serialization.rb +19 -1
- data/lib/data_mapper/support/string.rb +7 -16
- data/lib/data_mapper/support/symbol.rb +3 -15
- data/lib/data_mapper/support/typed_set.rb +68 -0
- data/lib/data_mapper/types/base.rb +44 -0
- data/lib/data_mapper/types/string.rb +34 -0
- data/lib/data_mapper/validations/number_validator.rb +40 -0
- data/lib/data_mapper/validations/string_validator.rb +20 -0
- data/lib/data_mapper/validations/validator.rb +13 -0
- data/performance.rb +26 -1
- data/profile_data_mapper.rb +1 -1
- data/rakefile.rb +42 -2
- data/spec/acts_as_tree_spec.rb +11 -3
- data/spec/adapters/data_object_adapter_spec.rb +31 -0
- data/spec/associations/belongs_to_association_spec.rb +98 -0
- data/spec/associations/has_and_belongs_to_many_association_spec.rb +377 -0
- data/spec/associations/has_many_association_spec.rb +337 -0
- data/spec/attributes_spec.rb +23 -1
- data/spec/auto_migrations_spec.rb +86 -29
- data/spec/callbacks_spec.rb +107 -0
- data/spec/column_spec.rb +5 -2
- data/spec/count_command_spec.rb +33 -1
- data/spec/database_spec.rb +18 -0
- data/spec/dependency_spec.rb +4 -2
- data/spec/embedded_value_spec.rb +8 -8
- data/spec/fixtures/people.yaml +1 -1
- data/spec/fixtures/projects.yaml +10 -1
- data/spec/fixtures/tasks.yaml +6 -0
- data/spec/fixtures/tasks_tasks.yaml +2 -0
- data/spec/fixtures/tomatoes.yaml +1 -0
- data/spec/is_a_tree_spec.rb +149 -0
- data/spec/load_command_spec.rb +71 -9
- data/spec/magic_columns_spec.rb +17 -2
- data/spec/migration_spec.rb +267 -0
- data/spec/models/animal.rb +1 -1
- data/spec/models/candidate.rb +8 -0
- data/spec/models/career.rb +1 -1
- data/spec/models/chain.rb +8 -0
- data/spec/models/comment.rb +1 -1
- data/spec/models/exhibit.rb +1 -1
- data/spec/models/fence.rb +7 -0
- data/spec/models/fruit.rb +2 -2
- data/spec/models/job.rb +8 -0
- data/spec/models/person.rb +2 -3
- data/spec/models/post.rb +1 -1
- data/spec/models/project.rb +21 -1
- data/spec/models/section.rb +1 -1
- data/spec/models/serializer.rb +1 -1
- data/spec/models/task.rb +9 -0
- data/spec/models/tomato.rb +27 -0
- data/spec/models/user.rb +8 -2
- data/spec/models/zoo.rb +2 -7
- data/spec/paranoia_spec.rb +1 -1
- data/spec/{base_spec.rb → persistence_spec.rb} +207 -18
- data/spec/postgres_spec.rb +48 -6
- data/spec/property_spec.rb +90 -9
- data/spec/query_spec.rb +71 -5
- data/spec/save_command_spec.rb +11 -0
- data/spec/spec_helper.rb +14 -11
- data/spec/support/blank_spec.rb +8 -0
- data/spec/support/inflector_spec.rb +41 -0
- data/spec/support/object_spec.rb +9 -0
- data/spec/{serialization_spec.rb → support/serialization_spec.rb} +1 -1
- data/spec/support/silence_spec.rb +15 -0
- data/spec/{support_spec.rb → support/string_spec.rb} +3 -3
- data/spec/support/struct_spec.rb +12 -0
- data/spec/support/typed_set_spec.rb +66 -0
- data/spec/table_spec.rb +3 -3
- data/spec/types/string.rb +81 -0
- data/spec/validates_uniqueness_of_spec.rb +17 -0
- data/spec/validations/number_validator.rb +59 -0
- data/spec/validations/string_validator.rb +14 -0
- metadata +59 -17
- data/do_performance.rb +0 -153
- data/lib/data_mapper/support/active_record_impersonation.rb +0 -103
- data/lib/data_mapper/support/weak_hash.rb +0 -46
- data/spec/active_record_impersonation_spec.rb +0 -129
- data/spec/associations_spec.rb +0 -232
- data/spec/conditions_spec.rb +0 -49
- data/spec/has_many_association_spec.rb +0 -173
- data/spec/models/animals_exhibit.rb +0 -8
data/spec/callbacks_spec.rb
CHANGED
@@ -76,4 +76,111 @@ describe DataMapper::Callbacks do
|
|
76
76
|
post.instance_variable_get("@three").should eql('blue_cow')
|
77
77
|
end
|
78
78
|
|
79
|
+
it "should execute materialization callbacks" do
|
80
|
+
|
81
|
+
$before_materialize = 0
|
82
|
+
$after_materialize = 0
|
83
|
+
|
84
|
+
Zoo.before_materialize do
|
85
|
+
$before_materialize += 1
|
86
|
+
end
|
87
|
+
|
88
|
+
Zoo.after_materialize do
|
89
|
+
$after_materialize += 1
|
90
|
+
end
|
91
|
+
|
92
|
+
class Zoo
|
93
|
+
|
94
|
+
# This syntax doesn't work in DM.
|
95
|
+
# Which I don't think is necessarily a bad thing...
|
96
|
+
# Just FYI -Sam
|
97
|
+
def before_materialize
|
98
|
+
$before_materialize += 1
|
99
|
+
end
|
100
|
+
|
101
|
+
def call_before_materialize
|
102
|
+
$before_materialize += 1
|
103
|
+
end
|
104
|
+
|
105
|
+
# Example of invalid syntax
|
106
|
+
def after_materialize
|
107
|
+
$after_materialize += 1
|
108
|
+
end
|
109
|
+
|
110
|
+
def call_after_materialize
|
111
|
+
$after_materialize += 1
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
Zoo.before_materialize :call_before_materialize
|
117
|
+
Zoo.after_materialize :call_after_materialize
|
118
|
+
|
119
|
+
Zoo.before_materialize "$before_materialize += 1"
|
120
|
+
Zoo.after_materialize "$after_materialize += 1"
|
121
|
+
|
122
|
+
Zoo.first
|
123
|
+
|
124
|
+
$before_materialize.should == 3
|
125
|
+
$after_materialize.should == 3
|
126
|
+
|
127
|
+
Zoo[1]
|
128
|
+
|
129
|
+
$before_materialize.should == 6
|
130
|
+
$after_materialize.should == 6
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should execute creation callbacks" do
|
135
|
+
|
136
|
+
$before_create = 0
|
137
|
+
$after_create = 0
|
138
|
+
|
139
|
+
Zoo.before_create do
|
140
|
+
$before_create += 1
|
141
|
+
end
|
142
|
+
|
143
|
+
Zoo.after_create do
|
144
|
+
$after_create += 1
|
145
|
+
end
|
146
|
+
|
147
|
+
class Zoo
|
148
|
+
|
149
|
+
# Example of invalid syntax
|
150
|
+
def before_create
|
151
|
+
$before_create += 1
|
152
|
+
end
|
153
|
+
|
154
|
+
def call_before_create
|
155
|
+
$before_create += 1
|
156
|
+
end
|
157
|
+
|
158
|
+
# Example of invalid syntax
|
159
|
+
def after_create
|
160
|
+
$after_create += 1
|
161
|
+
end
|
162
|
+
|
163
|
+
def call_after_create
|
164
|
+
$after_create += 1
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
Zoo.before_create :call_before_create
|
170
|
+
Zoo.after_create :call_after_create
|
171
|
+
|
172
|
+
Zoo.before_create "$before_create += 1"
|
173
|
+
Zoo.after_create "$after_create += 1"
|
174
|
+
|
175
|
+
Zoo.create(:name => 'bob')
|
176
|
+
|
177
|
+
$before_create.should == 3
|
178
|
+
$after_create.should == 3
|
179
|
+
|
180
|
+
Zoo.new(:name => 'bob2').save
|
181
|
+
|
182
|
+
$before_create.should == 6
|
183
|
+
$after_create.should == 6
|
184
|
+
end
|
185
|
+
|
79
186
|
end
|
data/spec/column_spec.rb
CHANGED
@@ -46,13 +46,13 @@ describe DataMapper::Adapters::Sql::Mappings::Column do
|
|
46
46
|
lambda { database.query("SELECT name FROM zoos") }.should_not raise_error
|
47
47
|
lambda { database.query("SELECT moo FROM zoos") }.should raise_error
|
48
48
|
|
49
|
-
name_column.rename!(:moo)
|
49
|
+
name_column = name_column.rename!(:moo)
|
50
50
|
name_column.name.should eql(:moo)
|
51
51
|
|
52
52
|
lambda { database.query("SELECT name FROM zoos") }.should raise_error
|
53
53
|
lambda { database.query("SELECT moo FROM zoos") }.should_not raise_error
|
54
54
|
|
55
|
-
name_column.rename!(:name)
|
55
|
+
name_column = name_column.rename!(:name)
|
56
56
|
name_column.name.should eql(:name)
|
57
57
|
|
58
58
|
lambda { database.query("SELECT name FROM zoos") }.should_not raise_error
|
@@ -88,6 +88,7 @@ describe DataMapper::Adapters::Sql::Mappings::Column do
|
|
88
88
|
|
89
89
|
Zoo.send(:undef_method, :moo)
|
90
90
|
Zoo.send(:undef_method, :moo=)
|
91
|
+
Zoo.properties.delete_if { |x| x.name == :moo }
|
91
92
|
|
92
93
|
lambda { database.query("SELECT moo FROM zoos") }.should raise_error
|
93
94
|
end
|
@@ -100,6 +101,8 @@ describe DataMapper::Adapters::Sql::Mappings::Column do
|
|
100
101
|
it "should be able to create a column with unique index" do
|
101
102
|
column = table.add_column("name", :string, :index => :unique)
|
102
103
|
column.unique?.should be_true
|
104
|
+
column.index?.should be_nil
|
105
|
+
table.to_create_index_sql.should == []
|
103
106
|
table.to_create_sql.should match(/UNIQUE/)
|
104
107
|
end
|
105
108
|
|
data/spec/count_command_spec.rb
CHANGED
@@ -1,13 +1,45 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
2
|
|
3
|
-
describe DataMapper::Adapters::AbstractAdapter do
|
3
|
+
describe DataMapper::Adapters::AbstractAdapter, "count()" do
|
4
4
|
|
5
5
|
before(:all) do
|
6
6
|
fixtures(:zoos)
|
7
|
+
fixtures(:projects)
|
7
8
|
end
|
8
9
|
|
9
10
|
it "should return a count of the selected table" do
|
10
11
|
Zoo.count.should be_a_kind_of(Integer)
|
11
12
|
Zoo.count.should == Zoo.all.size
|
12
13
|
end
|
14
|
+
|
15
|
+
it "should accept finder style options" do
|
16
|
+
# Hash-style (with SymbolOperators)
|
17
|
+
Zoo.count(:name => 'Dallas').should == Zoo.all(:name => 'Dallas').length
|
18
|
+
Zoo.count(:name.not => nil).should == Zoo.all(:name.not => nil).length
|
19
|
+
Zoo.count(:name.not => nil, :notes => nil).should == Zoo.all(:name.not => nil, :notes => nil).length
|
20
|
+
Zoo.count(:name.like => '%.%').should == Zoo.all(:name.like => '%.%').length
|
21
|
+
|
22
|
+
# :conditions
|
23
|
+
Zoo.count(:conditions => ["name = ?", 'Dallas']).should == Zoo.all(:conditions => ["name = ?", 'Dallas']).length
|
24
|
+
|
25
|
+
# mix and match
|
26
|
+
Zoo.count(:notes => nil, :conditions => ["name = ?", 'Dallas']).should == Zoo.all(:notes => nil, :conditions => ["name = ?", 'Dallas']).length
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should respect paranoia" do
|
30
|
+
p = Project[3]
|
31
|
+
p.destroy!
|
32
|
+
|
33
|
+
Project.count.should == Project.all.length
|
34
|
+
# clean up
|
35
|
+
p.deleted_at = nil
|
36
|
+
p.save
|
37
|
+
end
|
38
|
+
|
39
|
+
#This won't work at the moment, hopefully before 0.3.0
|
40
|
+
it "should do distinct counting" do
|
41
|
+
#Zoo.count(:distinct => :name).should == Zoo.all.length # there all distinct in the fixtures
|
42
|
+
#Zoo.count(:distinct => :name, :notes.not => nil).should == Zoo.all(:notes.not => nil).length
|
43
|
+
#Zoo.count(:distinct => :name, :conditions => ["notes is not null"]).should == Zoo.all(:notes.not => nil).length
|
44
|
+
end
|
13
45
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe('Multiple Databases') do
|
4
|
+
|
5
|
+
it "should scope model creation and lookup" do
|
6
|
+
database(:secondary) do
|
7
|
+
Zoo.create :name => 'secondary'
|
8
|
+
end
|
9
|
+
|
10
|
+
Zoo.first(:name => 'secondary').should be_nil
|
11
|
+
|
12
|
+
database(:secondary) do
|
13
|
+
Zoo.first(:name => 'secondary').should_not be_nil
|
14
|
+
Zoo.first(:name => 'secondary').destroy!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/spec/dependency_spec.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
2
|
|
3
|
-
describe DataMapper::Persistence
|
3
|
+
# Can't describe DataMapper::Persistence because
|
4
|
+
# rspec will include it for some crazy reason!
|
5
|
+
describe "DataMapper::Persistence" do
|
4
6
|
|
5
7
|
it "should be able to add a dependency for a class not yet defined" do
|
6
8
|
|
@@ -12,7 +14,7 @@ describe DataMapper::Persistence do
|
|
12
14
|
$happy_cow_defined = true
|
13
15
|
end
|
14
16
|
|
15
|
-
class HappyCow
|
17
|
+
class HappyCow #< DataMapper::Base # please do not remove this
|
16
18
|
include DataMapper::Persistence
|
17
19
|
|
18
20
|
property :name, :string, :key => true
|
data/spec/embedded_value_spec.rb
CHANGED
@@ -19,7 +19,7 @@ describe DataMapper::EmbeddedValue do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'should not require prefix' do
|
22
|
-
class PointyHeadedBoss
|
22
|
+
class PointyHeadedBoss #< DataMapper::Base # please do not remove this
|
23
23
|
include DataMapper::Persistence
|
24
24
|
|
25
25
|
set_table_name 'people'
|
@@ -38,7 +38,7 @@ describe DataMapper::EmbeddedValue do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'should add convenience methods to the non-embedded base' do
|
41
|
-
class Employee
|
41
|
+
class Employee #< DataMapper::Base # please do not remove this
|
42
42
|
include DataMapper::Persistence
|
43
43
|
|
44
44
|
set_table_name 'people'
|
@@ -55,7 +55,7 @@ describe DataMapper::EmbeddedValue do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'should support lazy loading of embedded properties' do
|
58
|
-
class Human
|
58
|
+
class Human #< DataMapper::Base # please do not remove this
|
59
59
|
include DataMapper::Persistence
|
60
60
|
|
61
61
|
set_table_name 'people'
|
@@ -72,7 +72,7 @@ describe DataMapper::EmbeddedValue do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'should default to public method visibility for all' do
|
75
|
-
class SoftwareEngineer
|
75
|
+
class SoftwareEngineer #< DataMapper::Base # please do not remove this
|
76
76
|
include DataMapper::Persistence
|
77
77
|
|
78
78
|
set_table_name 'people'
|
@@ -89,7 +89,7 @@ describe DataMapper::EmbeddedValue do
|
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'should respect protected property options for all' do
|
92
|
-
class SanitationEngineer
|
92
|
+
class SanitationEngineer #< DataMapper::Base # please do not remove this
|
93
93
|
include DataMapper::Persistence
|
94
94
|
|
95
95
|
set_table_name 'people'
|
@@ -107,7 +107,7 @@ describe DataMapper::EmbeddedValue do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
it 'should respect private property options for all' do
|
110
|
-
class ElectricalEngineer
|
110
|
+
class ElectricalEngineer #< DataMapper::Base # please do not remove this
|
111
111
|
include DataMapper::Persistence
|
112
112
|
|
113
113
|
set_table_name 'people'
|
@@ -125,7 +125,7 @@ describe DataMapper::EmbeddedValue do
|
|
125
125
|
end
|
126
126
|
|
127
127
|
it 'should set both reader and writer visibiliy for all when accessor option is passed' do
|
128
|
-
class TrainEngineer
|
128
|
+
class TrainEngineer #< DataMapper::Base # please do not remove this
|
129
129
|
include DataMapper::Persistence
|
130
130
|
|
131
131
|
set_table_name 'people'
|
@@ -142,7 +142,7 @@ describe DataMapper::EmbeddedValue do
|
|
142
142
|
end
|
143
143
|
|
144
144
|
it 'should allow individual properties to override method visibility options passed on the block' do
|
145
|
-
class ChemicalEngineer
|
145
|
+
class ChemicalEngineer #< DataMapper::Base # please do not remove this
|
146
146
|
include DataMapper::Persistence
|
147
147
|
|
148
148
|
set_table_name 'people'
|
data/spec/fixtures/people.yaml
CHANGED
data/spec/fixtures/projects.yaml
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
---
|
2
2
|
- id: 1
|
3
3
|
title: Test
|
4
|
-
description:
|
4
|
+
description: test
|
5
|
+
- id: 2
|
6
|
+
title: The Empire State Building
|
7
|
+
description: "The Empire State Building is a 102-story Art Deco skyscraper in New York City, New York"
|
8
|
+
- id: 3
|
9
|
+
title: World Trade Center
|
10
|
+
description: "The World Trade Center in New York City, United States"
|
11
|
+
- id: 4
|
12
|
+
title: The Statue Of Liberty
|
13
|
+
description: "Liberty Enlightening the World (French: La liberte eclairant le monde), known more commonly as the Statue of Liberty"
|
@@ -0,0 +1,6 @@
|
|
1
|
+
- name: task_relax
|
2
|
+
notes: I am the relaxed task an should be related to task_vacation
|
3
|
+
- name: task_drink_heartily
|
4
|
+
notes: I am the drink heartily task and should be related to task_relax
|
5
|
+
- name: task_vacation
|
6
|
+
notes: I am the vacation task and should be related to task_relax
|
@@ -0,0 +1 @@
|
|
1
|
+
--- []
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
class DataMapper::MockBase
|
4
|
+
include DataMapper::Is::Tree
|
5
|
+
end
|
6
|
+
|
7
|
+
class DefaultTree < DataMapper::MockBase
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "DataMapper::Is::Tree receiving various is_a_tree configurations" do
|
11
|
+
setup do
|
12
|
+
DefaultTree.stub!(:has_many)
|
13
|
+
DefaultTree.stub!(:belongs_to)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should setup a belongs_to relationship with the parent with the default configurations" do
|
17
|
+
DefaultTree.should_receive(:belongs_to).with(:parent, :foreign_key => "parent_id", :counter_cache => nil,
|
18
|
+
:class_name => "DefaultTree")
|
19
|
+
DefaultTree.send(:is_a_tree)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should setup a has_many relationship with the children with default configurations" do
|
23
|
+
DefaultTree.should_receive(:has_many).with(:children, :foreign_key => "parent_id", :order => nil,
|
24
|
+
:class_name => "DefaultTree")
|
25
|
+
DefaultTree.send(:is_a_tree)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should setup a belongs_to relationship with the correct foreign key" do
|
29
|
+
DefaultTree.should_receive(:belongs_to).with(:parent, :foreign_key => "something_id", :counter_cache => nil,
|
30
|
+
:class_name => "DefaultTree")
|
31
|
+
DefaultTree.send(:is_a_tree, :foreign_key => "something_id")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should setup a has_many relationship with the children with the correct foreign key" do
|
35
|
+
DefaultTree.should_receive(:has_many).with(:children, :foreign_key => "something_id", :order => nil,
|
36
|
+
:class_name => "DefaultTree")
|
37
|
+
DefaultTree.send(:is_a_tree, :foreign_key => "something_id")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should setup a has_many relationship with the children with the correct order" do
|
41
|
+
DefaultTree.should_receive(:has_many).with(:children, :foreign_key => "parent_id", :order => 'position',
|
42
|
+
:class_name => "DefaultTree")
|
43
|
+
DefaultTree.send(:is_a_tree, :order => 'position')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "Default DataMapper::Is::Tree class methods" do
|
48
|
+
setup do
|
49
|
+
DefaultTree.stub!(:has_many)
|
50
|
+
DefaultTree.stub!(:belongs_to)
|
51
|
+
DefaultTree.send(:can_has_tree)
|
52
|
+
DefaultTree.stub!(:all).and_return([])
|
53
|
+
DefaultTree.stub!(:first).and_return(nil)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should return an empty array for .roots" do
|
57
|
+
DefaultTree.roots.should == []
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should find with the correct options on .roots" do
|
61
|
+
DefaultTree.should_receive(:all).with(:parent_id => nil, :order => nil)
|
62
|
+
DefaultTree.roots
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return nil for .first_root" do
|
66
|
+
DefaultTree.root.should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should find with the correct options on .first_root" do
|
70
|
+
DefaultTree.should_receive(:first).with(:parent_id => nil, :order => nil)
|
71
|
+
DefaultTree.first_root
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "Configured DataMapper::Is::Tree class methods" do
|
76
|
+
setup do
|
77
|
+
DefaultTree.stub!(:has_many)
|
78
|
+
DefaultTree.stub!(:belongs_to)
|
79
|
+
DefaultTree.send(:can_has_tree, :foreign_key => 'mew_id', :order => 'mew')
|
80
|
+
DefaultTree.stub!(:all).and_return([])
|
81
|
+
DefaultTree.stub!(:first).and_return(nil)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return an empty array for .roots" do
|
85
|
+
DefaultTree.roots.should == []
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should find with the correct options on .roots" do
|
89
|
+
DefaultTree.should_receive(:all).with(:mew_id => nil, :order => 'mew')
|
90
|
+
DefaultTree.roots
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should return nil for .first_root" do
|
94
|
+
DefaultTree.root.should be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should find with the correct options on .first_root" do
|
98
|
+
DefaultTree.should_receive(:first).with(:mew_id => nil, :order => 'mew')
|
99
|
+
DefaultTree.first_root
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "Default DataMapper::Is::Tree instance methods" do
|
104
|
+
setup do
|
105
|
+
DefaultTree.stub!(:has_many)
|
106
|
+
DefaultTree.stub!(:belongs_to)
|
107
|
+
DefaultTree.send(:is_a_tree)
|
108
|
+
@root = DefaultTree.new
|
109
|
+
@child = DefaultTree.new
|
110
|
+
@grandchild1 = DefaultTree.new
|
111
|
+
@grandchild2 = DefaultTree.new
|
112
|
+
|
113
|
+
# Mocking the belongs_to & has_many relationships (part of the not-needing-a-db-to-test plan)
|
114
|
+
@root.stub!(:parent).and_return nil
|
115
|
+
@child.stub!(:parent).and_return @root
|
116
|
+
@grandchild1.stub!(:parent).and_return(@child)
|
117
|
+
@grandchild2.stub!(:parent).and_return(@child)
|
118
|
+
@child.stub!(:children).and_return([@grandchild1, @grandchild2])
|
119
|
+
@root.stub!(:children).and_return([@child])
|
120
|
+
@grandchild1.stub!(:children).and_return []
|
121
|
+
@grandchild2.stub!(:children).and_return []
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should return an array of parents, furthest parent first, for #ancestors" do
|
125
|
+
@grandchild1.ancestors.should == [@root, @child]
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return an array of siblings for #siblings" do
|
129
|
+
@grandchild1.siblings.should == [@grandchild2]
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should return all children of the node's parent for #generation" do
|
133
|
+
@grandchild1.generation.should == [@grandchild1, @grandchild2]
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return roots on #generation when there is no parent" do
|
137
|
+
DefaultTree.should_receive(:roots).and_return [@root]
|
138
|
+
@root.generation.should == [@root]
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should return the top-most parent on #root" do
|
142
|
+
@grandchild1.root.should == @root
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should return self on #root if self has no parent" do
|
146
|
+
@root.root.should == @root
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|