datamapper 0.2.5 → 0.3.0
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/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
|