dm-core 0.9.2 → 0.9.3
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/.autotest +26 -0
- data/{CHANGELOG → History.txt} +78 -77
- data/Manifest.txt +123 -0
- data/{README → README.txt} +0 -0
- data/Rakefile +29 -0
- data/SPECS +63 -0
- data/TODO +1 -0
- data/lib/dm-core.rb +6 -1
- data/lib/dm-core/adapters/data_objects_adapter.rb +29 -32
- data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
- data/lib/dm-core/adapters/postgres_adapter.rb +1 -1
- data/lib/dm-core/adapters/sqlite3_adapter.rb +2 -2
- data/lib/dm-core/associations.rb +26 -0
- data/lib/dm-core/associations/many_to_many.rb +34 -25
- data/lib/dm-core/associations/many_to_one.rb +4 -4
- data/lib/dm-core/associations/one_to_many.rb +48 -13
- data/lib/dm-core/associations/one_to_one.rb +4 -4
- data/lib/dm-core/associations/relationship.rb +144 -42
- data/lib/dm-core/associations/relationship_chain.rb +31 -24
- data/lib/dm-core/auto_migrations.rb +0 -4
- data/lib/dm-core/collection.rb +40 -7
- data/lib/dm-core/dependency_queue.rb +31 -0
- data/lib/dm-core/hook.rb +2 -2
- data/lib/dm-core/is.rb +2 -2
- data/lib/dm-core/logger.rb +10 -10
- data/lib/dm-core/model.rb +94 -41
- data/lib/dm-core/property.rb +72 -41
- data/lib/dm-core/property_set.rb +8 -14
- data/lib/dm-core/query.rb +34 -9
- data/lib/dm-core/repository.rb +0 -0
- data/lib/dm-core/resource.rb +13 -13
- data/lib/dm-core/scope.rb +25 -2
- data/lib/dm-core/type.rb +3 -3
- data/lib/dm-core/types/discriminator.rb +10 -8
- data/lib/dm-core/types/object.rb +4 -0
- data/lib/dm-core/types/paranoid_boolean.rb +15 -4
- data/lib/dm-core/types/paranoid_datetime.rb +15 -4
- data/lib/dm-core/version.rb +3 -0
- data/script/all +5 -0
- data/script/performance.rb +191 -0
- data/script/profile.rb +86 -0
- data/spec/integration/association_spec.rb +288 -204
- data/spec/integration/association_through_spec.rb +9 -3
- data/spec/integration/associations/many_to_many_spec.rb +97 -31
- data/spec/integration/associations/many_to_one_spec.rb +41 -6
- data/spec/integration/associations/one_to_many_spec.rb +18 -2
- data/spec/integration/auto_migrations_spec.rb +0 -0
- data/spec/integration/collection_spec.rb +89 -42
- data/spec/integration/dependency_queue_spec.rb +58 -0
- data/spec/integration/model_spec.rb +67 -8
- data/spec/integration/postgres_adapter_spec.rb +19 -20
- data/spec/integration/property_spec.rb +17 -8
- data/spec/integration/query_spec.rb +273 -191
- data/spec/integration/resource_spec.rb +108 -10
- data/spec/integration/strategic_eager_loading_spec.rb +138 -0
- data/spec/integration/transaction_spec.rb +3 -3
- data/spec/integration/type_spec.rb +121 -0
- data/spec/lib/logging_helper.rb +18 -0
- data/spec/lib/model_loader.rb +91 -0
- data/spec/lib/publicize_methods.rb +28 -0
- data/spec/models/vehicles.rb +34 -0
- data/spec/models/zoo.rb +48 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +25 -62
- data/spec/unit/adapters/data_objects_adapter_spec.rb +1 -0
- data/spec/unit/associations/many_to_many_spec.rb +3 -0
- data/spec/unit/associations/many_to_one_spec.rb +9 -1
- data/spec/unit/associations/one_to_many_spec.rb +12 -4
- data/spec/unit/associations/relationship_spec.rb +19 -15
- data/spec/unit/associations_spec.rb +37 -0
- data/spec/unit/collection_spec.rb +8 -0
- data/spec/unit/data_mapper_spec.rb +14 -0
- data/spec/unit/model_spec.rb +2 -2
- data/spec/unit/property_set_spec.rb +0 -13
- data/spec/unit/property_spec.rb +92 -21
- data/spec/unit/query_spec.rb +49 -4
- data/spec/unit/resource_spec.rb +122 -60
- data/spec/unit/scope_spec.rb +11 -0
- data/tasks/ci.rb +68 -0
- data/tasks/dm.rb +63 -0
- data/tasks/doc.rb +20 -0
- data/tasks/hoe.rb +38 -0
- data/tasks/install.rb +20 -0
- metadata +63 -22
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe "DataMapper::DependencyQueue" do
|
4
|
+
before :each do
|
5
|
+
@q = DataMapper::DependencyQueue.new
|
6
|
+
@dependencies = @q.instance_variable_get("@dependencies")
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#initialize" do
|
10
|
+
describe "@dependencies" do
|
11
|
+
it "should be a hash after initialize" do
|
12
|
+
@dependencies.should be_a_kind_of(Hash)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should set value to [] when new key is accessed" do
|
16
|
+
@dependencies['New Key'].should == []
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#add" do
|
22
|
+
it "should store the supplied callback in @dependencies" do
|
23
|
+
@q.add('MissingConstant') { true }
|
24
|
+
@dependencies['MissingConstant'].first.call.should == true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#resolve!" do
|
29
|
+
describe "(when dependency is not defined)" do
|
30
|
+
it "should not alter @dependencies" do
|
31
|
+
@q.add('MissingConstant') { true }
|
32
|
+
old_dependencies = @dependencies.dup
|
33
|
+
@q.resolve!
|
34
|
+
old_dependencies.should == @dependencies
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "(when dependency is defined)" do
|
39
|
+
before :each do
|
40
|
+
@q.add('MissingConstant') { |klass| klass.instance_variable_set("@resolved", true) } # add before MissingConstant is loaded
|
41
|
+
|
42
|
+
class MissingConstant
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should execute stored callbacks" do
|
47
|
+
@q.resolve!
|
48
|
+
MissingConstant.instance_variable_get("@resolved").should == true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should clear @dependencies" do
|
52
|
+
@q.resolve!
|
53
|
+
@dependencies['MissingConstant'].should be_empty
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -13,6 +13,9 @@ if ADAPTER
|
|
13
13
|
property :name, String
|
14
14
|
property :type, Discriminator
|
15
15
|
end
|
16
|
+
|
17
|
+
class STIDescendant < STI
|
18
|
+
end
|
16
19
|
end
|
17
20
|
|
18
21
|
describe "DataMapper::Model with #{ADAPTER}" do
|
@@ -20,18 +23,29 @@ if ADAPTER
|
|
20
23
|
repository(ADAPTER) do
|
21
24
|
ModelSpec::STI.auto_migrate!
|
22
25
|
end
|
23
|
-
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
27
|
+
@planet = DataMapper::Model.new('planet') do
|
28
|
+
def self.default_repository_name; ADAPTER end
|
29
|
+
property :name, String, :key => true
|
30
|
+
property :distance, Integer
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
+
@moon = DataMapper::Model.new('moon') do
|
34
|
+
def self.default_repository_name; ADAPTER end
|
35
|
+
property :id, DM::Serial
|
36
|
+
property :name, String
|
33
37
|
end
|
34
38
|
|
39
|
+
@planet.auto_migrate!(ADAPTER)
|
40
|
+
@moon.auto_migrate!(ADAPTER)
|
41
|
+
|
42
|
+
repository(ADAPTER) do
|
43
|
+
@moon.create(:name => "Charon")
|
44
|
+
@moon.create(:name => "Phobos")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '.new' do
|
35
49
|
it 'should be able to persist' do
|
36
50
|
repository(ADAPTER) do
|
37
51
|
pluto = @planet.new
|
@@ -46,6 +60,51 @@ if ADAPTER
|
|
46
60
|
end
|
47
61
|
end
|
48
62
|
|
63
|
+
describe ".get" do
|
64
|
+
include LoggingHelper
|
65
|
+
|
66
|
+
it "should typecast key" do
|
67
|
+
resource = nil
|
68
|
+
lambda {
|
69
|
+
repository(ADAPTER) do
|
70
|
+
resource = @moon.get("1")
|
71
|
+
end
|
72
|
+
}.should_not raise_error
|
73
|
+
resource.should be_kind_of(DataMapper::Resource)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should use the identity map within a repository block" do
|
77
|
+
logger do |log|
|
78
|
+
repository(ADAPTER) do
|
79
|
+
@moon.get("1")
|
80
|
+
@moon.get(1)
|
81
|
+
end
|
82
|
+
log.readlines.size.should == 1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should not use the identity map outside a repository block" do
|
87
|
+
logger do |log|
|
88
|
+
@moon.get(1)
|
89
|
+
@moon.get(1)
|
90
|
+
log.readlines.size.should == 2
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe ".base_model" do
|
96
|
+
describe "(when called on base model)" do
|
97
|
+
it "should refer to itself" do
|
98
|
+
ModelSpec::STI.base_model.should == ModelSpec::STI
|
99
|
+
end
|
100
|
+
end
|
101
|
+
describe "(when called on descendant model)" do
|
102
|
+
it "should refer to the base model" do
|
103
|
+
ModelSpec::STIDescendant.base_model.should == ModelSpec::STI.base_model
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
49
108
|
it 'should provide #load' do
|
50
109
|
ModelSpec::STI.should respond_to(:load)
|
51
110
|
end
|
@@ -146,7 +146,7 @@ if HAS_POSTGRES
|
|
146
146
|
pending "This works, but no create-schema support in PostgresAdapter to easily test with"
|
147
147
|
lambda do
|
148
148
|
repository(:postgres) do
|
149
|
-
Voyager.create
|
149
|
+
Voyager.create(:age => 1_000)
|
150
150
|
end
|
151
151
|
end.should_not raise_error
|
152
152
|
end
|
@@ -388,9 +388,9 @@ if HAS_POSTGRES
|
|
388
388
|
SailBoat.auto_migrate!(:postgres)
|
389
389
|
|
390
390
|
repository(:postgres) do
|
391
|
-
SailBoat.create
|
392
|
-
SailBoat.create
|
393
|
-
SailBoat.create
|
391
|
+
SailBoat.create(:id => 1, :name => "A", :port => "C")
|
392
|
+
SailBoat.create(:id => 2, :name => "B", :port => "B")
|
393
|
+
SailBoat.create(:id => 3, :name => "C", :port => "A")
|
394
394
|
end
|
395
395
|
end
|
396
396
|
|
@@ -436,9 +436,9 @@ if HAS_POSTGRES
|
|
436
436
|
SailBoat.auto_migrate!(:postgres)
|
437
437
|
|
438
438
|
repository(:postgres) do
|
439
|
-
SailBoat.create
|
440
|
-
SailBoat.create
|
441
|
-
SailBoat.create
|
439
|
+
SailBoat.create(:id => 1, :notes=>'Note',:trip_report=>'Report',:miles=>23)
|
440
|
+
SailBoat.create(:id => 2, :notes=>'Note',:trip_report=>'Report',:miles=>23)
|
441
|
+
SailBoat.create(:id => 3, :notes=>'Note',:trip_report=>'Report',:miles=>23)
|
442
442
|
end
|
443
443
|
end
|
444
444
|
|
@@ -480,7 +480,7 @@ if HAS_POSTGRES
|
|
480
480
|
|
481
481
|
repository(:postgres) do
|
482
482
|
100.times do
|
483
|
-
SerialFinderSpec.create
|
483
|
+
SerialFinderSpec.create(:sample => rand.to_s)
|
484
484
|
end
|
485
485
|
end
|
486
486
|
end
|
@@ -507,8 +507,9 @@ if HAS_POSTGRES
|
|
507
507
|
sfs.should be_a_kind_of(SerialFinderSpec)
|
508
508
|
sfs.should_not be_a_new_record
|
509
509
|
|
510
|
-
sfs.
|
511
|
-
sfs.sample
|
510
|
+
sfs.attribute_loaded?(:sample).should be_false
|
511
|
+
sfs.sample
|
512
|
+
sfs.attribute_loaded?(:sample).should be_true
|
512
513
|
end
|
513
514
|
|
514
515
|
it "should translate an Array to an IN clause" do
|
@@ -529,6 +530,7 @@ if HAS_POSTGRES
|
|
529
530
|
before :all do
|
530
531
|
class Engine
|
531
532
|
include DataMapper::Resource
|
533
|
+
def self.default_repository_name; :postgres end
|
532
534
|
|
533
535
|
property :id, Serial
|
534
536
|
property :name, String
|
@@ -536,14 +538,13 @@ if HAS_POSTGRES
|
|
536
538
|
|
537
539
|
class Yard
|
538
540
|
include DataMapper::Resource
|
541
|
+
def self.default_repository_name; :postgres end
|
539
542
|
|
540
543
|
property :id, Serial
|
541
544
|
property :name, String
|
542
545
|
property :engine_id, Integer
|
543
546
|
|
544
|
-
|
545
|
-
belongs_to :engine
|
546
|
-
end
|
547
|
+
belongs_to :engine
|
547
548
|
end
|
548
549
|
end
|
549
550
|
|
@@ -591,7 +592,7 @@ if HAS_POSTGRES
|
|
591
592
|
it 'should save the association key in the child' do
|
592
593
|
repository(:postgres) do
|
593
594
|
e = Engine.first(:id => 2)
|
594
|
-
Yard.create
|
595
|
+
Yard.create(:id => 2, :name => 'yard2', :engine => e)
|
595
596
|
end
|
596
597
|
|
597
598
|
repository(:postgres) do
|
@@ -618,25 +619,23 @@ if HAS_POSTGRES
|
|
618
619
|
before :all do
|
619
620
|
class Host
|
620
621
|
include DataMapper::Resource
|
622
|
+
def self.default_repository_name; :postgres end
|
621
623
|
|
622
624
|
property :id, Serial
|
623
625
|
property :name, String
|
624
626
|
|
625
|
-
|
626
|
-
has n, :slices
|
627
|
-
end
|
627
|
+
has n, :slices
|
628
628
|
end
|
629
629
|
|
630
630
|
class Slice
|
631
631
|
include DataMapper::Resource
|
632
|
+
def self.default_repository_name; :postgres end
|
632
633
|
|
633
634
|
property :id, Serial
|
634
635
|
property :name, String
|
635
636
|
property :host_id, Integer
|
636
637
|
|
637
|
-
|
638
|
-
belongs_to :host
|
639
|
-
end
|
638
|
+
belongs_to :host
|
640
639
|
end
|
641
640
|
end
|
642
641
|
|
@@ -13,7 +13,7 @@ if ADAPTER
|
|
13
13
|
property :id, Serial
|
14
14
|
property :name, String, :track => :set # :track default is :get for mutable types
|
15
15
|
property :notes, DataMapper::Types::Text
|
16
|
-
property :age, Integer # :track default is :set for
|
16
|
+
property :age, Integer # :track default is :set for immutable types
|
17
17
|
property :rating, Integer
|
18
18
|
property :location, String
|
19
19
|
property :lead, TrueClass, :track => :load
|
@@ -78,7 +78,7 @@ if ADAPTER
|
|
78
78
|
|
79
79
|
it "should track on :load" do
|
80
80
|
repository(ADAPTER) do
|
81
|
-
jan = Actor.create
|
81
|
+
jan = Actor.create(:name => 'jan', :lead => true)
|
82
82
|
jan.lead = false
|
83
83
|
jan.original_values[:lead].should be_true
|
84
84
|
jan.dirty?.should == true
|
@@ -94,7 +94,7 @@ if ADAPTER
|
|
94
94
|
it "should track on :hash" do
|
95
95
|
cv = { 2005 => "Othello" }
|
96
96
|
repository(ADAPTER) do
|
97
|
-
tom = Actor.create
|
97
|
+
tom = Actor.create(:name => 'tom', :cv => cv)
|
98
98
|
end
|
99
99
|
repository(ADAPTER) do
|
100
100
|
tom = Actor.first(:name => 'tom')
|
@@ -109,7 +109,7 @@ if ADAPTER
|
|
109
109
|
|
110
110
|
it "should track with lazy text fields (#342)" do
|
111
111
|
repository(ADAPTER) do
|
112
|
-
tim = Actor.create
|
112
|
+
tim = Actor.create(:name => 'tim')
|
113
113
|
end
|
114
114
|
repository(ADAPTER) do
|
115
115
|
tim = Actor.first(:name => 'tim')
|
@@ -142,9 +142,9 @@ if ADAPTER
|
|
142
142
|
RowBoat.auto_migrate!(ADAPTER)
|
143
143
|
|
144
144
|
repository(ADAPTER) do
|
145
|
-
RowBoat.create
|
146
|
-
RowBoat.create
|
147
|
-
RowBoat.create
|
145
|
+
RowBoat.create(:id => 1, :notes=>'Note',:trip_report=>'Report',:miles=>23)
|
146
|
+
RowBoat.create(:id => 2, :notes=>'Note',:trip_report=>'Report',:miles=>23)
|
147
|
+
RowBoat.create(:id => 3, :notes=>'Note',:trip_report=>'Report',:miles=>23)
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
@@ -169,6 +169,15 @@ if ADAPTER
|
|
169
169
|
result[1].trip_report.should_not be_nil
|
170
170
|
result[2].attribute_loaded?(:miles).should be_true
|
171
171
|
end
|
172
|
+
|
173
|
+
it "should lazy load on Property#set" do
|
174
|
+
repository(ADAPTER) do
|
175
|
+
boat = RowBoat.first
|
176
|
+
boat.attribute_loaded?(:notes).should be_false
|
177
|
+
boat.notes = 'New Note'
|
178
|
+
boat.original_values[:notes].should == "Note"
|
179
|
+
end
|
180
|
+
end
|
172
181
|
end
|
173
182
|
|
174
183
|
describe 'defaults' do
|
@@ -211,7 +220,7 @@ if ADAPTER
|
|
211
220
|
|
212
221
|
it "should have defaults even with creates" do
|
213
222
|
repository(ADAPTER) do
|
214
|
-
Catamaran.create
|
223
|
+
Catamaran.create(:name => 'Jingle All The Way')
|
215
224
|
cat = Catamaran.first
|
216
225
|
cat.name.should == 'Jingle All The Way'
|
217
226
|
cat.could_be_bool0.should == true
|
@@ -1,49 +1,238 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
3
|
if ADAPTER
|
4
|
+
module QuerySpec
|
5
|
+
class SailBoat
|
6
|
+
include DataMapper::Resource
|
7
|
+
|
8
|
+
property :id, Serial
|
9
|
+
property :name, String
|
10
|
+
property :port, String
|
11
|
+
property :captain, String
|
12
|
+
|
13
|
+
def self.default_repository_name
|
14
|
+
ADAPTER
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Permission
|
19
|
+
include DataMapper::Resource
|
20
|
+
|
21
|
+
property :id, Serial
|
22
|
+
property :user_id, Integer
|
23
|
+
property :resource_id, Integer
|
24
|
+
property :resource_type, String
|
25
|
+
property :token, String
|
26
|
+
|
27
|
+
def self.default_repository_name
|
28
|
+
ADAPTER
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Region
|
33
|
+
include DataMapper::Resource
|
34
|
+
|
35
|
+
property :id, Serial
|
36
|
+
property :name, String
|
37
|
+
property :type, String
|
38
|
+
|
39
|
+
def self.default_repository_name
|
40
|
+
ADAPTER
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Factory
|
45
|
+
include DataMapper::Resource
|
46
|
+
|
47
|
+
property :id, Serial
|
48
|
+
property :region_id, Integer
|
49
|
+
property :name, String
|
50
|
+
|
51
|
+
repository(:mock) do
|
52
|
+
property :land, String
|
53
|
+
end
|
54
|
+
|
55
|
+
belongs_to :region
|
56
|
+
|
57
|
+
def self.default_repository_name
|
58
|
+
ADAPTER
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Vehicle
|
63
|
+
include DataMapper::Resource
|
64
|
+
|
65
|
+
property :id, Serial
|
66
|
+
property :factory_id, Integer
|
67
|
+
property :name, String
|
68
|
+
|
69
|
+
belongs_to :factory
|
70
|
+
|
71
|
+
def self.default_repository_name
|
72
|
+
ADAPTER
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Group
|
77
|
+
include DataMapper::Resource
|
78
|
+
property :id, Serial
|
79
|
+
property :name, String
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
module Namespace
|
84
|
+
class Region
|
85
|
+
include DataMapper::Resource
|
86
|
+
|
87
|
+
property :id, Serial
|
88
|
+
property :name, String
|
89
|
+
|
90
|
+
def self.default_repository_name
|
91
|
+
ADAPTER
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class Factory
|
96
|
+
include DataMapper::Resource
|
97
|
+
|
98
|
+
property :id, Serial
|
99
|
+
property :region_id, Integer
|
100
|
+
property :name, String
|
101
|
+
|
102
|
+
repository(:mock) do
|
103
|
+
property :land, String
|
104
|
+
end
|
105
|
+
|
106
|
+
belongs_to :region
|
107
|
+
|
108
|
+
def self.default_repository_name
|
109
|
+
ADAPTER
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class Vehicle
|
114
|
+
include DataMapper::Resource
|
115
|
+
property :id, Serial
|
116
|
+
property :factory_id, Integer
|
117
|
+
property :name, String
|
118
|
+
|
119
|
+
belongs_to :factory
|
120
|
+
|
121
|
+
def self.default_repository_name
|
122
|
+
ADAPTER
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
4
127
|
describe DataMapper::Query, "with #{ADAPTER}" do
|
5
|
-
describe '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
128
|
+
describe '#unique' do
|
129
|
+
include LoggingHelper
|
130
|
+
|
131
|
+
before do
|
132
|
+
QuerySpec::SailBoat.auto_migrate!
|
133
|
+
|
134
|
+
QuerySpec::SailBoat.create(:name => 'A', :port => 'C')
|
135
|
+
QuerySpec::SailBoat.create(:name => 'B', :port => 'B')
|
136
|
+
QuerySpec::SailBoat.create(:name => 'C', :port => 'A')
|
137
|
+
end
|
138
|
+
|
139
|
+
def parse_statement(log)
|
140
|
+
log.readlines.join.chomp.split(' ~ ').last
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'when true' do
|
144
|
+
if [ :postgres, :sqlite3, :mysql ].include?(ADAPTER)
|
145
|
+
it 'should add a GROUP BY to the SQL query' do
|
146
|
+
logger do |log|
|
147
|
+
QuerySpec::SailBoat.all(:unique => true, :fields => [ :id ]).to_a
|
148
|
+
|
149
|
+
case ADAPTER
|
150
|
+
when :postgres, :sqlite3
|
151
|
+
parse_statement(log).should == 'SELECT "id" FROM "query_spec_sail_boats" GROUP BY "id" ORDER BY "id"'
|
152
|
+
when :mysql
|
153
|
+
parse_statement(log).should == 'SELECT `id` FROM `query_spec_sail_boats` GROUP BY `id` ORDER BY `id`'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should not add a GROUP BY to the SQL query if no field is a Property' do
|
159
|
+
operator = DataMapper::Query::Operator.new(:thing, :test)
|
160
|
+
|
161
|
+
# make the operator act like a Property
|
162
|
+
class << operator
|
163
|
+
property = QuerySpec::SailBoat.properties[:id]
|
164
|
+
(property.methods - (public_instance_methods - %w[ type ])).each do |method|
|
165
|
+
define_method(method) do |*args|
|
166
|
+
property.send(method, *args)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
operator.should_not be_kind_of(DataMapper::Property)
|
172
|
+
|
173
|
+
logger do |log|
|
174
|
+
QuerySpec::SailBoat.all(:unique => true, :fields => [ operator ]).to_a
|
175
|
+
|
176
|
+
case ADAPTER
|
177
|
+
when :postgres, :sqlite3
|
178
|
+
parse_statement(log).should == 'SELECT "id" FROM "query_spec_sail_boats" ORDER BY "id"'
|
179
|
+
when :mysql
|
180
|
+
parse_statement(log).should == 'SELECT `id` FROM `query_spec_sail_boats` ORDER BY `id`'
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
12
184
|
end
|
13
185
|
end
|
14
186
|
|
187
|
+
describe 'when false' do
|
188
|
+
if [ :postgres, :sqlite3, :mysql ].include?(ADAPTER)
|
189
|
+
it 'should not add a GROUP BY to the SQL query' do
|
190
|
+
logger do |log|
|
191
|
+
QuerySpec::SailBoat.all(:unique => false, :fields => [ :id ]).to_a
|
192
|
+
|
193
|
+
case ADAPTER
|
194
|
+
when :postgres, :sqlite3
|
195
|
+
parse_statement(log).should == 'SELECT "id" FROM "query_spec_sail_boats" ORDER BY "id"'
|
196
|
+
when :mysql
|
197
|
+
parse_statement(log).should == 'SELECT `id` FROM `query_spec_sail_boats` ORDER BY `id`'
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe 'when ordering' do
|
15
206
|
before do
|
16
|
-
SailBoat.auto_migrate!
|
207
|
+
QuerySpec::SailBoat.auto_migrate!
|
17
208
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
SailBoat.create!(:name => 'C', :port => 'A')
|
22
|
-
end
|
209
|
+
QuerySpec::SailBoat.create(:name => 'A', :port => 'C')
|
210
|
+
QuerySpec::SailBoat.create(:name => 'B', :port => 'B')
|
211
|
+
QuerySpec::SailBoat.create(:name => 'C', :port => 'A')
|
23
212
|
end
|
24
213
|
|
25
214
|
it "should find by conditions" do
|
26
215
|
lambda do
|
27
216
|
repository(ADAPTER) do
|
28
|
-
SailBoat.first(:conditions => ['name = ?', 'B'])
|
217
|
+
QuerySpec::SailBoat.first(:conditions => [ 'name = ?', 'B' ])
|
29
218
|
end
|
30
219
|
end.should_not raise_error
|
31
220
|
|
32
221
|
lambda do
|
33
222
|
repository(ADAPTER) do
|
34
|
-
SailBoat.first(:conditions => ['name = ?', 'A'])
|
223
|
+
QuerySpec::SailBoat.first(:conditions => [ 'name = ?', 'A' ])
|
35
224
|
end
|
36
225
|
end.should_not raise_error
|
37
226
|
end
|
38
227
|
|
39
228
|
it "should find by conditions passed in as hash" do
|
40
229
|
repository(ADAPTER) do
|
41
|
-
SailBoat.create
|
230
|
+
QuerySpec::SailBoat.create(:name => "couldbe@email.com", :port => 'wee')
|
42
231
|
|
43
|
-
find = SailBoat.first(:name => 'couldbe@email.com')
|
232
|
+
find = QuerySpec::SailBoat.first(:name => 'couldbe@email.com')
|
44
233
|
find.name.should == 'couldbe@email.com'
|
45
234
|
|
46
|
-
find = SailBoat.first(:name => 'couldbe@email.com', :port.not => nil)
|
235
|
+
find = QuerySpec::SailBoat.first(:name => 'couldbe@email.com', :port.not => nil)
|
47
236
|
find.should_not be_nil
|
48
237
|
find.port.should_not be_nil
|
49
238
|
find.name.should == 'couldbe@email.com'
|
@@ -52,100 +241,78 @@ if ADAPTER
|
|
52
241
|
|
53
242
|
it "should find by conditions passed in a range" do
|
54
243
|
repository(ADAPTER) do
|
55
|
-
find = SailBoat.all(:id => 0..2)
|
244
|
+
find = QuerySpec::SailBoat.all(:id => 0..2)
|
56
245
|
find.should_not be_nil
|
57
246
|
find.should have(2).entries
|
58
247
|
|
59
|
-
find = SailBoat.all(:id.not => 0..2)
|
248
|
+
find = QuerySpec::SailBoat.all(:id.not => 0..2)
|
60
249
|
find.should have(1).entries
|
61
250
|
end
|
62
251
|
end
|
63
252
|
|
64
253
|
it "should order results" do
|
65
254
|
repository(ADAPTER) do
|
66
|
-
result = SailBoat.all(:order => [
|
67
|
-
DataMapper::Query::Direction.new(SailBoat.properties[:name], :asc)
|
255
|
+
result = QuerySpec::SailBoat.all(:order => [
|
256
|
+
DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:name], :asc)
|
68
257
|
])
|
69
258
|
result[0].id.should == 1
|
70
259
|
|
71
|
-
result = SailBoat.all(:order => [
|
72
|
-
DataMapper::Query::Direction.new(SailBoat.properties[:port], :asc)
|
260
|
+
result = QuerySpec::SailBoat.all(:order => [
|
261
|
+
DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:port], :asc)
|
73
262
|
])
|
74
263
|
result[0].id.should == 3
|
75
264
|
|
76
|
-
result = SailBoat.all(:order => [
|
77
|
-
DataMapper::Query::Direction.new(SailBoat.properties[:name], :asc),
|
78
|
-
DataMapper::Query::Direction.new(SailBoat.properties[:port], :asc)
|
265
|
+
result = QuerySpec::SailBoat.all(:order => [
|
266
|
+
DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:name], :asc),
|
267
|
+
DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:port], :asc)
|
79
268
|
])
|
80
269
|
result[0].id.should == 1
|
81
270
|
|
82
|
-
result = SailBoat.all(:order => [
|
83
|
-
SailBoat.properties[:name],
|
84
|
-
DataMapper::Query::Direction.new(SailBoat.properties[:port], :asc)
|
271
|
+
result = QuerySpec::SailBoat.all(:order => [
|
272
|
+
QuerySpec::SailBoat.properties[:name],
|
273
|
+
DataMapper::Query::Direction.new(QuerySpec::SailBoat.properties[:port], :asc)
|
85
274
|
])
|
86
275
|
result[0].id.should == 1
|
87
276
|
|
88
|
-
result = SailBoat.all(:order => [:name])
|
277
|
+
result = QuerySpec::SailBoat.all(:order => [ :name ])
|
89
278
|
result[0].id.should == 1
|
90
279
|
|
91
|
-
result = SailBoat.all(:order => [:name.desc])
|
280
|
+
result = QuerySpec::SailBoat.all(:order => [ :name.desc ])
|
92
281
|
result[0].id.should == 3
|
93
282
|
end
|
94
283
|
end
|
95
284
|
end
|
96
285
|
|
97
286
|
describe 'when sub-selecting' do
|
98
|
-
before :all do
|
99
|
-
class Permission
|
100
|
-
include DataMapper::Resource
|
101
|
-
property :id, Serial
|
102
|
-
property :user_id, Integer
|
103
|
-
property :resource_id, Integer
|
104
|
-
property :resource_type, String
|
105
|
-
property :token, String
|
106
|
-
end
|
107
|
-
|
108
|
-
class SailBoat
|
109
|
-
include DataMapper::Resource
|
110
|
-
property :id, Serial
|
111
|
-
property :name, String
|
112
|
-
property :port, String
|
113
|
-
property :captain, String
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
287
|
before do
|
118
|
-
Permission.auto_migrate!
|
119
|
-
SailBoat.auto_migrate!(ADAPTER)
|
288
|
+
[ QuerySpec::SailBoat, QuerySpec::Permission ].each { |m| m.auto_migrate! }
|
120
289
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
SailBoat.create!(:id => 3, :name => "Infringer III", :port => "Cape Town", :captain => 'Jason')
|
290
|
+
QuerySpec::SailBoat.create(:id => 1, :name => "Fantasy I", :port => "Cape Town", :captain => 'Joe')
|
291
|
+
QuerySpec::SailBoat.create(:id => 2, :name => "Royal Flush II", :port => "Cape Town", :captain => 'James')
|
292
|
+
QuerySpec::SailBoat.create(:id => 3, :name => "Infringer III", :port => "Cape Town", :captain => 'Jason')
|
125
293
|
|
126
|
-
|
127
|
-
|
128
|
-
|
294
|
+
#User 1 permission -- read boat 1 & 2
|
295
|
+
QuerySpec::Permission.create(:id => 1, :user_id => 1, :resource_id => 1, :resource_type => 'SailBoat', :token => 'READ')
|
296
|
+
QuerySpec::Permission.create(:id => 2, :user_id => 1, :resource_id => 2, :resource_type => 'SailBoat', :token => 'READ')
|
129
297
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end
|
298
|
+
#User 2 permission -- read boat 2 & 3
|
299
|
+
QuerySpec::Permission.create(:id => 3, :user_id => 2, :resource_id => 2, :resource_type => 'SailBoat', :token => 'READ')
|
300
|
+
QuerySpec::Permission.create(:id => 4, :user_id => 2, :resource_id => 3, :resource_type => 'SailBoat', :token => 'READ')
|
134
301
|
end
|
135
302
|
|
136
303
|
it 'should accept a DM::Query as a value of a condition' do
|
137
304
|
# User 1
|
138
|
-
acl = DataMapper::Query.new(repository(ADAPTER), Permission, :user_id => 1, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
|
305
|
+
acl = DataMapper::Query.new(repository(ADAPTER), QuerySpec::Permission, :user_id => 1, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
|
139
306
|
query = { :port => 'Cape Town', :id => acl, :captain.like => 'J%', :order => [ :id ] }
|
140
|
-
boats = repository(ADAPTER) { SailBoat.all(query) }
|
307
|
+
boats = repository(ADAPTER) { QuerySpec::SailBoat.all(query) }
|
141
308
|
boats.should have(2).entries
|
142
309
|
boats.entries[0].id.should == 1
|
143
310
|
boats.entries[1].id.should == 2
|
144
311
|
|
145
312
|
# User 2
|
146
|
-
acl = DataMapper::Query.new(repository(ADAPTER), Permission, :user_id => 2, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
|
313
|
+
acl = DataMapper::Query.new(repository(ADAPTER), QuerySpec::Permission, :user_id => 2, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
|
147
314
|
query = { :port => 'Cape Town', :id => acl, :captain.like => 'J%', :order => [ :id ] }
|
148
|
-
boats = repository(ADAPTER) { SailBoat.all(query) }
|
315
|
+
boats = repository(ADAPTER) { QuerySpec::SailBoat.all(query) }
|
149
316
|
|
150
317
|
boats.should have(2).entries
|
151
318
|
boats.entries[0].id.should == 2
|
@@ -154,130 +321,44 @@ if ADAPTER
|
|
154
321
|
|
155
322
|
it 'when value is NOT IN another query' do
|
156
323
|
# Boats that User 1 Cannot see
|
157
|
-
acl = DataMapper::Query.new(repository(ADAPTER), Permission, :user_id => 1, :resource_type => 'SailBoat', :token => 'READ', :fields => [:resource_id])
|
324
|
+
acl = DataMapper::Query.new(repository(ADAPTER), QuerySpec::Permission, :user_id => 1, :resource_type => 'SailBoat', :token => 'READ', :fields => [ :resource_id ])
|
158
325
|
query = { :port => 'Cape Town', :id.not => acl, :captain.like => 'J%' }
|
159
|
-
boats = repository(ADAPTER) { SailBoat.all(query) }
|
326
|
+
boats = repository(ADAPTER) { QuerySpec::SailBoat.all(query) }
|
160
327
|
boats.should have(1).entries
|
161
328
|
boats.entries[0].id.should == 3
|
162
329
|
end
|
163
330
|
end # describe sub-selecting
|
164
331
|
|
165
332
|
describe 'when linking associated objects' do
|
166
|
-
before :all do
|
167
|
-
class Region
|
168
|
-
include DataMapper::Resource
|
169
|
-
property :id, Serial
|
170
|
-
property :name, String
|
171
|
-
|
172
|
-
def self.default_repository_name
|
173
|
-
ADAPTER
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
class Factory
|
178
|
-
include DataMapper::Resource
|
179
|
-
property :id, Serial
|
180
|
-
property :region_id, Integer
|
181
|
-
property :name, String
|
182
|
-
|
183
|
-
repository(:mock) do
|
184
|
-
property :land, String
|
185
|
-
end
|
186
|
-
|
187
|
-
belongs_to :region
|
188
|
-
|
189
|
-
def self.default_repository_name
|
190
|
-
ADAPTER
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
class Vehicle
|
195
|
-
include DataMapper::Resource
|
196
|
-
property :id, Serial
|
197
|
-
property :factory_id, Integer
|
198
|
-
property :name, String
|
199
|
-
|
200
|
-
belongs_to :factory
|
201
|
-
|
202
|
-
def self.default_repository_name
|
203
|
-
ADAPTER
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
module Namespace
|
208
|
-
class Region
|
209
|
-
include DataMapper::Resource
|
210
|
-
property :id, Serial
|
211
|
-
property :name, String
|
212
|
-
|
213
|
-
def self.default_repository_name
|
214
|
-
ADAPTER
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
class Factory
|
219
|
-
include DataMapper::Resource
|
220
|
-
property :id, Serial
|
221
|
-
property :region_id, Integer
|
222
|
-
property :name, String
|
223
|
-
|
224
|
-
repository(:mock) do
|
225
|
-
property :land, String
|
226
|
-
end
|
227
|
-
|
228
|
-
belongs_to :region
|
229
|
-
|
230
|
-
def self.default_repository_name
|
231
|
-
ADAPTER
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
class Vehicle
|
236
|
-
include DataMapper::Resource
|
237
|
-
property :id, Serial
|
238
|
-
property :factory_id, Integer
|
239
|
-
property :name, String
|
240
|
-
|
241
|
-
belongs_to :factory
|
242
|
-
|
243
|
-
def self.default_repository_name
|
244
|
-
ADAPTER
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
333
|
before do
|
251
|
-
Region.auto_migrate!
|
252
|
-
Factory.auto_migrate!
|
253
|
-
Vehicle.auto_migrate!
|
334
|
+
[ QuerySpec::Region, QuerySpec::Factory, QuerySpec::Vehicle ].each { |m| m.auto_migrate! }
|
254
335
|
|
255
|
-
Region.
|
256
|
-
Factory.
|
257
|
-
Vehicle.
|
336
|
+
QuerySpec::Region.create(:id => 1, :name => 'North West', :type => 'commercial')
|
337
|
+
QuerySpec::Factory.create(:id => 2000, :region_id => 1, :name => 'North West Plant')
|
338
|
+
QuerySpec::Vehicle.create(:id => 1, :factory_id => 2000, :name => '10 ton delivery truck')
|
258
339
|
|
259
340
|
Namespace::Region.auto_migrate!
|
260
341
|
Namespace::Factory.auto_migrate!
|
261
342
|
Namespace::Vehicle.auto_migrate!
|
262
343
|
|
263
|
-
Namespace::Region.
|
264
|
-
Namespace::Factory.
|
265
|
-
Namespace::Vehicle.
|
344
|
+
Namespace::Region.create(:id => 1, :name => 'North West')
|
345
|
+
Namespace::Factory.create(:id => 2000, :region_id => 1, :name => 'North West Plant')
|
346
|
+
Namespace::Vehicle.create(:id => 1, :factory_id => 2000, :name => '10 ton delivery truck')
|
266
347
|
end
|
267
348
|
|
268
349
|
it 'should require that all properties in :fields and all :links come from the same repository' #do
|
269
|
-
# land = Factory.properties(:mock)[:land]
|
350
|
+
# land = QuerySpec::Factory.properties(:mock)[:land]
|
270
351
|
# fields = []
|
271
|
-
# Vehicle.properties(ADAPTER).map do |property|
|
352
|
+
# QuerySpec::Vehicle.properties(ADAPTER).map do |property|
|
272
353
|
# fields << property
|
273
354
|
# end
|
274
355
|
# fields << land
|
275
356
|
#
|
276
357
|
# lambda{
|
277
358
|
# begin
|
278
|
-
# results = repository(ADAPTER) { Vehicle.all(:links => [:factory], :fields => fields) }
|
359
|
+
# results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ :factory ], :fields => fields) }
|
279
360
|
# rescue RuntimeError
|
280
|
-
# $!.message.should == "Property Factory.land not available in repository #{ADAPTER}"
|
361
|
+
# $!.message.should == "Property QuerySpec::Factory.land not available in repository #{ADAPTER}"
|
281
362
|
# raise $!
|
282
363
|
# end
|
283
364
|
# }.should raise_error(RuntimeError)
|
@@ -287,21 +368,21 @@ if ADAPTER
|
|
287
368
|
factory = DataMapper::Associations::Relationship.new(
|
288
369
|
:factory,
|
289
370
|
ADAPTER,
|
290
|
-
'Vehicle',
|
291
|
-
'Factory',
|
371
|
+
'QuerySpec::Vehicle',
|
372
|
+
'QuerySpec::Factory',
|
292
373
|
{ :child_key => [ :factory_id ], :parent_key => [ :id ] }
|
293
374
|
)
|
294
|
-
results = repository(ADAPTER) { Vehicle.all(:links => [factory]) }
|
375
|
+
results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ factory ]) }
|
295
376
|
results.should have(1).entries
|
296
377
|
end
|
297
378
|
|
298
379
|
it 'should accept a symbol of an association name as a link' do
|
299
|
-
results = repository(ADAPTER) { Vehicle.all(:links => [:factory]) }
|
380
|
+
results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ :factory ]) }
|
300
381
|
results.should have(1).entries
|
301
382
|
end
|
302
383
|
|
303
384
|
it 'should accept a string of an association name as a link' do
|
304
|
-
results = repository(ADAPTER) { Vehicle.all(:links => ['factory']) }
|
385
|
+
results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ 'factory' ]) }
|
305
386
|
results.should have(1).entries
|
306
387
|
end
|
307
388
|
|
@@ -309,37 +390,37 @@ if ADAPTER
|
|
309
390
|
region = DataMapper::Associations::Relationship.new(
|
310
391
|
:region,
|
311
392
|
ADAPTER,
|
312
|
-
'Factory',
|
313
|
-
'Region',
|
393
|
+
'QuerySpec::Factory',
|
394
|
+
'QuerySpec::Region',
|
314
395
|
{ :child_key => [ :region_id ], :parent_key => [ :id ] }
|
315
396
|
)
|
316
|
-
results = repository(ADAPTER) { Vehicle.all(:links => ['factory',region]) }
|
397
|
+
results = repository(ADAPTER) { QuerySpec::Vehicle.all(:links => [ 'factory', region ]) }
|
317
398
|
results.should have(1).entries
|
318
399
|
end
|
319
400
|
|
320
401
|
it 'should only accept a DM::Assoc::Relationship, String & Symbol as a link' do
|
321
402
|
lambda{
|
322
|
-
DataMapper::Query.new(repository(ADAPTER), Vehicle, :links => [1])
|
403
|
+
DataMapper::Query.new(repository(ADAPTER), QuerySpec::Vehicle, :links => [1])
|
323
404
|
}.should raise_error(ArgumentError)
|
324
405
|
end
|
325
406
|
|
326
407
|
it 'should have a association by the name of the Symbol or String' do
|
327
408
|
lambda{
|
328
|
-
DataMapper::Query.new(repository(ADAPTER), Vehicle, :links=>['Sailing'])
|
409
|
+
DataMapper::Query.new(repository(ADAPTER), QuerySpec::Vehicle, :links => [ 'Sailing' ])
|
329
410
|
}.should raise_error(ArgumentError)
|
330
411
|
|
331
412
|
lambda{
|
332
|
-
DataMapper::Query.new(repository(ADAPTER), Vehicle, :links=>[:sailing])
|
413
|
+
DataMapper::Query.new(repository(ADAPTER), QuerySpec::Vehicle, :links => [ :sailing ])
|
333
414
|
}.should raise_error(ArgumentError)
|
334
415
|
end
|
335
416
|
|
336
417
|
it 'should create an n-level query path' do
|
337
|
-
Vehicle.factory.region.model.should == Region
|
338
|
-
Vehicle.factory.region.name.property.should == Region.properties(Region.repository.name)[:name]
|
418
|
+
QuerySpec::Vehicle.factory.region.model.should == QuerySpec::Region
|
419
|
+
QuerySpec::Vehicle.factory.region.name.property.should == QuerySpec::Region.properties(QuerySpec::Region.repository.name)[ :name ]
|
339
420
|
end
|
340
421
|
|
341
422
|
it 'should accept a DM::QueryPath as the key to a condition' do
|
342
|
-
vehicle = Vehicle.first(Vehicle.factory.region.name => 'North West')
|
423
|
+
vehicle = QuerySpec::Vehicle.first(QuerySpec::Vehicle.factory.region.name => 'North West')
|
343
424
|
vehicle.name.should == '10 ton delivery truck'
|
344
425
|
|
345
426
|
vehicle = Namespace::Vehicle.first(Namespace::Vehicle.factory.region.name => 'North West')
|
@@ -347,29 +428,30 @@ if ADAPTER
|
|
347
428
|
end
|
348
429
|
|
349
430
|
it "should accept a string representing a DM::QueryPath as they key to a condition" do
|
350
|
-
vehicle = Vehicle.first("factory.region.name" => 'North West')
|
431
|
+
vehicle = QuerySpec::Vehicle.first("factory.region.name" => 'North West')
|
351
432
|
vehicle.name.should == '10 ton delivery truck'
|
352
433
|
end
|
353
434
|
|
435
|
+
it "should accept 'id' and 'type' as endpoints on ah DM::QueryPath" do
|
436
|
+
vehicle = QuerySpec::Vehicle.first( QuerySpec::Vehicle.factory.region.type => 'commercial' )
|
437
|
+
vehicle.name.should == '10 ton delivery truck'
|
438
|
+
vehicle = QuerySpec::Vehicle.first( QuerySpec::Vehicle.factory.region.id => 1 )
|
439
|
+
vehicle.name.should == '10 ton delivery truck'
|
440
|
+
end
|
441
|
+
|
354
442
|
it 'should auto generate the link if a DM::Property from a different resource is in the :fields option'
|
355
443
|
|
356
444
|
it 'should create links with composite keys'
|
357
445
|
|
358
446
|
it 'should eager load associations' do
|
359
447
|
repository(ADAPTER) do
|
360
|
-
vehicle = Vehicle.first(:includes => [Vehicle.factory])
|
448
|
+
vehicle = QuerySpec::Vehicle.first(:includes => [ QuerySpec::Vehicle.factory ])
|
361
449
|
end
|
362
450
|
end
|
363
451
|
|
364
452
|
it "should behave when using mocks" do
|
365
|
-
|
366
|
-
|
367
|
-
property :id, Serial
|
368
|
-
property :name, String
|
369
|
-
end
|
370
|
-
|
371
|
-
Group.should_receive(:all).with(:order => [:id.asc])
|
372
|
-
Group.all(:order => [:id.asc])
|
453
|
+
QuerySpec::Group.should_receive(:all).with(:order => [ :id.asc ])
|
454
|
+
QuerySpec::Group.all(:order => [ :id.asc ])
|
373
455
|
end
|
374
456
|
end # describe links
|
375
457
|
end # DM::Query
|