dm-core 0.9.11 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/.autotest +17 -14
  2. data/.gitignore +3 -1
  3. data/FAQ +6 -5
  4. data/History.txt +5 -50
  5. data/Manifest.txt +66 -76
  6. data/QUICKLINKS +1 -1
  7. data/README.txt +21 -15
  8. data/Rakefile +6 -7
  9. data/SPECS +2 -29
  10. data/TODO +1 -1
  11. data/deps.rip +2 -0
  12. data/dm-core.gemspec +11 -15
  13. data/lib/dm-core.rb +105 -110
  14. data/lib/dm-core/adapters.rb +135 -16
  15. data/lib/dm-core/adapters/abstract_adapter.rb +251 -181
  16. data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
  17. data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
  18. data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
  19. data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
  20. data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
  21. data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
  22. data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
  23. data/lib/dm-core/associations/many_to_many.rb +372 -90
  24. data/lib/dm-core/associations/many_to_one.rb +220 -73
  25. data/lib/dm-core/associations/one_to_many.rb +319 -255
  26. data/lib/dm-core/associations/one_to_one.rb +66 -53
  27. data/lib/dm-core/associations/relationship.rb +561 -156
  28. data/lib/dm-core/collection.rb +1101 -379
  29. data/lib/dm-core/core_ext/kernel.rb +12 -0
  30. data/lib/dm-core/core_ext/symbol.rb +10 -0
  31. data/lib/dm-core/identity_map.rb +4 -34
  32. data/lib/dm-core/migrations.rb +1283 -0
  33. data/lib/dm-core/model.rb +570 -369
  34. data/lib/dm-core/model/descendant_set.rb +81 -0
  35. data/lib/dm-core/model/hook.rb +45 -0
  36. data/lib/dm-core/model/is.rb +32 -0
  37. data/lib/dm-core/model/property.rb +247 -0
  38. data/lib/dm-core/model/relationship.rb +335 -0
  39. data/lib/dm-core/model/scope.rb +90 -0
  40. data/lib/dm-core/property.rb +808 -273
  41. data/lib/dm-core/property_set.rb +141 -98
  42. data/lib/dm-core/query.rb +1037 -483
  43. data/lib/dm-core/query/conditions/comparison.rb +872 -0
  44. data/lib/dm-core/query/conditions/operation.rb +221 -0
  45. data/lib/dm-core/query/direction.rb +43 -0
  46. data/lib/dm-core/query/operator.rb +84 -0
  47. data/lib/dm-core/query/path.rb +138 -0
  48. data/lib/dm-core/query/sort.rb +45 -0
  49. data/lib/dm-core/repository.rb +210 -94
  50. data/lib/dm-core/resource.rb +641 -421
  51. data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
  52. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
  53. data/lib/dm-core/support/chainable.rb +22 -0
  54. data/lib/dm-core/support/deprecate.rb +12 -0
  55. data/lib/dm-core/support/logger.rb +13 -0
  56. data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
  57. data/lib/dm-core/transaction.rb +333 -92
  58. data/lib/dm-core/type.rb +98 -60
  59. data/lib/dm-core/types/boolean.rb +1 -1
  60. data/lib/dm-core/types/discriminator.rb +34 -20
  61. data/lib/dm-core/types/object.rb +7 -4
  62. data/lib/dm-core/types/paranoid_boolean.rb +11 -9
  63. data/lib/dm-core/types/paranoid_datetime.rb +11 -9
  64. data/lib/dm-core/types/serial.rb +3 -3
  65. data/lib/dm-core/types/text.rb +3 -4
  66. data/lib/dm-core/version.rb +1 -1
  67. data/script/performance.rb +102 -109
  68. data/script/profile.rb +169 -38
  69. data/spec/lib/adapter_helpers.rb +105 -0
  70. data/spec/lib/collection_helpers.rb +18 -0
  71. data/spec/lib/counter_adapter.rb +34 -0
  72. data/spec/lib/pending_helpers.rb +27 -0
  73. data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
  74. data/spec/public/associations/many_to_many_spec.rb +193 -0
  75. data/spec/public/associations/many_to_one_spec.rb +73 -0
  76. data/spec/public/associations/one_to_many_spec.rb +77 -0
  77. data/spec/public/associations/one_to_one_spec.rb +156 -0
  78. data/spec/public/collection_spec.rb +65 -0
  79. data/spec/public/migrations_spec.rb +359 -0
  80. data/spec/public/model/relationship_spec.rb +924 -0
  81. data/spec/public/model_spec.rb +159 -0
  82. data/spec/public/property_spec.rb +829 -0
  83. data/spec/public/resource_spec.rb +71 -0
  84. data/spec/public/sel_spec.rb +44 -0
  85. data/spec/public/setup_spec.rb +145 -0
  86. data/spec/public/shared/association_collection_shared_spec.rb +317 -0
  87. data/spec/public/shared/collection_shared_spec.rb +1670 -0
  88. data/spec/public/shared/finder_shared_spec.rb +1619 -0
  89. data/spec/public/shared/resource_shared_spec.rb +924 -0
  90. data/spec/public/shared/sel_shared_spec.rb +112 -0
  91. data/spec/public/transaction_spec.rb +129 -0
  92. data/spec/public/types/discriminator_spec.rb +130 -0
  93. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  94. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
  95. data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
  96. data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
  97. data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
  98. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
  99. data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
  100. data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
  101. data/spec/semipublic/associations/relationship_spec.rb +194 -0
  102. data/spec/semipublic/associations_spec.rb +177 -0
  103. data/spec/semipublic/collection_spec.rb +142 -0
  104. data/spec/semipublic/property_spec.rb +61 -0
  105. data/spec/semipublic/query/conditions_spec.rb +528 -0
  106. data/spec/semipublic/query/path_spec.rb +443 -0
  107. data/spec/semipublic/query_spec.rb +2626 -0
  108. data/spec/semipublic/resource_spec.rb +47 -0
  109. data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
  110. data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
  111. data/spec/spec.opts +3 -1
  112. data/spec/spec_helper.rb +80 -57
  113. data/tasks/ci.rb +19 -31
  114. data/tasks/dm.rb +43 -48
  115. data/tasks/doc.rb +8 -11
  116. data/tasks/gemspec.rb +5 -5
  117. data/tasks/hoe.rb +15 -16
  118. data/tasks/install.rb +8 -10
  119. metadata +74 -111
  120. data/lib/dm-core/associations.rb +0 -207
  121. data/lib/dm-core/associations/relationship_chain.rb +0 -81
  122. data/lib/dm-core/auto_migrations.rb +0 -105
  123. data/lib/dm-core/dependency_queue.rb +0 -32
  124. data/lib/dm-core/hook.rb +0 -11
  125. data/lib/dm-core/is.rb +0 -16
  126. data/lib/dm-core/logger.rb +0 -232
  127. data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
  128. data/lib/dm-core/migrator.rb +0 -29
  129. data/lib/dm-core/scope.rb +0 -58
  130. data/lib/dm-core/support.rb +0 -7
  131. data/lib/dm-core/support/array.rb +0 -13
  132. data/lib/dm-core/support/assertions.rb +0 -8
  133. data/lib/dm-core/support/errors.rb +0 -23
  134. data/lib/dm-core/support/kernel.rb +0 -11
  135. data/lib/dm-core/support/symbol.rb +0 -41
  136. data/lib/dm-core/type_map.rb +0 -80
  137. data/lib/dm-core/types.rb +0 -19
  138. data/script/all +0 -4
  139. data/spec/integration/association_spec.rb +0 -1382
  140. data/spec/integration/association_through_spec.rb +0 -203
  141. data/spec/integration/associations/many_to_many_spec.rb +0 -449
  142. data/spec/integration/associations/many_to_one_spec.rb +0 -163
  143. data/spec/integration/associations/one_to_many_spec.rb +0 -188
  144. data/spec/integration/auto_migrations_spec.rb +0 -413
  145. data/spec/integration/collection_spec.rb +0 -1073
  146. data/spec/integration/data_objects_adapter_spec.rb +0 -32
  147. data/spec/integration/dependency_queue_spec.rb +0 -46
  148. data/spec/integration/model_spec.rb +0 -197
  149. data/spec/integration/mysql_adapter_spec.rb +0 -85
  150. data/spec/integration/postgres_adapter_spec.rb +0 -731
  151. data/spec/integration/property_spec.rb +0 -253
  152. data/spec/integration/query_spec.rb +0 -514
  153. data/spec/integration/repository_spec.rb +0 -61
  154. data/spec/integration/resource_spec.rb +0 -513
  155. data/spec/integration/sqlite3_adapter_spec.rb +0 -352
  156. data/spec/integration/sti_spec.rb +0 -273
  157. data/spec/integration/strategic_eager_loading_spec.rb +0 -156
  158. data/spec/integration/transaction_spec.rb +0 -75
  159. data/spec/integration/type_spec.rb +0 -275
  160. data/spec/lib/logging_helper.rb +0 -18
  161. data/spec/lib/mock_adapter.rb +0 -27
  162. data/spec/lib/model_loader.rb +0 -100
  163. data/spec/lib/publicize_methods.rb +0 -28
  164. data/spec/models/content.rb +0 -16
  165. data/spec/models/vehicles.rb +0 -34
  166. data/spec/models/zoo.rb +0 -48
  167. data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
  168. data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
  169. data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
  170. data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
  171. data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
  172. data/spec/unit/associations/many_to_many_spec.rb +0 -32
  173. data/spec/unit/associations/many_to_one_spec.rb +0 -159
  174. data/spec/unit/associations/one_to_many_spec.rb +0 -393
  175. data/spec/unit/associations/one_to_one_spec.rb +0 -7
  176. data/spec/unit/associations/relationship_spec.rb +0 -71
  177. data/spec/unit/associations_spec.rb +0 -242
  178. data/spec/unit/auto_migrations_spec.rb +0 -111
  179. data/spec/unit/collection_spec.rb +0 -182
  180. data/spec/unit/data_mapper_spec.rb +0 -35
  181. data/spec/unit/identity_map_spec.rb +0 -126
  182. data/spec/unit/is_spec.rb +0 -80
  183. data/spec/unit/migrator_spec.rb +0 -33
  184. data/spec/unit/model_spec.rb +0 -321
  185. data/spec/unit/naming_conventions_spec.rb +0 -36
  186. data/spec/unit/property_set_spec.rb +0 -90
  187. data/spec/unit/property_spec.rb +0 -753
  188. data/spec/unit/query_spec.rb +0 -571
  189. data/spec/unit/repository_spec.rb +0 -93
  190. data/spec/unit/resource_spec.rb +0 -649
  191. data/spec/unit/scope_spec.rb +0 -142
  192. data/spec/unit/transaction_spec.rb +0 -493
  193. data/spec/unit/type_map_spec.rb +0 -114
  194. data/spec/unit/type_spec.rb +0 -119
@@ -0,0 +1,142 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ # run the specs once with a loaded collection and once not
4
+ [ false, true ].each do |loaded|
5
+ describe DataMapper::Collection do
6
+ extend DataMapper::Spec::CollectionHelpers::GroupMethods
7
+
8
+ self.loaded = loaded
9
+
10
+ before :all do
11
+ module ::Blog
12
+ class Article
13
+ include DataMapper::Resource
14
+
15
+ property :id, Serial
16
+ property :title, String
17
+ property :content, Text
18
+ property :subtitle, String
19
+ end
20
+ end
21
+
22
+ @article_model = Blog::Article
23
+ end
24
+
25
+ supported_by :all do
26
+ before :all do
27
+ @article_repository = @repository
28
+ @articles_query = DataMapper::Query.new(@article_repository, @article_model, :title => 'Sample Article')
29
+
30
+ @article = @article_model.create(:title => 'Sample Article', :content => 'Sample')
31
+
32
+ @articles = @article_model.all(@articles_query)
33
+
34
+ @articles.entries if loaded
35
+ end
36
+
37
+ it { DataMapper::Collection.should respond_to(:new) }
38
+
39
+ describe '.new' do
40
+ describe 'with resources' do
41
+ before :all do
42
+ @return = @collection = DataMapper::Collection.new(@articles_query, [ @article ])
43
+ end
44
+
45
+ it 'should return a Collection' do
46
+ @return.should be_kind_of(DataMapper::Collection)
47
+ end
48
+
49
+ it 'should be loaded' do
50
+ @return.should be_loaded
51
+ end
52
+
53
+ it 'should contain the article' do
54
+ @collection.should == [ @article ]
55
+ end
56
+ end
57
+
58
+ describe 'with no resources' do
59
+ before :all do
60
+ @return = @collection = DataMapper::Collection.new(@articles_query)
61
+ end
62
+
63
+ it 'should return a Collection' do
64
+ @return.should be_kind_of(DataMapper::Collection)
65
+ end
66
+
67
+ it 'should not be loaded' do
68
+ @return.should_not be_loaded
69
+ end
70
+
71
+ it 'should contain the article' do
72
+ @collection.should == [ @article ]
73
+ end
74
+ end
75
+ end
76
+
77
+ it { @articles.should respond_to(:properties) }
78
+
79
+ describe '#properties' do
80
+ before :all do
81
+ @return = @properties = @articles.properties
82
+ end
83
+
84
+ it 'should return a PropertySet' do
85
+ @return.should be_kind_of(DataMapper::PropertySet)
86
+ end
87
+
88
+ it 'should be expected properties' do
89
+ @properties.to_a.should == @articles_query.fields
90
+ end
91
+ end
92
+
93
+ it { @articles.should respond_to(:query) }
94
+
95
+ describe '#query' do
96
+ before :all do
97
+ @return = @articles.query
98
+ end
99
+
100
+ it 'should return a Query' do
101
+ @return.should be_kind_of(DataMapper::Query)
102
+ end
103
+
104
+ it 'should return expected Query' do
105
+ @return.should eql(@articles_query)
106
+ end
107
+ end
108
+
109
+ it { @articles.should respond_to(:relationships) }
110
+
111
+ describe '#relationships' do
112
+ before :all do
113
+ @return = @relationships = @articles.relationships
114
+ end
115
+
116
+ it 'should return a Hash' do
117
+ @return.should be_kind_of(Hash)
118
+ end
119
+
120
+ it 'should return expected Hash' do
121
+ @return.should equal(@article_model.relationships(@article_repository.name))
122
+ end
123
+ end
124
+
125
+ it { @articles.should respond_to(:repository) }
126
+
127
+ describe '#repository' do
128
+ before :all do
129
+ @return = @repository = @articles.repository
130
+ end
131
+
132
+ it 'should return a Repository' do
133
+ @return.should be_kind_of(DataMapper::Repository)
134
+ end
135
+
136
+ it 'should be expected Repository' do
137
+ @repository.should == @article_repository
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property do
4
+ before :all do
5
+ module ::Blog
6
+ class Author
7
+ include DataMapper::Resource
8
+
9
+ property :name, String, :key => true
10
+ property :alias, String
11
+ end
12
+ end
13
+ end
14
+
15
+ describe '#valid?' do
16
+ describe 'when provided a valid value' do
17
+ it 'should return true' do
18
+ Blog::Author.properties[:name].valid?('Dan Kubb').should be_true
19
+ end
20
+ end
21
+
22
+ describe 'when provide an invalid value' do
23
+ it 'should return false' do
24
+ Blog::Author.properties[:name].valid?(1).should be_false
25
+ end
26
+ end
27
+
28
+ describe 'when provide a nil value when not nullable' do
29
+ it 'should return false' do
30
+ Blog::Author.properties[:name].valid?(nil).should be_false
31
+ end
32
+ end
33
+
34
+ describe 'when provide a nil value when nullable' do
35
+ it 'should return false' do
36
+ Blog::Author.properties[:alias].valid?(nil).should be_true
37
+ end
38
+ end
39
+ end
40
+
41
+ describe 'override property definition in other repository' do
42
+ before(:all) do
43
+ module ::Blog
44
+ class Author
45
+ repository(:other) do
46
+ property :name, String, :key => true, :field => 'other_name'
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ it 'should return property options in other repository' do
53
+ ::Blog::Author.properties(:other)[:name].options[:field].should == 'other_name'
54
+ end
55
+
56
+ it 'should return property options in default repository' do
57
+ ::Blog::Author.properties[:name].options[:field].should be_nil
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,528 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ include DataMapper::Query::Conditions
4
+
5
+ module ComparisonSpecHelpers
6
+
7
+ def match(record)
8
+ ComparisonMatcher.new(record)
9
+ end
10
+
11
+ class ComparisonMatcher
12
+
13
+ def initialize(record)
14
+ @record = record
15
+ end
16
+
17
+ def matches?(comparison)
18
+ @comparison = comparison
19
+ comparison.matches?(@record)
20
+ end
21
+
22
+ def failure_message
23
+ "Expected #{@comparison.inspect} to match #{@record.inspect}"
24
+ end
25
+
26
+ def negative_failure_message
27
+ "Expected #{@comparison.inspect} to NOT match #{@record.inspect}"
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ describe DataMapper::Query::Conditions do
35
+
36
+ include ComparisonSpecHelpers
37
+
38
+ before :all do
39
+ class ::Mass < DataMapper::Type
40
+ primitive Integer
41
+
42
+ def self.load(value, property)
43
+ { 1 => 'Small', 2 => 'Large', 3 => 'XLarge' }[value]
44
+ end
45
+
46
+ def self.dump(value, property)
47
+ { 'Small' => 1, 'Large' => 2, 'XLarge' => 3 }[value]
48
+ end
49
+ end
50
+
51
+ class ::Heffalump
52
+ include DataMapper::Resource
53
+
54
+ property :id, Serial
55
+ property :color, String
56
+ property :num_spots, Integer
57
+ property :striped, Boolean
58
+ property :mass, Mass, :default => 'Large', :nullable => false
59
+
60
+ belongs_to :parent, Heffalump
61
+
62
+ # Heffalumps are surprisingly picky when it comes to choosing friends --
63
+ # they greatly prefer the company of similarly sized beasts. :)
64
+ has n, :mass_mates, Heffalump, :child_key => [:mass], :parent_key => [:mass]
65
+ end
66
+
67
+ @heff1 = Heffalump.new(:id => 1, :num_spots => 1, :color => 'green', :striped => true, :mass => 'Small')
68
+ @heff2 = Heffalump.new(:id => 2, :num_spots => 2, :color => 'green', :striped => false, :mass => 'Large', :parent => @heff1)
69
+ @heff3 = Heffalump.new(:id => 3, :num_spots => 3, :color => 'blue', :striped => false, :mass => 'XLarge', :parent => @heff2)
70
+ end
71
+
72
+ describe 'Operations' do
73
+ before do
74
+ @comp1 = Comparison.new(:eql, Heffalump.num_spots, 1)
75
+ @comp2 = Comparison.new(:eql, Heffalump.color, 'green')
76
+ end
77
+
78
+ it 'should initialize an AbstractOperation object' do
79
+ op = Operation.new(:and)
80
+ op.should be_kind_of(AbstractOperation)
81
+ end
82
+
83
+ {
84
+ :and => AndOperation,
85
+ :or => OrOperation,
86
+ :not => NotOperation
87
+ }.each do |operand, klass|
88
+ it "should initialize as #{klass} for the #{operand} operator" do
89
+ op = Operation.new(operand)
90
+ op.should be_kind_of(klass)
91
+ end
92
+ end
93
+
94
+ it 'should set the remaining args in @operands' do
95
+ op = Operation.new(:and, @comp1, @comp2)
96
+ op.operands.should == [@comp1, @comp2]
97
+ end
98
+
99
+ it 'should have operands be empty of no operands are provided' do
100
+ op = Operation.new(:and)
101
+ op.operands.should == []
102
+ end
103
+
104
+ describe 'NotOperation' do
105
+ before do
106
+ @op = Operation.new(:not, @comp1)
107
+ end
108
+
109
+ it 'should not allow more than one operand' do
110
+ lambda {
111
+ Operation.new(:not, @comp1, @comp2)
112
+ }.should raise_error(InvalidOperation)
113
+ end
114
+
115
+ it 'should negate the comparison' do
116
+ @comp1.should match(@heff1)
117
+ @op.should_not match(@heff1)
118
+ end
119
+ end
120
+
121
+ describe 'AndOperation' do
122
+ before do
123
+ @op = Operation.new(:and, @comp1, @comp2)
124
+ end
125
+
126
+ it 'should match if all comparisons match' do
127
+ @comp1.should match(@heff1)
128
+ @comp2.should match(@heff1)
129
+
130
+ @op.should match(@heff1)
131
+ end
132
+
133
+ it 'should not match of any of the comparisons does not match' do
134
+ @comp1.should_not match(@heff2)
135
+
136
+ @op.should_not match(@heff2)
137
+ end
138
+ end
139
+
140
+ describe 'OrOperation' do
141
+ before do
142
+ @op = Operation.new(:or, @comp1, @comp2)
143
+ end
144
+
145
+ it 'should match if any of the comparisons match' do
146
+ @comp1.should_not match(@heff2)
147
+ @comp2.should match(@heff2)
148
+
149
+ @op.should match(@heff2)
150
+ end
151
+
152
+ it 'should not match if none of the comparisons match' do
153
+ @comp1.should_not match(@heff3)
154
+ @comp2.should_not match(@heff3)
155
+
156
+ @op.should_not match(@heff3)
157
+ end
158
+ end
159
+ end
160
+
161
+ describe 'Comparisons' do
162
+ it 'should initialize an AbstractComparison object' do
163
+ comp = Comparison.new(:eql, Heffalump.num_spots, 1)
164
+ comp.should be_kind_of(AbstractComparison)
165
+ end
166
+
167
+ {
168
+ :eql => EqualToComparison,
169
+ :gt => GreaterThanComparison,
170
+ :gte => GreaterThanOrEqualToComparison,
171
+ :lt => LessThanComparison,
172
+ :lte => LessThanOrEqualToComparison,
173
+ :regexp => RegexpComparison
174
+ }.each do |slug, klass|
175
+ it "should initialize as #{klass} for the #{slug} comparator" do
176
+ comp = Comparison.new(slug, Heffalump.num_spots, 2)
177
+ comp.should be_kind_of(klass)
178
+ end
179
+ end
180
+
181
+ it 'should initialize as InclusionComparison for the :in comparator' do
182
+ comp = Comparison.new(:in, Heffalump.num_spots, [ 2 ])
183
+ comp.should be_kind_of(InclusionComparison)
184
+ end
185
+
186
+ describe 'EqualToComparison' do
187
+ describe 'with a value matching the property primitive' do
188
+ before :all do
189
+ @comp = Comparison.new(:eql, Heffalump.striped, false)
190
+ end
191
+
192
+ it_should_behave_like 'A valid query condition'
193
+
194
+ it 'should match records that equal the given value' do
195
+ @comp.should match(@heff2)
196
+ @comp.should match(@heff3)
197
+ end
198
+
199
+ it 'should not match records that do not equal the given value' do
200
+ @comp.should_not match(@heff1)
201
+ end
202
+ end
203
+
204
+ describe 'with a value coerced into the property primitive' do
205
+ before :all do
206
+ @comp = Comparison.new(:eql, Heffalump.striped, 'false')
207
+ end
208
+
209
+ it_should_behave_like 'A valid query condition'
210
+
211
+ it 'should match records that equal the given value' do
212
+ @comp.should match(@heff2)
213
+ @comp.should match(@heff3)
214
+ end
215
+
216
+ it 'should not match records that do not equal the given value' do
217
+ @comp.should_not match(@heff1)
218
+ end
219
+ end
220
+
221
+ describe 'with a value from a custom type' do
222
+ before :all do
223
+ @comp = Comparison.new(:eql, Heffalump.mass, 'Large')
224
+ end
225
+
226
+ it_should_behave_like 'A valid query condition'
227
+
228
+ it 'should match records that equal the given value' do
229
+ @comp.should match(@heff2)
230
+ end
231
+
232
+ it 'should not match records that do not equal the given value' do
233
+ @comp.should_not match(@heff1)
234
+ @comp.should_not match(@heff3)
235
+ end
236
+ end
237
+
238
+ describe 'with a relationship subject' do
239
+ before :all do
240
+ @comp = Comparison.new(:eql, Heffalump.relationships[:parent], @heff1)
241
+ end
242
+
243
+ it_should_behave_like 'A valid query condition'
244
+
245
+ it 'should match records that equal the given value' do
246
+ @comp.should match(@heff2)
247
+ end
248
+
249
+ it 'should not match records that do not equal the given value' do
250
+ @comp.should_not match(@heff1)
251
+ @comp.should_not match(@heff3)
252
+ end
253
+ end
254
+
255
+ describe 'with a relationship subject using a custom type key' do
256
+ before :all do
257
+ @comp = Comparison.new(:eql, Heffalump.relationships[:mass_mates], @heff1)
258
+ end
259
+
260
+ it_should_behave_like 'A valid query condition'
261
+
262
+ it 'should match records that equal the given value' do
263
+ @comp.should match(Heffalump.new(:id => 4, :mass => 'Small'))
264
+ @comp.should match(@heff1)
265
+ end
266
+
267
+ it 'should not match records that do not equal the given value' do
268
+ @comp.should_not match(@heff2)
269
+ @comp.should_not match(@heff3)
270
+ end
271
+ end
272
+ end
273
+
274
+ describe 'InclusionComparison' do
275
+ describe 'with a value matching the property primitive' do
276
+ before :all do
277
+ @comp = Comparison.new(:in, Heffalump.num_spots, 1..2)
278
+ end
279
+
280
+ it_should_behave_like 'A valid query condition'
281
+
282
+ it 'should match records that equal the given value' do
283
+ @comp.should match(@heff1)
284
+ @comp.should match(@heff2)
285
+ end
286
+
287
+ it 'should not match records that do not equal the given value' do
288
+ @comp.should_not match(@heff3)
289
+ end
290
+ end
291
+
292
+ describe 'with a value coerced into the property primitive' do
293
+ before :all do
294
+ @comp = Comparison.new(:in, Heffalump.num_spots, '1'..'2')
295
+ end
296
+
297
+ it_should_behave_like 'A valid query condition'
298
+
299
+ it 'should match records that equal the given value' do
300
+ @comp.should match(@heff1)
301
+ @comp.should match(@heff2)
302
+ end
303
+
304
+ it 'should not match records that do not equal the given value' do
305
+ @comp.should_not match(@heff3)
306
+ end
307
+ end
308
+
309
+ describe 'with a value from a custom type' do
310
+ before :all do
311
+ @comp = Comparison.new(:in, Heffalump.mass, ['Small', 'Large'])
312
+ end
313
+
314
+ it_should_behave_like 'A valid query condition'
315
+
316
+ it 'should match records that equal the given value' do
317
+ @comp.should match(@heff1)
318
+ @comp.should match(@heff2)
319
+ end
320
+
321
+ it 'should not match records that do not equal the given value' do
322
+ @comp.should_not match(@heff3)
323
+ end
324
+ end
325
+
326
+ describe 'with a relationship subject' do
327
+ before :all do
328
+ @comp = Comparison.new(:in, Heffalump.relationships[:parent], [@heff1, @heff2])
329
+ end
330
+
331
+ it_should_behave_like 'A valid query condition'
332
+
333
+ it 'should match records that equal the given value' do
334
+ @comp.should match(@heff2)
335
+ @comp.should match(@heff3)
336
+ end
337
+
338
+ it 'should not match records that do not equal the given value' do
339
+ @comp.should_not match(@heff1)
340
+ end
341
+ end
342
+
343
+ describe 'with a relationship subject using a custom type key' do
344
+ before :all do
345
+ @comp = Comparison.new(:in, Heffalump.relationships[:mass_mates], [@heff1, @heff2])
346
+ end
347
+
348
+ it_should_behave_like 'A valid query condition'
349
+
350
+ it 'should match records that equal the given value' do
351
+ @comp.should match(Heffalump.new(:mass => 'Small'))
352
+ @comp.should match(Heffalump.new(:mass => 'Large'))
353
+ @comp.should match(@heff1)
354
+ @comp.should match(@heff2)
355
+ end
356
+
357
+ it 'should not match records that do not equal the given value' do
358
+ @comp.should_not match(@heff3)
359
+ end
360
+ end
361
+ end
362
+
363
+ describe 'GreaterThanComparison' do
364
+ describe 'with a value matching the property primitive' do
365
+ before :all do
366
+ @comp = Comparison.new(:gt, Heffalump.num_spots, 2)
367
+ end
368
+
369
+ it_should_behave_like 'A valid query condition'
370
+
371
+ it 'should match records that are greater than the given value' do
372
+ @comp.should match(@heff3)
373
+ end
374
+
375
+ it 'should not match records that are not greater than the given value' do
376
+ @comp.should_not match(@heff1)
377
+ @comp.should_not match(@heff2)
378
+ end
379
+ end
380
+
381
+ describe 'with a value coerced into the property primitive' do
382
+ before :all do
383
+ @comp = Comparison.new(:gt, Heffalump.num_spots, '2')
384
+ end
385
+
386
+ it_should_behave_like 'A valid query condition'
387
+
388
+ it 'should match records that are greater than the given value' do
389
+ @comp.should match(@heff3)
390
+ end
391
+
392
+ it 'should not match records that are not greater than the given value' do
393
+ @comp.should_not match(@heff1)
394
+ @comp.should_not match(@heff2)
395
+ end
396
+ end
397
+ end
398
+
399
+ describe 'GreaterThanOrEqualToComparison' do
400
+ describe 'with a value matching the property primitive' do
401
+ before :all do
402
+ @comp = Comparison.new(:gte, Heffalump.num_spots, 2)
403
+ end
404
+
405
+ it_should_behave_like 'A valid query condition'
406
+
407
+ it 'should match records that are greater than or equal to the given value' do
408
+ @comp.should match(@heff2)
409
+ @comp.should match(@heff3)
410
+ end
411
+
412
+ it 'should not match records that are not greater than or equal to the given value' do
413
+ @comp.should_not match(@heff1)
414
+ end
415
+ end
416
+
417
+ describe 'with a value coerced into the property primitive' do
418
+ before :all do
419
+ @comp = Comparison.new(:gte, Heffalump.num_spots, 2.0)
420
+ end
421
+
422
+ it_should_behave_like 'A valid query condition'
423
+
424
+ it 'should match records that are greater than or equal to the given value' do
425
+ @comp.should match(@heff2)
426
+ @comp.should match(@heff3)
427
+ end
428
+
429
+ it 'should not match records that are not greater than or equal to the given value' do
430
+ @comp.should_not match(@heff1)
431
+ end
432
+ end
433
+ end
434
+
435
+ describe 'LessThanComparison' do
436
+ describe 'with a value matching the property primitive' do
437
+ before :all do
438
+ @comp = Comparison.new(:lt, Heffalump.num_spots, 2)
439
+ end
440
+
441
+ it_should_behave_like 'A valid query condition'
442
+
443
+ it 'should match records that are less than the given value' do
444
+ @comp.should match(@heff1)
445
+ end
446
+
447
+ it 'should not match records that are not less than the given value' do
448
+ @comp.should_not match(@heff2)
449
+ @comp.should_not match(@heff3)
450
+ end
451
+ end
452
+
453
+ describe 'with a value coerced into the property primitive' do
454
+ before :all do
455
+ @comp = Comparison.new(:lt, Heffalump.num_spots, BigDecimal('2.0'))
456
+ end
457
+
458
+ it_should_behave_like 'A valid query condition'
459
+
460
+ it 'should match records that are less than the given value' do
461
+ @comp.should match(@heff1)
462
+ end
463
+
464
+ it 'should not match records that are not less than the given value' do
465
+ @comp.should_not match(@heff2)
466
+ @comp.should_not match(@heff3)
467
+ end
468
+ end
469
+ end
470
+
471
+ describe 'LessThanOrEqualToComparison' do
472
+ describe 'with a value matching the property primitive' do
473
+ before :all do
474
+ @comp = Comparison.new(:lte, Heffalump.num_spots, 2)
475
+ end
476
+
477
+ it_should_behave_like 'A valid query condition'
478
+
479
+ it 'should match records that are less than or equal to the given value' do
480
+ @comp.should match(@heff1)
481
+ @comp.should match(@heff2)
482
+ end
483
+
484
+ it 'should not match records that are not less than or equal to the given value' do
485
+ @comp.should_not match(@heff3)
486
+ end
487
+ end
488
+
489
+ describe 'with a value coerced into the property primitive' do
490
+ before :all do
491
+ @comp = Comparison.new(:lte, Heffalump.num_spots, '2')
492
+ end
493
+
494
+ it_should_behave_like 'A valid query condition'
495
+
496
+ it 'should match records that are less than or equal to the given value' do
497
+ @comp.should match(@heff1)
498
+ @comp.should match(@heff2)
499
+ end
500
+
501
+ it 'should not match records that are not less than or equal to the given value' do
502
+ @comp.should_not match(@heff3)
503
+ end
504
+ end
505
+ end
506
+
507
+ describe 'RegexpComparison' do
508
+ before :all do
509
+ @comp = Comparison.new(:regexp, Heffalump.color, /green/)
510
+ @heff2.color = 'forest green'
511
+ end
512
+
513
+ it_should_behave_like 'A valid query condition'
514
+
515
+ it 'should match records that match the regexp' do
516
+ @comp.should match(@heff1)
517
+ @comp.should match(@heff2)
518
+ end
519
+
520
+ it "should not match records that don't match the regexp" do
521
+ @comp.should_not match(@heff3)
522
+ end
523
+
524
+ end
525
+
526
+ end
527
+
528
+ end