dm-core 1.0.2 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/Gemfile +28 -94
  2. data/LICENSE +1 -1
  3. data/README.rdoc +44 -11
  4. data/Rakefile +1 -7
  5. data/VERSION +1 -1
  6. data/dm-core.gemspec +398 -299
  7. data/lib/dm-core.rb +23 -13
  8. data/lib/dm-core/adapters/abstract_adapter.rb +1 -1
  9. data/lib/dm-core/associations/many_to_many.rb +1 -3
  10. data/lib/dm-core/associations/many_to_one.rb +54 -36
  11. data/lib/dm-core/associations/one_to_many.rb +1 -2
  12. data/lib/dm-core/associations/relationship.rb +11 -2
  13. data/lib/dm-core/collection.rb +3 -7
  14. data/lib/dm-core/core_ext/symbol.rb +1 -1
  15. data/lib/dm-core/identity_map.rb +0 -5
  16. data/lib/dm-core/model.rb +11 -21
  17. data/lib/dm-core/model/property.rb +43 -58
  18. data/lib/dm-core/model/relationship.rb +49 -44
  19. data/lib/dm-core/property.rb +106 -130
  20. data/lib/dm-core/property/date_time.rb +1 -3
  21. data/lib/dm-core/property/decimal.rb +11 -7
  22. data/lib/dm-core/property/integer.rb +2 -2
  23. data/lib/dm-core/property/lookup.rb +3 -16
  24. data/lib/dm-core/property/numeric.rb +3 -3
  25. data/lib/dm-core/property/object.rb +2 -11
  26. data/lib/dm-core/property/string.rb +1 -1
  27. data/lib/dm-core/property_set.rb +34 -54
  28. data/lib/dm-core/query.rb +85 -56
  29. data/lib/dm-core/query/conditions/comparison.rb +3 -6
  30. data/lib/dm-core/query/direction.rb +0 -4
  31. data/lib/dm-core/query/path.rb +22 -6
  32. data/lib/dm-core/relationship_set.rb +74 -0
  33. data/lib/dm-core/resource.rb +21 -32
  34. data/lib/dm-core/resource/state.rb +3 -4
  35. data/lib/dm-core/spec/lib/spec_helper.rb +1 -4
  36. data/lib/dm-core/spec/setup.rb +12 -5
  37. data/lib/dm-core/spec/shared/public/property_spec.rb +35 -21
  38. data/lib/dm-core/spec/shared/resource_spec.rb +1 -1
  39. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +9 -9
  40. data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
  41. data/lib/dm-core/support/deprecate.rb +1 -1
  42. data/lib/dm-core/support/descendant_set.rb +12 -5
  43. data/lib/dm-core/support/ordered_set.rb +382 -0
  44. data/lib/dm-core/support/subject_set.rb +252 -0
  45. data/lib/dm-core/version.rb +1 -1
  46. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +1 -2
  47. data/spec/public/associations/many_to_many_spec.rb +11 -9
  48. data/spec/public/associations/many_to_one_spec.rb +1 -1
  49. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +1 -1
  50. data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +2 -2
  51. data/spec/public/associations/one_to_many_spec.rb +6 -5
  52. data/spec/public/associations/one_to_one_spec.rb +1 -1
  53. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +1 -1
  54. data/spec/public/collection_spec.rb +7 -6
  55. data/spec/public/finalize_spec.rb +1 -1
  56. data/spec/public/model/hook_spec.rb +4 -3
  57. data/spec/public/model/property_spec.rb +9 -3
  58. data/spec/public/model/relationship_spec.rb +2 -4
  59. data/spec/public/model_spec.rb +1 -1
  60. data/spec/public/property/binary_spec.rb +1 -1
  61. data/spec/public/property/boolean_spec.rb +1 -1
  62. data/spec/public/property/class_spec.rb +1 -1
  63. data/spec/public/property/date_spec.rb +1 -1
  64. data/spec/public/property/date_time_spec.rb +1 -1
  65. data/spec/public/property/decimal_spec.rb +7 -6
  66. data/spec/public/property/discriminator_spec.rb +1 -1
  67. data/spec/public/property/float_spec.rb +1 -1
  68. data/spec/public/property/integer_spec.rb +1 -1
  69. data/spec/public/property/object_spec.rb +2 -2
  70. data/spec/public/property/serial_spec.rb +1 -1
  71. data/spec/public/property/string_spec.rb +1 -1
  72. data/spec/public/property/text_spec.rb +6 -3
  73. data/spec/public/property/time_spec.rb +1 -1
  74. data/spec/public/property_spec.rb +13 -11
  75. data/spec/public/resource_spec.rb +43 -1
  76. data/spec/public/sel_spec.rb +1 -1
  77. data/spec/public/setup_spec.rb +1 -1
  78. data/spec/public/shared/collection_shared_spec.rb +6 -1
  79. data/spec/semipublic/adapters/abstract_adapter_spec.rb +1 -1
  80. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +1 -1
  81. data/spec/semipublic/associations/many_to_many_spec.rb +1 -1
  82. data/spec/semipublic/associations/many_to_one_spec.rb +1 -1
  83. data/spec/semipublic/associations/one_to_many_spec.rb +1 -1
  84. data/spec/semipublic/associations/one_to_one_spec.rb +1 -1
  85. data/spec/semipublic/associations/relationship_spec.rb +1 -1
  86. data/spec/semipublic/associations_spec.rb +1 -1
  87. data/spec/semipublic/collection_spec.rb +1 -1
  88. data/spec/semipublic/model_spec.rb +1 -1
  89. data/spec/semipublic/property/binary_spec.rb +1 -1
  90. data/spec/semipublic/property/boolean_spec.rb +1 -1
  91. data/spec/semipublic/property/class_spec.rb +1 -1
  92. data/spec/semipublic/property/date_spec.rb +1 -1
  93. data/spec/semipublic/property/date_time_spec.rb +1 -1
  94. data/spec/semipublic/property/decimal_spec.rb +6 -5
  95. data/spec/semipublic/property/discriminator_spec.rb +1 -1
  96. data/spec/semipublic/property/float_spec.rb +1 -1
  97. data/spec/semipublic/property/integer_spec.rb +1 -1
  98. data/spec/semipublic/property/lookup_spec.rb +8 -5
  99. data/spec/semipublic/property/serial_spec.rb +1 -1
  100. data/spec/semipublic/property/string_spec.rb +1 -1
  101. data/spec/semipublic/property/text_spec.rb +1 -1
  102. data/spec/semipublic/property/time_spec.rb +1 -1
  103. data/spec/semipublic/property_spec.rb +32 -7
  104. data/spec/semipublic/query/conditions/comparison_spec.rb +1 -264
  105. data/spec/semipublic/query/conditions/operation_spec.rb +1 -2
  106. data/spec/semipublic/query/path_spec.rb +27 -1
  107. data/spec/semipublic/query_spec.rb +87 -36
  108. data/spec/semipublic/resource/state/clean_spec.rb +1 -2
  109. data/spec/semipublic/resource/state/deleted_spec.rb +1 -2
  110. data/spec/semipublic/resource/state/dirty_spec.rb +1 -2
  111. data/spec/semipublic/resource/state/immutable_spec.rb +1 -2
  112. data/spec/semipublic/resource/state/transient_spec.rb +7 -2
  113. data/spec/semipublic/resource/state_spec.rb +1 -1
  114. data/spec/semipublic/resource_spec.rb +1 -1
  115. data/spec/unit/array_spec.rb +1 -0
  116. data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
  117. data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
  118. data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
  119. data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
  120. data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
  121. data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
  122. data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
  123. data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
  124. data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
  125. data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
  126. data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
  127. data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
  128. data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
  129. data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
  130. data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
  131. data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
  132. data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
  133. data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
  134. data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
  135. data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
  136. data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
  137. data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
  138. data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
  139. data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
  140. data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
  141. data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
  142. data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
  143. data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
  144. data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
  145. data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
  146. data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
  147. data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
  148. data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
  149. data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
  150. data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
  151. data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
  152. data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
  153. data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
  154. data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
  155. data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
  156. data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
  157. data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
  158. data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
  159. data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
  160. data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
  161. data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
  162. data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
  163. data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
  164. data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
  165. data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
  166. data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
  167. data/spec/unit/hash_spec.rb +2 -1
  168. data/spec/unit/hook_spec.rb +1 -0
  169. data/spec/unit/lazy_array_spec.rb +2 -1
  170. data/spec/unit/module_spec.rb +2 -1
  171. data/spec/unit/object_spec.rb +1 -0
  172. data/spec/unit/try_dup_spec.rb +1 -0
  173. data/tasks/spec.rake +0 -3
  174. metadata +149 -52
  175. data/.gitignore +0 -37
  176. data/lib/dm-core/type.rb +0 -216
  177. data/lib/dm-core/types/boolean.rb +0 -9
  178. data/lib/dm-core/types/decimal.rb +0 -9
  179. data/lib/dm-core/types/discriminator.rb +0 -50
  180. data/lib/dm-core/types/object.rb +0 -25
  181. data/lib/dm-core/types/serial.rb +0 -11
  182. data/lib/dm-core/types/text.rb +0 -11
  183. data/tasks/local_gemfile.rake +0 -16
  184. data/tasks/metrics.rake +0 -37
@@ -1,20 +1,23 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
  require 'dm-core/property/lookup'
3
3
 
4
4
  describe DataMapper::Property::Lookup do
5
5
  supported_by :all do
6
- before(:all) do
6
+ before :all do
7
+ Object.send(:remove_const, :Foo) if defined?(Foo)
7
8
  @klass = Class.new { extend DataMapper::Model }
8
9
 
9
- DataMapper::Types::LegacyType = Class.new(DataMapper::Types::Text)
10
+ module Foo
11
+ class OtherProperty < DataMapper::Property::String; end
12
+ end
10
13
  end
11
14
 
12
15
  it "should provide access to Property classes" do
13
16
  @klass::Serial.should == DataMapper::Property::Serial
14
17
  end
15
18
 
16
- it "should provide access to legacy Types" do
17
- @klass::LegacyType.should be(DataMapper::Types::LegacyType)
19
+ it "should provide access to Property classes from outside of the Property namespace" do
20
+ @klass::OtherProperty.should be(Foo::OtherProperty)
18
21
  end
19
22
 
20
23
  it "should not provide access to unknown Property classes" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Serial do
4
4
  before :all do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::String do
4
4
  before :all do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Text do
4
4
  before :all do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Time do
4
4
  before :all do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  # instance methods
4
4
  describe DataMapper::Property do
@@ -21,12 +21,15 @@ describe DataMapper::Property do
21
21
  end
22
22
  end
23
23
 
24
- describe "with custom types" do
24
+ describe "with property subclasses" do
25
25
  before :all do
26
+ Object.send(:remove_const, :CustomProps) if Object.const_defined?(:CustomProps)
27
+
26
28
  module ::CustomProps
27
- class Property
28
- class Hash < DataMapper::Property::Object; end
29
- class Other < DataMapper::Property::Object; end
29
+ module Property
30
+ class Hash < DataMapper::Property::Object; end
31
+ class Other < DataMapper::Property::Object; end
32
+ class Serial < DataMapper::Property::Object; end
30
33
  end
31
34
  end
32
35
  end
@@ -42,6 +45,28 @@ describe DataMapper::Property do
42
45
 
43
46
  it { subject.should be(::CustomProps::Property::Other) }
44
47
  end
48
+
49
+ describe "should always use the DM property when a built-in is referenced indirectly" do
50
+ subject do
51
+ Class.new do
52
+ extend ::DataMapper::Model
53
+ end
54
+ end
55
+
56
+ it { subject::Serial.should be(::DataMapper::Property::Serial) }
57
+ end
58
+
59
+ describe "should always use the custom property when an overridden built-in is directly attached to the model" do
60
+ subject do
61
+ Class.new do
62
+ extend ::DataMapper::Model
63
+ include ::CustomProps::Property
64
+ end
65
+ end
66
+
67
+ it { subject::Serial.should be(::CustomProps::Property::Serial) }
68
+ end
69
+
45
70
  end
46
71
  end
47
72
 
@@ -53,7 +78,7 @@ describe DataMapper::Property do
53
78
  property :id, Integer, :key => true
54
79
  property :name, String
55
80
  property :rating, Float
56
- property :rate, Decimal
81
+ property :rate, Decimal, :precision => 5, :scale => 2
57
82
  property :type, Class
58
83
  property :alias, String
59
84
  property :active, Boolean
@@ -68,7 +93,7 @@ describe DataMapper::Property do
68
93
  end
69
94
 
70
95
  describe 'override property definition in other repository' do
71
- before(:all) do
96
+ before :all do
72
97
  module ::Blog
73
98
  class Author
74
99
  repository(:other) do
@@ -1,267 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper'))
2
-
3
- shared_examples_for 'DataMapper::Query::Conditions::AbstractComparison' do
4
- before :all do
5
- module ::Blog
6
- class Article
7
- include DataMapper::Resource
8
-
9
- property :id, Serial
10
- property :title, String, :required => true
11
-
12
- belongs_to :parent, self, :required => false
13
- has n, :children, self, :inverse => :parent
14
- end
15
- end
16
-
17
- DataMapper.finalize
18
-
19
- @model = Blog::Article
20
- end
21
-
22
- before do
23
- class ::OtherComparison < DataMapper::Query::Conditions::AbstractComparison
24
- slug :other
25
- end
26
- end
27
-
28
- before do
29
- @relationship = @model.relationships[:parent]
30
- end
31
-
32
- it { subject.class.should respond_to(:new) }
33
-
34
- describe '.new' do
35
- subject { @comparison.class.new(@property, @value) }
36
-
37
- it { should be_kind_of(@comparison.class) }
38
-
39
- it { subject.subject.should equal(@property) }
40
-
41
- it { subject.value.should == @value }
42
- end
43
-
44
- it { subject.class.should respond_to(:slug) }
45
-
46
- describe '.slug' do
47
- describe 'with no arguments' do
48
- subject { @comparison.class.slug }
49
-
50
- it { should == @slug }
51
- end
52
-
53
- describe 'with an argument' do
54
- subject { @comparison.class.slug(:other) }
55
-
56
- it { should == :other }
57
-
58
- # reset the slug
59
- after { @comparison.class.slug(@slug) }
60
- end
61
- end
62
-
63
- it { should respond_to(:==) }
64
-
65
- describe '#==' do
66
- describe 'when the other AbstractComparison is equal' do
67
- # artificially modify the object so #== will throw an
68
- # exception if the equal? branch is not followed when heckling
69
- before { @comparison.singleton_class.send(:undef_method, :slug) }
70
-
71
- subject { @comparison == @comparison }
72
-
73
- it { should be(true) }
74
- end
75
-
76
- describe 'when the other AbstractComparison is the same class' do
77
- subject { @comparison == DataMapper::Query::Conditions::Comparison.new(@slug, @property, @value) }
78
-
79
- it { should be(true) }
80
- end
81
-
82
- describe 'when the other AbstractComparison is a different class' do
83
- subject { @comparison == DataMapper::Query::Conditions::Comparison.new(:other, @property, @value) }
84
-
85
- it { should be(false) }
86
- end
87
-
88
- describe 'when the other AbstractComparison is the same class, with different property' do
89
- subject { @comparison == DataMapper::Query::Conditions::Comparison.new(@slug, @other_property, @value) }
90
-
91
- it { should be(false) }
92
- end
93
-
94
- describe 'when the other AbstractComparison is the same class, with different value' do
95
- subject { @comparison == DataMapper::Query::Conditions::Comparison.new(@slug, @property, @other_value) }
96
-
97
- it { should be(false) }
98
- end
99
- end
100
-
101
- it { should respond_to(:eql?) }
102
-
103
- describe '#eql?' do
104
- describe 'when the other AbstractComparison is equal' do
105
- # artificially modify the object so #eql? will throw an
106
- # exception if the equal? branch is not followed when heckling
107
- before { @comparison.singleton_class.send(:undef_method, :slug) }
108
-
109
- subject { @comparison.eql?(@comparison) }
110
-
111
- it { should be(true) }
112
- end
113
-
114
- describe 'when the other AbstractComparison is the same class' do
115
- subject { @comparison.eql?(DataMapper::Query::Conditions::Comparison.new(@slug, @property, @value)) }
116
-
117
- it { should be(true) }
118
- end
119
-
120
- describe 'when the other AbstractComparison is a different class' do
121
- subject { @comparison.eql?(DataMapper::Query::Conditions::Comparison.new(:other, @property, @value)) }
122
-
123
- it { should be(false) }
124
- end
125
-
126
- describe 'when the other AbstractComparison is the same class, with different property' do
127
- subject { @comparison.eql?(DataMapper::Query::Conditions::Comparison.new(@slug, @other_property, @value)) }
128
-
129
- it { should be(false) }
130
- end
131
-
132
- describe 'when the other AbstractComparison is the same class, with different value' do
133
- subject { @comparison.eql?(DataMapper::Query::Conditions::Comparison.new(@slug, @property, @other_value)) }
134
-
135
- it { should be(false) }
136
- end
137
- end
138
-
139
- it { should respond_to(:hash) }
140
-
141
- describe '#hash' do
142
- subject { @comparison.hash }
143
-
144
- it 'should match the same AbstractComparison with the same property and value' do
145
- should == DataMapper::Query::Conditions::Comparison.new(@slug, @property, @value).hash
146
- end
147
-
148
- it 'should not match the same AbstractComparison with different property' do
149
- should_not == DataMapper::Query::Conditions::Comparison.new(@slug, @other_property, @value).hash
150
- end
151
-
152
- it 'should not match the same AbstractComparison with different value' do
153
- should_not == DataMapper::Query::Conditions::Comparison.new(@slug, @property, @other_value).hash
154
- end
155
-
156
- it 'should not match a different AbstractComparison with the same property and value' do
157
- should_not == @other.hash
158
- end
159
-
160
- it 'should not match a different AbstractComparison with different property' do
161
- should_not == @other.class.new(@other_property, @value).hash
162
- end
163
-
164
- it 'should not match a different AbstractComparison with different value' do
165
- should_not == @other.class.new(@property, @other_value).hash
166
- end
167
- end
168
-
169
- it { should respond_to(:loaded_value) }
170
-
171
- describe '#loaded_value' do
172
- subject { @comparison.loaded_value }
173
-
174
- it { should == @value }
175
- end
176
-
177
- it { should respond_to(:parent) }
178
-
179
- describe '#parent' do
180
- subject { @comparison.parent }
181
-
182
- describe 'should be nil by default' do
183
- it { should be_nil }
184
- end
185
-
186
- describe 'should relate to parent operation' do
187
- before do
188
- @operation = DataMapper::Query::Conditions::Operation.new(:and)
189
- @comparison.parent = @operation
190
- end
191
-
192
- it { should be_equal(@operation) }
193
- end
194
- end
195
-
196
- it { should respond_to(:parent=) }
197
-
198
- describe '#parent=' do
199
- before do
200
- @operation = DataMapper::Query::Conditions::Operation.new(:and)
201
- end
202
-
203
- subject { @comparison.parent = @operation }
204
-
205
- it { should equal(@operation) }
206
-
207
- it 'should change the parent' do
208
- method(:subject).should change(@comparison, :parent).
209
- from(nil).
210
- to(@operation)
211
- end
212
- end
213
-
214
- it { should respond_to(:property?) }
215
-
216
- describe '#property?' do
217
- subject { @comparison.property? }
218
-
219
- it { should be(true) }
220
- end
221
-
222
- it { should respond_to(:slug) }
223
-
224
- describe '#slug' do
225
- subject { @comparison.slug }
226
-
227
- it { should == @slug }
228
- end
229
-
230
- it { should respond_to(:subject) }
231
-
232
- describe '#subject' do
233
- subject { @comparison.subject }
234
-
235
- it { should be_equal(@property) }
236
- end
237
-
238
- it { should respond_to(:valid?) }
239
-
240
- describe '#valid?' do
241
- subject { @comparison.valid? }
242
-
243
- describe 'when the value is valid for the subject' do
244
- it { should be(true) }
245
- end
246
-
247
- describe 'when the value is not valid for the subject' do
248
- before do
249
- @comparison = DataMapper::Query::Conditions::Comparison.new(@slug, @property, nil)
250
- end
251
-
252
- it { should be(false) }
253
- end
254
- end
255
-
256
- it { should respond_to(:value) }
257
-
258
- describe '#value' do
259
- subject { @comparison.value }
260
-
261
- it { should == @value }
262
- end
263
- end
264
-
1
+ require 'spec_helper'
265
2
  describe DataMapper::Query::Conditions::Comparison do
266
3
  before :all do
267
4
  module ::Blog
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper'))
2
-
1
+ require 'spec_helper'
3
2
  module OperationMatchers
4
3
  class HaveValidParent
5
4
  def matches?(target)
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  # class methods
4
4
  describe DataMapper::Query::Path do
@@ -427,6 +427,32 @@ describe DataMapper::Query::Path do
427
427
  end
428
428
  end
429
429
 
430
+ describe 'ordering' do
431
+ before do
432
+ @path = Article.author.title
433
+ end
434
+
435
+ describe '#desc' do
436
+ before do
437
+ @return = @path.desc
438
+ end
439
+
440
+ it 'returns a :desc operator from the path' do
441
+ @return.should == DataMapper::Query::Operator.new(@path.property, :desc)
442
+ end
443
+ end
444
+
445
+ describe '#asc' do
446
+ before do
447
+ @return = @path.asc
448
+ end
449
+
450
+ it 'returns a :desc operator from the path' do
451
+ @return.should == DataMapper::Query::Operator.new(@path.property, :asc)
452
+ end
453
+ end
454
+ end
455
+
430
456
  ((DataMapper::Query::Conditions::Comparison.slugs | [ :not ]) - [ :eql, :in ]).each do |slug|
431
457
  describe "##{slug}" do
432
458
  before do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  require 'ostruct'
4
4
 
@@ -18,7 +18,7 @@ describe DataMapper::Query do
18
18
 
19
19
  property :name, String, :key => true
20
20
  property :password, Password
21
- property :balance, Decimal
21
+ property :balance, Decimal, :precision => 5, :scale => 2
22
22
 
23
23
  belongs_to :referrer, self, :required => false
24
24
  has n, :referrals, self, :inverse => :referrer
@@ -637,7 +637,7 @@ describe DataMapper::Query do
637
637
  end
638
638
  end
639
639
 
640
- describe 'with a custom Property' do
640
+ describe 'with a Property subclass' do
641
641
  before :all do
642
642
  @options[:conditions] = { :password => 'password' }
643
643
  @return = DataMapper::Query.new(@repository, @model, @options.freeze)
@@ -787,6 +787,29 @@ describe DataMapper::Query do
787
787
  end
788
788
  end
789
789
 
790
+ describe 'that is a Hash with a String key that is a Path and not for a Relationship in the model' do
791
+ it 'should raise an exception' do
792
+ lambda {
793
+ DataMapper::Query.new(@repository, @model, @options.update(:conditions => { 'unknown.id' => 1 }))
794
+ }.should raise_error(ArgumentError, "condition \"unknown.id\" does not map to a relationship in #{@model}")
795
+ end
796
+ end
797
+
798
+ describe 'that is a Hash with a Property that does not belong to the model' do
799
+ before do
800
+ Object.send(:remove_const, :Alternate) if Object.const_defined?(:Alternate)
801
+ @alternate_model = DataMapper::Model.new('Alternate') do
802
+ property :id, DataMapper::Property::Serial
803
+ end
804
+ end
805
+
806
+ it 'should raise an exception' do
807
+ lambda {
808
+ DataMapper::Query.new(@repository, @model, @options.update(:conditions => { @alternate_model.properties[:id] => 1 }))
809
+ }.should raise_error(ArgumentError, "condition :id does not map to a property in #{@model}, but belongs to #{@alternate_model}")
810
+ end
811
+ end
812
+
790
813
  describe 'that is a Hash with a Query::Operator key that is not for a Property in the model' do
791
814
  it 'should raise an exception' do
792
815
  lambda {
@@ -935,6 +958,41 @@ describe DataMapper::Query do
935
958
  @return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name]) ]
936
959
  end
937
960
  end
961
+
962
+ describe 'that contains a Query::Direction with a property that is not part of the model' do
963
+ before :all do
964
+ @property = DataMapper::Property::String.new(@model, :unknown)
965
+ @direction = DataMapper::Query::Direction.new(@property, :desc)
966
+ @return = DataMapper::Query.new(@repository, @model, @options.update(:order => [ @direction ]))
967
+ end
968
+
969
+ it 'should set the order, since it may map to a joined model' do
970
+ @return.order.should == [ @direction ]
971
+ end
972
+ end
973
+
974
+ describe 'that contains a Property that is not part of the model' do
975
+ before :all do
976
+ @property = DataMapper::Property::String.new(@model, :unknown)
977
+ @return = DataMapper::Query.new(@repository, @model, @options.update(:order => [ @property ]))
978
+ end
979
+
980
+ it 'should set the order, since it may map to a joined model' do
981
+ @return.order.should == [ DataMapper::Query::Direction.new(@property) ]
982
+ end
983
+ end
984
+
985
+ describe 'that contains a Query::Path to a property on a linked model' do
986
+ before :all do
987
+ @property = @model.referrer.name
988
+ @return = DataMapper::Query.new(@repository, @model, @options.update(:order => [ @property ]))
989
+ end
990
+
991
+ it 'should set the order' do
992
+ @return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name]) ]
993
+ end
994
+ end
995
+
938
996
  describe 'that is an Array containing a Symbol' do
939
997
  before :all do
940
998
  @return = DataMapper::Query.new(@repository, @model, @options.freeze)
@@ -1079,19 +1137,6 @@ describe DataMapper::Query do
1079
1137
  end
1080
1138
  end
1081
1139
 
1082
- describe 'that contains a Query::Direction with a property that is not part of the model' do
1083
- before :all do
1084
- @property = DataMapper::Property::String.new(@model, :unknown)
1085
- @direction = DataMapper::Query::Direction.new(@property, :desc)
1086
- end
1087
-
1088
- it 'should raise an exception' do
1089
- lambda {
1090
- DataMapper::Query.new(@repository, @model, @options.update(:order => [ @direction ]))
1091
- }.should raise_error(ArgumentError, "+options[:order]+ entry :unknown does not map to a property in #{@model}")
1092
- end
1093
- end
1094
-
1095
1140
  describe 'that contains a Query::Operator with a target that is not part of the model' do
1096
1141
  it 'should raise an exception' do
1097
1142
  lambda {
@@ -1108,18 +1153,6 @@ describe DataMapper::Query do
1108
1153
  end
1109
1154
  end
1110
1155
 
1111
- describe 'that contains a Property that is not part of the model' do
1112
- before :all do
1113
- @property = DataMapper::Property::String.new(@model, :unknown)
1114
- end
1115
-
1116
- it 'should raise an exception' do
1117
- lambda {
1118
- DataMapper::Query.new(@repository, @model, @options.update(:order => [ @property ]))
1119
- }.should raise_error(ArgumentError, "+options[:order]+ entry :unknown does not map to a property in #{@model}")
1120
- end
1121
- end
1122
-
1123
1156
  describe 'that contains a Symbol that is not for a Property in the model' do
1124
1157
  it 'should raise an exception' do
1125
1158
  lambda {
@@ -1960,7 +1993,15 @@ describe DataMapper::Query do
1960
1993
  end
1961
1994
  end
1962
1995
 
1963
- subject { @query.send(method, @other) }
1996
+ subject do
1997
+ result = @query.send(method, @other)
1998
+
1999
+ if @another
2000
+ result = result.send(method, @another)
2001
+ end
2002
+
2003
+ result
2004
+ end
1964
2005
 
1965
2006
  describe 'with equivalent query' do
1966
2007
  before { @other = @query.dup }
@@ -1995,8 +2036,9 @@ describe DataMapper::Query do
1995
2036
 
1996
2037
  describe 'with self matching everything' do
1997
2038
  before do
1998
- @query = DataMapper::Query.new(@repository, @model)
1999
- @other = DataMapper::Query.new(@repository, @model, :name => 'Dan Kubb')
2039
+ @query = DataMapper::Query.new(@repository, @model)
2040
+ @other = DataMapper::Query.new(@repository, @model, :name => 'Dan Kubb')
2041
+ @another = DataMapper::Query.new(@repository, @model, :citizenship => 'US')
2000
2042
  end
2001
2043
 
2002
2044
  it { should be_kind_of(DataMapper::Query) }
@@ -2005,10 +2047,10 @@ describe DataMapper::Query do
2005
2047
 
2006
2048
  it { should_not equal(@other) }
2007
2049
 
2050
+ it { should_not equal(@another) }
2051
+
2008
2052
  it 'should factor out the operation matching everything' do
2009
- pending 'TODO: compress Query#conditions for proper comparison' do
2010
- should == DataMapper::Query.new(@repository, @model, :name => 'Dan Kubb')
2011
- end
2053
+ should == DataMapper::Query.new(@repository, @model, :name => 'Dan Kubb', :citizenship => 'US')
2012
2054
  end
2013
2055
  end
2014
2056
 
@@ -3430,15 +3472,24 @@ describe DataMapper::Query do
3430
3472
  it { should_not be_unique }
3431
3473
  end
3432
3474
 
3433
- describe 'when links are provided, but unique is not specified' do
3475
+ describe 'when 1..n links are provided, but unique is not specified' do
3434
3476
  before :all do
3435
3477
  @query.should_not be_unique
3436
- @query.update(:links => [ :referrer ])
3478
+ @query.update(:links => [ :referrals ])
3437
3479
  end
3438
3480
 
3439
3481
  it { should be_unique }
3440
3482
  end
3441
3483
 
3484
+ describe 'when 0..1 links are provided, but unique is not specified' do
3485
+ before :all do
3486
+ @query.should_not be_unique
3487
+ @query.update(:links => [ :referrer ])
3488
+ end
3489
+
3490
+ it { should_not be_unique }
3491
+ end
3492
+
3442
3493
  describe 'when links are provided, but unique is false' do
3443
3494
  before :all do
3444
3495
  @query.should_not be_unique