dm-core 0.9.11 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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