dm-core 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +27 -0
- data/LICENSE +20 -0
- data/{README.txt → README.rdoc} +14 -3
- data/Rakefile +23 -22
- data/VERSION +1 -0
- data/dm-core.gemspec +201 -10
- data/lib/dm-core.rb +32 -23
- data/lib/dm-core/adapters.rb +0 -1
- data/lib/dm-core/adapters/data_objects_adapter.rb +230 -151
- data/lib/dm-core/adapters/mysql_adapter.rb +7 -8
- data/lib/dm-core/adapters/oracle_adapter.rb +39 -59
- data/lib/dm-core/adapters/postgres_adapter.rb +0 -1
- data/lib/dm-core/adapters/sqlite3_adapter.rb +5 -0
- data/lib/dm-core/adapters/sqlserver_adapter.rb +114 -0
- data/lib/dm-core/adapters/yaml_adapter.rb +0 -5
- data/lib/dm-core/associations/many_to_many.rb +118 -56
- data/lib/dm-core/associations/many_to_one.rb +48 -21
- data/lib/dm-core/associations/one_to_many.rb +8 -30
- data/lib/dm-core/associations/one_to_one.rb +1 -5
- data/lib/dm-core/associations/relationship.rb +89 -97
- data/lib/dm-core/collection.rb +299 -184
- data/lib/dm-core/core_ext/enumerable.rb +28 -0
- data/lib/dm-core/core_ext/kernel.rb +0 -2
- data/lib/dm-core/migrations.rb +314 -170
- data/lib/dm-core/model.rb +97 -66
- data/lib/dm-core/model/descendant_set.rb +1 -1
- data/lib/dm-core/model/hook.rb +0 -3
- data/lib/dm-core/model/property.rb +7 -10
- data/lib/dm-core/model/relationship.rb +79 -26
- data/lib/dm-core/model/scope.rb +3 -4
- data/lib/dm-core/property.rb +152 -90
- data/lib/dm-core/property_set.rb +18 -37
- data/lib/dm-core/query.rb +452 -153
- data/lib/dm-core/query/conditions/comparison.rb +266 -173
- data/lib/dm-core/query/conditions/operation.rb +499 -57
- data/lib/dm-core/query/direction.rb +0 -3
- data/lib/dm-core/query/operator.rb +0 -4
- data/lib/dm-core/query/path.rb +10 -12
- data/lib/dm-core/query/sort.rb +4 -10
- data/lib/dm-core/repository.rb +10 -6
- data/lib/dm-core/resource.rb +343 -148
- data/lib/dm-core/spec/adapter_shared_spec.rb +17 -1
- data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +277 -17
- data/lib/dm-core/support/chainable.rb +0 -2
- data/lib/dm-core/support/equalizer.rb +27 -3
- data/lib/dm-core/transaction.rb +75 -75
- data/lib/dm-core/type.rb +19 -5
- data/lib/dm-core/types/discriminator.rb +4 -4
- data/lib/dm-core/types/object.rb +2 -7
- data/lib/dm-core/types/paranoid_boolean.rb +8 -2
- data/lib/dm-core/types/paranoid_datetime.rb +8 -2
- data/lib/dm-core/version.rb +1 -1
- data/script/performance.rb +7 -7
- data/script/profile.rb +6 -6
- data/spec/lib/collection_helpers.rb +2 -2
- data/spec/lib/pending_helpers.rb +22 -3
- data/spec/lib/rspec_immediate_feedback_formatter.rb +1 -0
- data/spec/public/associations/many_to_many_spec.rb +6 -4
- data/spec/public/associations/many_to_one_spec.rb +10 -1
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +39 -0
- data/spec/public/associations/one_to_many_spec.rb +4 -3
- data/spec/public/associations/one_to_one_spec.rb +19 -1
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +45 -0
- data/spec/public/collection_spec.rb +4 -3
- data/spec/public/migrations_spec.rb +144 -0
- data/spec/public/model/relationship_spec.rb +115 -55
- data/spec/public/model_spec.rb +13 -13
- data/spec/public/property/object_spec.rb +106 -0
- data/spec/public/property_spec.rb +18 -14
- data/spec/public/resource_spec.rb +10 -1
- data/spec/public/sel_spec.rb +16 -49
- data/spec/public/setup_spec.rb +1 -1
- data/spec/public/shared/association_collection_shared_spec.rb +6 -14
- data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
- data/spec/public/shared/collection_shared_spec.rb +214 -217
- data/spec/public/shared/finder_shared_spec.rb +259 -365
- data/spec/public/shared/resource_shared_spec.rb +524 -248
- data/spec/public/transaction_spec.rb +27 -3
- data/spec/public/types/discriminator_spec.rb +1 -1
- data/spec/rcov.opts +6 -0
- data/spec/semipublic/adapters/sqlserver_adapter_spec.rb +17 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +3 -20
- data/spec/semipublic/associations_spec.rb +2 -2
- data/spec/semipublic/collection_spec.rb +0 -32
- data/spec/semipublic/model_spec.rb +96 -0
- data/spec/semipublic/property_spec.rb +3 -3
- data/spec/semipublic/query/conditions/comparison_spec.rb +1719 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1292 -0
- data/spec/semipublic/query_spec.rb +1285 -144
- data/spec/semipublic/resource_spec.rb +0 -24
- data/spec/semipublic/shared/resource_shared_spec.rb +103 -38
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +15 -6
- data/tasks/ci.rake +1 -0
- data/tasks/metrics.rake +37 -0
- data/tasks/spec.rake +41 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +99 -29
- data/CONTRIBUTING +0 -51
- data/FAQ +0 -93
- data/History.txt +0 -27
- data/MIT-LICENSE +0 -22
- data/Manifest.txt +0 -121
- data/QUICKLINKS +0 -11
- data/SPECS +0 -35
- data/TODO +0 -1
- data/spec/semipublic/query/conditions_spec.rb +0 -528
- data/tasks/ci.rb +0 -24
- data/tasks/dm.rb +0 -58
- data/tasks/doc.rb +0 -17
- data/tasks/gemspec.rb +0 -23
- data/tasks/hoe.rb +0 -45
- data/tasks/install.rb +0 -18
data/spec/public/model_spec.rb
CHANGED
@@ -7,13 +7,13 @@ describe DataMapper::Model do
|
|
7
7
|
class Article
|
8
8
|
include DataMapper::Resource
|
9
9
|
|
10
|
-
property :id,
|
11
|
-
property :title,
|
12
|
-
property :content,
|
10
|
+
property :id, Serial
|
11
|
+
property :title, String, :required => true
|
12
|
+
property :content, Text, :writer => :private, :default => lambda { |resource, property| resource.title }
|
13
13
|
property :subtitle, String
|
14
|
-
property :author,
|
14
|
+
property :author, String, :required => true
|
15
15
|
|
16
|
-
belongs_to :original, self, :
|
16
|
+
belongs_to :original, self, :required => false
|
17
17
|
has n, :revisions, self, :child_key => [ :original_id ]
|
18
18
|
has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
|
19
19
|
end
|
@@ -26,9 +26,9 @@ describe DataMapper::Model do
|
|
26
26
|
before :all do
|
27
27
|
@author = 'Dan Kubb'
|
28
28
|
|
29
|
-
@original = @article_model.create(:title => 'Original Article',
|
30
|
-
@article = @article_model.create(:title => 'Sample Article', :
|
31
|
-
@other = @article_model.create(:title => 'Other Article',
|
29
|
+
@original = @article_model.create(:title => 'Original Article', :author => @author)
|
30
|
+
@article = @article_model.create(:title => 'Sample Article', :original => @original, :author => @author)
|
31
|
+
@other = @article_model.create(:title => 'Other Article', :author => @author)
|
32
32
|
end
|
33
33
|
|
34
34
|
it { @article_model.should respond_to(:copy) }
|
@@ -40,8 +40,8 @@ describe DataMapper::Model do
|
|
40
40
|
@return = @resources = @article_model.copy(@repository.name, @alternate_adapter.name)
|
41
41
|
end
|
42
42
|
|
43
|
-
it 'should return
|
44
|
-
@return.should be_a_kind_of(
|
43
|
+
it 'should return a Collection' do
|
44
|
+
@return.should be_a_kind_of(DataMapper::Collection)
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'should return Resources' do
|
@@ -84,8 +84,8 @@ describe DataMapper::Model do
|
|
84
84
|
@return = @resources = @article_model.copy(@alternate_adapter.name, :default)
|
85
85
|
end
|
86
86
|
|
87
|
-
it 'should return
|
88
|
-
@return.should be_a_kind_of(
|
87
|
+
it 'should return a Collection' do
|
88
|
+
@return.should be_a_kind_of(DataMapper::Collection)
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'should return Resources' do
|
@@ -120,7 +120,7 @@ describe DataMapper::Model do
|
|
120
120
|
property :content, Text
|
121
121
|
property :subtitle, String
|
122
122
|
|
123
|
-
belongs_to :original, self, :
|
123
|
+
belongs_to :original, self, :required => false
|
124
124
|
has n, :revisions, self, :child_key => [ :original_id ]
|
125
125
|
has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
|
126
126
|
has n, :publications, :through => Resource
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe DataMapper::Property, 'Object type' do
|
4
|
+
before :all do
|
5
|
+
module ::Blog
|
6
|
+
class Article
|
7
|
+
include DataMapper::Resource
|
8
|
+
|
9
|
+
property :id, Serial
|
10
|
+
property :title, String
|
11
|
+
property :meta, Object, :required => true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
@model = Blog::Article
|
16
|
+
@property = @model.properties[:meta]
|
17
|
+
end
|
18
|
+
|
19
|
+
subject { @property }
|
20
|
+
|
21
|
+
it { should respond_to(:typecast) }
|
22
|
+
|
23
|
+
describe '#typecast' do
|
24
|
+
before do
|
25
|
+
@value = { 'lang' => 'en_CA' }
|
26
|
+
end
|
27
|
+
|
28
|
+
subject { @property.typecast(@value) }
|
29
|
+
|
30
|
+
it { should equal(@value) }
|
31
|
+
end
|
32
|
+
|
33
|
+
it { should respond_to(:value) }
|
34
|
+
|
35
|
+
describe '#value' do
|
36
|
+
describe 'with a value' do
|
37
|
+
before do
|
38
|
+
@value = { 'lang' => 'en_CA' }
|
39
|
+
end
|
40
|
+
|
41
|
+
subject { @property.value(@value) }
|
42
|
+
|
43
|
+
it { @property.type.load(subject, @property).should == @value }
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'with nil' do
|
47
|
+
subject { @property.value(nil) }
|
48
|
+
|
49
|
+
it { should be_nil }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it { should respond_to(:valid?) }
|
54
|
+
|
55
|
+
describe '#valid?' do
|
56
|
+
describe 'with a valid primitive' do
|
57
|
+
subject { @property.valid?('lang' => 'en_CA') }
|
58
|
+
|
59
|
+
it { should be_true }
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'with nil and property is not required' do
|
63
|
+
before do
|
64
|
+
@property = @model.property(:meta, Object, :required => false)
|
65
|
+
end
|
66
|
+
|
67
|
+
subject { @property.valid?(nil) }
|
68
|
+
|
69
|
+
it { should be_true }
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'with nil and property is required' do
|
73
|
+
subject { @property.valid?(nil) }
|
74
|
+
|
75
|
+
it { should be_false }
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'with nil and property is required, but validity is negated' do
|
79
|
+
subject { @property.valid?(nil, true) }
|
80
|
+
|
81
|
+
it { should be_true }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'persistable' do
|
86
|
+
supported_by :all do
|
87
|
+
before :all do
|
88
|
+
@do_adapter = defined?(DataMapper::Adapters::DataObjectsAdapter) && @adapter.kind_of?(DataMapper::Adapters::DataObjectsAdapter)
|
89
|
+
end
|
90
|
+
|
91
|
+
before :all do
|
92
|
+
@resource = @model.create(:title => 'Test', :meta => { 'lang' => 'en_CA' })
|
93
|
+
end
|
94
|
+
|
95
|
+
subject { @resource.reload.meta }
|
96
|
+
|
97
|
+
it 'should load the correct value' do
|
98
|
+
pending_if 'Fix adapters to use different serialization methods', !@do_adapter do
|
99
|
+
pending_if 'Fix DO adapter to send String for Text primitive', !!(RUBY_PLATFORM =~ /java/) do
|
100
|
+
should == { 'lang' => 'en_CA' }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -20,7 +20,7 @@ describe DataMapper::Property do
|
|
20
20
|
include DataMapper::Resource
|
21
21
|
|
22
22
|
property :md5hash, String, :key => true, :length => 32
|
23
|
-
property :title, String, :
|
23
|
+
property :title, String, :required => true, :unique => true
|
24
24
|
property :description, Text, :length => 1..1024, :lazy => [ :detail ]
|
25
25
|
property :format, String, :default => 'jpeg'
|
26
26
|
property :taken_at, Time, :default => proc { Time.now }
|
@@ -255,13 +255,13 @@ describe DataMapper::Property do
|
|
255
255
|
end
|
256
256
|
end
|
257
257
|
|
258
|
-
describe '#
|
258
|
+
describe '#allow_nil?' do
|
259
259
|
it 'returns true when property can accept nil as its value' do
|
260
|
-
Track.properties[:artist].
|
260
|
+
Track.properties[:artist].allow_nil?.should be_true
|
261
261
|
end
|
262
262
|
|
263
263
|
it 'returns false when property nil value is prohibited for this property' do
|
264
|
-
Image.properties[:title].
|
264
|
+
Image.properties[:title].allow_nil?.should be_false
|
265
265
|
end
|
266
266
|
end
|
267
267
|
|
@@ -282,16 +282,18 @@ describe DataMapper::Property do
|
|
282
282
|
# (since original value is set, property is no longer dirty)
|
283
283
|
describe '#set_original_value' do
|
284
284
|
before :all do
|
285
|
-
@image = Image.create(
|
286
|
-
|
287
|
-
|
288
|
-
|
285
|
+
@image = Image.create(
|
286
|
+
:md5hash => '5268f0f3f452844c79843e820f998869',
|
287
|
+
:title => 'Rome at the sunset',
|
288
|
+
:description => 'Just wow'
|
289
|
+
)
|
290
|
+
|
289
291
|
@property = Image.properties[:title]
|
290
292
|
end
|
291
293
|
|
292
294
|
describe 'when value changes' do
|
293
295
|
before :all do
|
294
|
-
@property.set_original_value(@image, '
|
296
|
+
@property.set_original_value(@image, 'New title')
|
295
297
|
end
|
296
298
|
|
297
299
|
it 'sets original value of the property' do
|
@@ -306,7 +308,7 @@ describe DataMapper::Property do
|
|
306
308
|
|
307
309
|
it 'only sets original value when it has changed' do
|
308
310
|
@property.set_original_value(@image, 'Rome at the sunset')
|
309
|
-
@image.original_attributes
|
311
|
+
@image.original_attributes.should_not have_key(@property)
|
310
312
|
end
|
311
313
|
end
|
312
314
|
end
|
@@ -315,10 +317,12 @@ describe DataMapper::Property do
|
|
315
317
|
before :all do
|
316
318
|
# keep in mind we must run these examples with a
|
317
319
|
# saved model instance
|
318
|
-
@image = Image.create(
|
319
|
-
|
320
|
-
|
321
|
-
|
320
|
+
@image = Image.create(
|
321
|
+
:md5hash => '5268f0f3f452844c79843e820f998869',
|
322
|
+
:title => 'Rome at the sunset',
|
323
|
+
:description => 'Just wow'
|
324
|
+
)
|
325
|
+
|
322
326
|
@property = Image.properties[:title]
|
323
327
|
end
|
324
328
|
|
@@ -12,7 +12,10 @@ describe DataMapper::Resource do
|
|
12
12
|
property :description, Text
|
13
13
|
property :admin, Boolean, :accessor => :private
|
14
14
|
|
15
|
-
belongs_to :
|
15
|
+
belongs_to :parent, self, :required => false
|
16
|
+
has n, :children, self, :inverse => :parent
|
17
|
+
|
18
|
+
belongs_to :referrer, self, :required => false
|
16
19
|
has n, :comments
|
17
20
|
|
18
21
|
# FIXME: figure out a different approach than stubbing things out
|
@@ -51,6 +54,12 @@ describe DataMapper::Resource do
|
|
51
54
|
end
|
52
55
|
end
|
53
56
|
|
57
|
+
class ::Default
|
58
|
+
include DataMapper::Resource
|
59
|
+
|
60
|
+
property :name, String, :key => true, :default => 'a default value'
|
61
|
+
end
|
62
|
+
|
54
63
|
@user_model = Blog::User
|
55
64
|
@author_model = Blog::Author
|
56
65
|
@comment_model = Blog::Comment
|
data/spec/public/sel_spec.rb
CHANGED
@@ -1,48 +1,5 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
-
describe 'SEL', 'with different key types' do
|
4
|
-
before :all do
|
5
|
-
module ::Blog
|
6
|
-
class Author
|
7
|
-
include DataMapper::Resource
|
8
|
-
|
9
|
-
property :id, Serial
|
10
|
-
property :name, String
|
11
|
-
|
12
|
-
has n, :articles
|
13
|
-
end
|
14
|
-
|
15
|
-
class Article
|
16
|
-
include DataMapper::Resource
|
17
|
-
|
18
|
-
property :id, Serial
|
19
|
-
property :title, String, :nullable => false
|
20
|
-
|
21
|
-
property :author_id, String # different type
|
22
|
-
|
23
|
-
belongs_to :author
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
@author_model = Blog::Author
|
28
|
-
@article_model = Blog::Article
|
29
|
-
end
|
30
|
-
|
31
|
-
supported_by :all do
|
32
|
-
before :all do
|
33
|
-
@author1 = @author_model.create(:name => 'Dan Kubb')
|
34
|
-
@author2 = @author_model.create(:name => 'Carl Porth')
|
35
|
-
|
36
|
-
@article1 = @author1.articles.create(:title => 'Sample Article')
|
37
|
-
@article2 = @author2.articles.create(:title => 'Other Article')
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'should return expected results' do
|
41
|
-
@article_model.all.map { |article| article.author }.should == [ @author1, @author2 ]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
3
|
describe 'SEL', 'with STI subclasses' do
|
47
4
|
before :all do
|
48
5
|
module ::Blog
|
@@ -60,7 +17,7 @@ describe 'SEL', 'with STI subclasses' do
|
|
60
17
|
|
61
18
|
property :id, Serial
|
62
19
|
property :type, Discriminator
|
63
|
-
property :title, String, :
|
20
|
+
property :title, String, :required => true
|
64
21
|
|
65
22
|
belongs_to :author
|
66
23
|
end
|
@@ -77,12 +34,22 @@ describe 'SEL', 'with STI subclasses' do
|
|
77
34
|
|
78
35
|
supported_by :all do
|
79
36
|
before :all do
|
80
|
-
|
81
|
-
|
37
|
+
@skip = defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
|
38
|
+
end
|
39
|
+
|
40
|
+
before :all do
|
41
|
+
rescue_if 'TODO: fix YAML serialization/deserialization', @skip do
|
42
|
+
author1 = @author_model.create(:name => 'Dan Kubb')
|
43
|
+
author2 = @author_model.create(:name => 'Sindre Aarsaether')
|
44
|
+
|
45
|
+
@article_model.create(:title => 'SEL', :author => author1)
|
46
|
+
@article_model.create(:title => 'STI', :author => author1)
|
47
|
+
@comment_model.create(:title => 'SEL and STI error', :author => author2)
|
48
|
+
end
|
49
|
+
end
|
82
50
|
|
83
|
-
|
84
|
-
|
85
|
-
@comment_model.create(:title => 'SEL and STI error', :author => author2)
|
51
|
+
before do
|
52
|
+
pending if @skip
|
86
53
|
end
|
87
54
|
|
88
55
|
it 'should allow STI loading of mixed relationships' do
|
data/spec/public/setup_spec.rb
CHANGED
@@ -114,7 +114,7 @@ describe DataMapper do
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
supported_by :postgres, :mysql, :sqlite3 do
|
117
|
+
supported_by :postgres, :mysql, :sqlite3, :sqlserver do
|
118
118
|
{ :path => :database, :user => :username }.each do |original_key, new_key|
|
119
119
|
describe "using #{new_key.inspect} option" do
|
120
120
|
before :all do
|
@@ -22,10 +22,6 @@ share_examples_for 'It can transfer a Resource from another association' do
|
|
22
22
|
pending if @skip
|
23
23
|
end
|
24
24
|
|
25
|
-
it 'should relate the Resource to the Collection' do
|
26
|
-
@resource.collection.should equal(@articles)
|
27
|
-
end
|
28
|
-
|
29
25
|
it 'should remove the Resource from the original Collection' do
|
30
26
|
pending do
|
31
27
|
@original.should_not be_include(@resource)
|
@@ -64,7 +60,7 @@ share_examples_for 'A public Association Collection' do
|
|
64
60
|
@original = @other_articles
|
65
61
|
@resource = @original.first
|
66
62
|
|
67
|
-
rescue_if
|
63
|
+
rescue_if @skip do
|
68
64
|
@return = @articles << @resource
|
69
65
|
end
|
70
66
|
end
|
@@ -107,7 +103,7 @@ share_examples_for 'A public Association Collection' do
|
|
107
103
|
@original = @other_articles
|
108
104
|
@resource = @original.first
|
109
105
|
|
110
|
-
rescue_if
|
106
|
+
rescue_if @skip do
|
111
107
|
@return = @articles.concat([ @resource ])
|
112
108
|
end
|
113
109
|
end
|
@@ -163,7 +159,7 @@ share_examples_for 'A public Association Collection' do
|
|
163
159
|
@original = @other_articles
|
164
160
|
@resource = @original.first
|
165
161
|
|
166
|
-
rescue_if
|
162
|
+
rescue_if @skip do
|
167
163
|
@return = @articles.insert(0, @resource)
|
168
164
|
end
|
169
165
|
end
|
@@ -226,7 +222,7 @@ share_examples_for 'A public Association Collection' do
|
|
226
222
|
@original = @other_articles
|
227
223
|
@resource = @original.first
|
228
224
|
|
229
|
-
rescue_if
|
225
|
+
rescue_if @skip do
|
230
226
|
@return = @articles.push(@resource)
|
231
227
|
end
|
232
228
|
end
|
@@ -249,7 +245,7 @@ share_examples_for 'A public Association Collection' do
|
|
249
245
|
@original = @other_articles
|
250
246
|
@resource = @original.first
|
251
247
|
|
252
|
-
rescue_if
|
248
|
+
rescue_if @skip do
|
253
249
|
@return = @articles.replace([ @resource ])
|
254
250
|
end
|
255
251
|
end
|
@@ -262,10 +258,6 @@ share_examples_for 'A public Association Collection' do
|
|
262
258
|
@return.should equal(@articles)
|
263
259
|
end
|
264
260
|
|
265
|
-
it 'should relate the Resource to the Collection' do
|
266
|
-
@resource.collection.should equal(@articles)
|
267
|
-
end
|
268
|
-
|
269
261
|
it_should_behave_like 'It can transfer a Resource from another association'
|
270
262
|
end
|
271
263
|
end
|
@@ -276,7 +268,7 @@ share_examples_for 'A public Association Collection' do
|
|
276
268
|
@original = @other_articles
|
277
269
|
@resource = @original.first
|
278
270
|
|
279
|
-
rescue_if
|
271
|
+
rescue_if @skip do
|
280
272
|
@return = @articles.unshift(@resource)
|
281
273
|
end
|
282
274
|
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
share_examples_for 'Collection Finder Interface' do
|
2
|
+
before :all do
|
3
|
+
%w[ @article_model @article @other @articles ].each do |ivar|
|
4
|
+
raise "+#{ivar}+ should be defined in before block" unless instance_variable_defined?(ivar)
|
5
|
+
raise "+#{ivar}+ should not be nil in before block" unless instance_variable_get(ivar)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
before :all do
|
10
|
+
@no_join = defined?(DataMapper::Adapters::InMemoryAdapter) && @adapter.kind_of?(DataMapper::Adapters::InMemoryAdapter) ||
|
11
|
+
defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
|
12
|
+
|
13
|
+
@many_to_many = @articles.kind_of?(DataMapper::Associations::ManyToMany::Collection)
|
14
|
+
|
15
|
+
@skip = @no_join && @many_to_many
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
pending if @skip
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#at' do
|
23
|
+
before :all do
|
24
|
+
@copy = @articles.dup
|
25
|
+
@copy.to_a
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'with positive offset', 'after prepending to the collection' do
|
29
|
+
before :all do
|
30
|
+
@return = @resource = @articles.unshift(@other).at(0)
|
31
|
+
end
|
32
|
+
|
33
|
+
should_not_be_a_kicker
|
34
|
+
|
35
|
+
it 'should return a Resource' do
|
36
|
+
@return.should be_kind_of(DataMapper::Resource)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should return expected Resource' do
|
40
|
+
@resource.should equal(@other)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'with negative offset', 'after appending to the collection' do
|
45
|
+
before :all do
|
46
|
+
@return = @resource = @articles.push(@other).at(-1)
|
47
|
+
end
|
48
|
+
|
49
|
+
should_not_be_a_kicker
|
50
|
+
|
51
|
+
it 'should return a Resource' do
|
52
|
+
@return.should be_kind_of(DataMapper::Resource)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should return expected Resource' do
|
56
|
+
@resource.should equal(@other)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#first' do
|
62
|
+
before :all do
|
63
|
+
1.upto(5) { |number| @articles.create(:content => "Article #{number}") }
|
64
|
+
|
65
|
+
@copy = @articles.dup
|
66
|
+
@copy.to_a
|
67
|
+
|
68
|
+
# reload the articles
|
69
|
+
@articles = @article_model.all(@articles.query)
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'with no arguments' do
|
73
|
+
before :all do
|
74
|
+
@return = @resource = @articles.first
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should return a Resource' do
|
78
|
+
@return.should be_kind_of(DataMapper::Resource)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should be first Resource in the Collection' do
|
82
|
+
@resource.should equal(@copy.entries.first)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should return the same Resource every time' do
|
86
|
+
@return.should equal(@articles.first)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'with no arguments', 'after prepending to the collection' do
|
91
|
+
before :all do
|
92
|
+
@return = @resource = @articles.unshift(@other).first
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should return a Resource' do
|
96
|
+
@return.should be_kind_of(DataMapper::Resource)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should return expected Resource' do
|
100
|
+
@resource.should equal(@other)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should be first Resource in the Collection' do
|
104
|
+
@resource.should equal(@copy.entries.unshift(@other).first)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'with empty query', 'after prepending to the collection' do
|
109
|
+
before :all do
|
110
|
+
@return = @resource = @articles.unshift(@other).first({})
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should return a Resource' do
|
114
|
+
@return.should be_kind_of(DataMapper::Resource)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should return expected Resource' do
|
118
|
+
@resource.should equal(@other)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should be first Resource in the Collection' do
|
122
|
+
@resource.should equal(@copy.entries.unshift(@other).first)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'with a limit specified', 'after prepending to the collection' do
|
127
|
+
before :all do
|
128
|
+
@return = @resources = @articles.unshift(@other).first(1)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should return a Collection' do
|
132
|
+
@return.should be_kind_of(DataMapper::Collection)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should be the expected Collection' do
|
136
|
+
@resources.should == [ @other ]
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should be the first N Resources in the Collection' do
|
140
|
+
@resources.should == @copy.entries.unshift(@other).first(1)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
[ :get, :get! ].each do |method|
|
146
|
+
describe 'with a key to a Resource within a Collection using a limit' do
|
147
|
+
before :all do
|
148
|
+
rescue_if @skip && method == :get! do
|
149
|
+
@articles = @articles.all(:limit => 1)
|
150
|
+
|
151
|
+
@return = @resource = @articles.send(method, *@article.key)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should return a Resource' do
|
156
|
+
@return.should be_kind_of(DataMapper::Resource)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should be matching Resource in the Collection' do
|
160
|
+
@resource.should == @article
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'with a key to a Resource within a Collection using an offset' do
|
165
|
+
before :all do
|
166
|
+
rescue_if @skip && method == :get! do
|
167
|
+
@new = @articles.create(:content => 'New Article')
|
168
|
+
@articles = @articles.all(:offset => 1, :limit => 1)
|
169
|
+
|
170
|
+
@return = @resource = @articles.send(method, *@new.key)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should return a Resource' do
|
175
|
+
@return.should be_kind_of(DataMapper::Resource)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should be matching Resource in the Collection' do
|
179
|
+
@resource.should equal(@new)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#last' do
|
185
|
+
before :all do
|
186
|
+
1.upto(5) { |number| @articles.create(:content => "Article #{number}") }
|
187
|
+
|
188
|
+
@copy = @articles.dup
|
189
|
+
@copy.to_a
|
190
|
+
|
191
|
+
# reload the articles
|
192
|
+
@articles = @article_model.all(@articles.query)
|
193
|
+
end
|
194
|
+
|
195
|
+
describe 'with no arguments' do
|
196
|
+
before :all do
|
197
|
+
@return = @resource = @articles.last
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should return a Resource' do
|
201
|
+
@return.should be_kind_of(DataMapper::Resource)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should be last Resource in the Collection' do
|
205
|
+
@resource.should equal(@copy.entries.last)
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'should return the same Resource every time' do
|
209
|
+
@return.should equal(@articles.last)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe 'with no arguments', 'after appending to the collection' do
|
214
|
+
before :all do
|
215
|
+
@return = @resource = @articles.push(@other).last
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should return a Resource' do
|
219
|
+
@return.should be_kind_of(DataMapper::Resource)
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'should return expected Resource' do
|
223
|
+
@resource.should equal(@other)
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'should be last Resource in the Collection' do
|
227
|
+
@resource.should equal(@copy.entries.push(@other).last)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe 'with empty query', 'after appending to the collection' do
|
232
|
+
before :all do
|
233
|
+
@return = @resource = @articles.push(@other).last({})
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'should return a Resource' do
|
237
|
+
@return.should be_kind_of(DataMapper::Resource)
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'should return expected Resource' do
|
241
|
+
@resource.should equal(@other)
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should be last Resource in the Collection' do
|
245
|
+
@resource.should equal(@copy.entries.push(@other).last)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe 'with a limit specified', 'after appending to the collection' do
|
250
|
+
before :all do
|
251
|
+
@return = @resources = @articles.push(@other).last(1)
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should return a Collection' do
|
255
|
+
@return.should be_kind_of(DataMapper::Collection)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'should be the expected Collection' do
|
259
|
+
@resources.should == [ @other ]
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'should be the last N Resources in the Collection' do
|
263
|
+
@resources.should == @copy.entries.push(@other).last(1)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|