dm-rinda-adapter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,331 @@
1
+
2
+ require 'rubygems'; require 'ruby-debug';
3
+
4
+ share_examples_for 'An Adapter' do
5
+
6
+ def self.adapter_supports?(*methods)
7
+ methods.all? do |method|
8
+ # TODO: figure out a way to see if the instance method is only inherited
9
+ # from the Abstract Adapter, and not defined in it's class. If that is
10
+ # the case return false
11
+
12
+ # CRUD methods can be inherited from parent class
13
+ described_type.instance_methods.any? { |instance_method| method.to_s == instance_method.to_s }
14
+ end
15
+ end
16
+
17
+ before :all do
18
+ raise '+@adapter+ should be defined in before block' unless instance_variable_get('@adapter')
19
+
20
+ class ::Heffalump
21
+ include DataMapper::Resource
22
+
23
+ property :id, Serial
24
+ property :color, String
25
+ property :num_spots, Integer
26
+ property :striped, Boolean
27
+ end
28
+
29
+
30
+ # create all tables and constraints before each spec
31
+ if @repository.respond_to?(:auto_migrate!)
32
+ Heffalump.auto_migrate!
33
+ end
34
+ end
35
+
36
+ if adapter_supports?(:create)
37
+ describe '#create' do
38
+ it 'should not raise any errors' do
39
+ lambda {
40
+ Heffalump.create(:color => 'peach')
41
+ }.should_not raise_error
42
+ end
43
+
44
+ it 'should set the identity field for the resource' do
45
+ heffalump = Heffalump.new(:color => 'peach')
46
+ heffalump.id.should be_nil
47
+ heffalump.save
48
+ heffalump.id.should_not be_nil
49
+ end
50
+ end
51
+ else
52
+ it 'needs to support #create'
53
+ end
54
+
55
+ if adapter_supports?(:read)
56
+ describe '#read' do
57
+ before :all do
58
+ @heffalump = Heffalump.create(:color => 'brownish hue')
59
+ #just going to borrow this, so I can check the return values
60
+ @query = Heffalump.all.query
61
+ end
62
+
63
+ it 'should not raise any errors' do
64
+ lambda {
65
+ Heffalump.all()
66
+ }.should_not raise_error
67
+ end
68
+
69
+ it 'should return stuff' do
70
+ Heffalump.all.should be_include(@heffalump)
71
+ end
72
+ end
73
+ else
74
+ it 'needs to support #read'
75
+ end
76
+
77
+ if adapter_supports?(:update)
78
+ describe '#update' do
79
+ before do
80
+ @heffalump = Heffalump.create(:color => 'indigo')
81
+ end
82
+
83
+ it 'should not raise any errors' do
84
+ lambda {
85
+ @heffalump.color = 'violet'
86
+ @heffalump.save
87
+ }.should_not raise_error
88
+ end
89
+
90
+ it 'should not alter the identity field' do
91
+ id = @heffalump.id
92
+ @heffalump.color = 'violet'
93
+ @heffalump.save
94
+ @heffalump.id.should == id
95
+ end
96
+
97
+ it 'should update altered fields' do
98
+ @heffalump.color = 'violet'
99
+ @heffalump.save
100
+ Heffalump.get(*@heffalump.key).color.should == 'violet'
101
+ end
102
+
103
+ it 'should not alter other fields' do
104
+ color = @heffalump.color
105
+ @heffalump.num_spots = 3
106
+ @heffalump.save
107
+ Heffalump.get(*@heffalump.key).color.should == color
108
+ end
109
+ end
110
+ else
111
+ it 'needs to support #update'
112
+ end
113
+
114
+ if adapter_supports?(:delete)
115
+ describe '#delete' do
116
+ before do
117
+ @heffalump = Heffalump.create(:color => 'forest green')
118
+ end
119
+
120
+ it 'should not raise any errors' do
121
+ lambda {
122
+ @heffalump.destroy
123
+ }.should_not raise_error
124
+ end
125
+
126
+ it 'should delete the requested resource' do
127
+ id = @heffalump.id
128
+ @heffalump.destroy
129
+ Heffalump.get(id).should be_nil
130
+ end
131
+ end
132
+ else
133
+ it 'needs to support #delete'
134
+ end
135
+
136
+ if adapter_supports?(:read, :create)
137
+ describe 'query matching' do
138
+ before :all do
139
+ @red = Heffalump.create(:color => 'red')
140
+ @two = Heffalump.create( :num_spots => 2)
141
+ @five = Heffalump.create(:num_spots => 5)
142
+ end
143
+
144
+ describe 'conditions' do
145
+ describe 'eql' do
146
+ it 'should be able to search for objects included in an inclusive range of values' do
147
+ Heffalump.all(:num_spots => 1..5).should be_include(@five)
148
+ end
149
+
150
+ it 'should be able to search for objects included in an exclusive range of values' do
151
+ Heffalump.all(:num_spots => 1...6).should be_include(@five)
152
+ end
153
+
154
+ it 'should not be able to search for values not included in an inclusive range of values' do
155
+ Heffalump.all(:num_spots => 1..4).should_not be_include(@five)
156
+ end
157
+
158
+ it 'should not be able to search for values not included in an exclusive range of values' do
159
+ Heffalump.all(:num_spots => 1...5).should_not be_include(@five)
160
+ end
161
+ end
162
+
163
+ describe 'not' do
164
+ it 'should be able to search for objects with not equal value' do
165
+ Heffalump.all(:color.not => 'red').should_not be_include(@red)
166
+ end
167
+
168
+ it 'should include objects that are not like the value' do
169
+ Heffalump.all(:color.not => 'black').should be_include(@red)
170
+ end
171
+
172
+ it 'should be able to search for objects with not nil value' do
173
+ Heffalump.all(:color.not => nil).should be_include(@red)
174
+ end
175
+
176
+ it 'should not include objects with a nil value' do
177
+ Heffalump.all(:color.not => nil).should_not be_include(@two)
178
+ end
179
+
180
+ it 'should be able to search for object with a nil value using required properties' do
181
+ Heffalump.all(:id.not => nil).should == [ @red, @two, @five ]
182
+ end
183
+
184
+ it 'should be able to search for objects not in an empty list (match all)' do
185
+ Heffalump.all(:color.not => []).should == [ @red, @two, @five ]
186
+ end
187
+
188
+ # it 'should be able to search for object with a nil value using required properties' do
189
+ # r = Heffalump.all(:id.not => nil)
190
+ # r.should be_include @red
191
+ # r.should be_include @two
192
+ # r.should be_include @five
193
+ # r.length.should == 3
194
+ # end
195
+
196
+ #it 'should be able to search for objects not in an empty list (match all)' do
197
+ # r=Heffalump.all(:color.not => [])
198
+ # r.should be_include @red
199
+ # r.should be_include @two
200
+ # r.should be_include @five
201
+ # r.length.should == 3
202
+ #end
203
+
204
+ it 'should be able to search for objects in an empty list and another OR condition (match none on the empty list)' do
205
+ Heffalump.all(:conditions => DataMapper::Query::Conditions::Operation.new(
206
+ :or,
207
+ DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:color], []),
208
+ DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:num_spots], [5]))).should == [ @five ]
209
+ end
210
+
211
+ it 'should be able to search for objects not included in an array of values' do
212
+ Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should be_include(@two)
213
+ end
214
+
215
+ it 'should be able to search for objects not included in an array of values' do
216
+ Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should_not be_include(@five)
217
+ end
218
+
219
+ it 'should be able to search for objects not included in an inclusive range of values' do
220
+ Heffalump.all(:num_spots.not => 1..4).should be_include(@five)
221
+ end
222
+
223
+ it 'should be able to search for objects not included in an exclusive range of values' do
224
+ Heffalump.all(:num_spots.not => 1...5).should be_include(@five)
225
+ end
226
+
227
+ it 'should not be able to search for values not included in an inclusive range of values' do
228
+ Heffalump.all(:num_spots.not => 1..5).should_not be_include(@five)
229
+ end
230
+
231
+ it 'should not be able to search for values not included in an exclusive range of values' do
232
+ Heffalump.all(:num_spots.not => 1...6).should_not be_include(@five)
233
+ end
234
+ end
235
+
236
+ describe 'like' do
237
+ it 'should be able to search for objects that match value' do
238
+ Heffalump.all(:color.like => '%ed').should be_include(@red)
239
+ end
240
+
241
+ it 'should not search for objects that do not match the value' do
242
+ Heffalump.all(:color.like => '%blak%').should_not be_include(@red)
243
+ end
244
+ end
245
+
246
+ describe 'regexp' do
247
+ before do
248
+ if (defined?(DataMapper::Adapters::Sqlite3Adapter) && @adapter.kind_of?(DataMapper::Adapters::Sqlite3Adapter) ||
249
+ defined?(DataMapper::Adapters::SqlserverAdapter) && @adapter.kind_of?(DataMapper::Adapters::SqlserverAdapter))
250
+ pending 'delegate regexp matches to same system that the InMemory and YAML adapters use'
251
+ end
252
+ end
253
+
254
+ it 'should be able to search for objects that match value' do
255
+ Heffalump.all(:color => /ed/).should be_include(@red)
256
+ end
257
+
258
+ it 'should not be able to search for objects that do not match the value' do
259
+ Heffalump.all(:color => /blak/).should_not be_include(@red)
260
+ end
261
+
262
+ it 'should be able to do a negated search for objects that match value' do
263
+ Heffalump.all(:color.not => /blak/).should be_include(@red)
264
+ end
265
+
266
+ it 'should not be able to do a negated search for objects that do not match value' do
267
+ Heffalump.all(:color.not => /ed/).should_not be_include(@red)
268
+ end
269
+
270
+ end
271
+
272
+ describe 'gt' do
273
+ it 'should be able to search for objects with value greater than' do
274
+ Heffalump.all(:num_spots.gt => 1).should be_include(@two)
275
+ end
276
+
277
+ it 'should not find objects with a value less than' do
278
+ Heffalump.all(:num_spots.gt => 3).should_not be_include(@two)
279
+ end
280
+ end
281
+
282
+ describe 'gte' do
283
+ it 'should be able to search for objects with value greater than' do
284
+ Heffalump.all(:num_spots.gte => 1).should be_include(@two)
285
+ end
286
+
287
+ it 'should be able to search for objects with values equal to' do
288
+ Heffalump.all(:num_spots.gte => 2).should be_include(@two)
289
+ end
290
+
291
+ it 'should not find objects with a value less than' do
292
+ Heffalump.all(:num_spots.gte => 3).should_not be_include(@two)
293
+ end
294
+ end
295
+
296
+ describe 'lt' do
297
+ it 'should be able to search for objects with value less than' do
298
+ Heffalump.all(:num_spots.lt => 3).should be_include(@two)
299
+ end
300
+
301
+ it 'should not find objects with a value less than' do
302
+ Heffalump.all(:num_spots.gt => 2).should_not be_include(@two)
303
+ end
304
+ end
305
+
306
+ describe 'lte' do
307
+ it 'should be able to search for objects with value less than' do
308
+ Heffalump.all(:num_spots.lte => 3).should be_include(@two)
309
+ end
310
+
311
+ it 'should be able to search for objects with values equal to' do
312
+ Heffalump.all(:num_spots.lte => 2).should be_include(@two)
313
+ end
314
+
315
+ it 'should not find objects with a value less than' do
316
+ Heffalump.all(:num_spots.lte => 1).should_not be_include(@two)
317
+ end
318
+ end
319
+ end
320
+
321
+ describe 'limits' do
322
+ it 'should be able to limit the objects' do
323
+ Heffalump.all(:limit => 2).length.should == 2
324
+ end
325
+ end
326
+
327
+ end
328
+ else
329
+ it 'needs to support #read and #create to test query matching'
330
+ end
331
+ end
@@ -0,0 +1,3 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+ $db = DataMapper::Mongo::Spec.database(:default)
3
+ include DataMapper::Mongo
@@ -0,0 +1,105 @@
1
+ require "benchmark"
2
+
3
+ module DataMapper::Spec
4
+ module AdapterHelpers
5
+ def self.current_adapters
6
+ @current_adapters ||= []
7
+ end
8
+
9
+ def supported_by(*adapters, &block)
10
+ adapters = get_adapters(*adapters)
11
+
12
+ PRIMARY.only(*adapters).each do |adapter, connection_uri|
13
+ # keep track of the current adapters
14
+ AdapterHelpers.current_adapters << adapters
15
+
16
+ describe("with #{adapter}") do
17
+
18
+ before :all do
19
+ # store these in instance vars for the shared adapter specs
20
+ @adapter = DataMapper.setup(:default, connection_uri)
21
+ @repository = DataMapper.repository(@adapter.name)
22
+
23
+ # create all tables and constraints before each spec
24
+ if @repository.respond_to?(:auto_migrate!)
25
+ @repository.auto_migrate!
26
+ end
27
+ end
28
+
29
+ after :all do
30
+ # remove all tables and constraints after each spec
31
+ if DataMapper.respond_to?(:auto_migrate_down!, true)
32
+ DataMapper.send(:auto_migrate_down!, @repository.name)
33
+ end
34
+ end
35
+
36
+ # TODO: add destroy_model_storage and migrations code
37
+ # that removes the YAML file and remove this code
38
+ after :all do
39
+ if defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
40
+ descendants = DataMapper::Model.descendants.to_a
41
+ while model = descendants.shift
42
+ descendants.concat(model.descendants.to_a - [ model ])
43
+
44
+ model.default_scope.clear
45
+ model.all(:repository => @repository).destroy!
46
+ end
47
+ end
48
+ end
49
+
50
+ self.instance_eval(&block)
51
+ end
52
+
53
+ AdapterHelpers.current_adapters.pop
54
+ end
55
+ end
56
+
57
+ def with_alternate_adapter(&block)
58
+ adapters = AdapterHelpers.current_adapters.last
59
+
60
+ ALTERNATE.only(*adapters).each do |adapter, connection_uri|
61
+ describe("and #{adapter}") do
62
+
63
+ before :all do
64
+ @alternate_adapter = DataMapper.setup(:alternate, connection_uri)
65
+ @alternate_repository = DataMapper.repository(@alternate_adapter.name)
66
+
67
+ # create all tables and constraints before each spec
68
+ if @alternate_repository.respond_to?(:auto_migrate!)
69
+ @alternate_repository.auto_migrate!
70
+ end
71
+ end
72
+
73
+ after :all do
74
+ # remove all tables and constraints after each spec
75
+ if DataMapper.respond_to?(:auto_migrate_down!, true)
76
+ DataMapper.send(:auto_migrate_down!, @alternate_repository.name)
77
+ end
78
+ end
79
+
80
+ # TODO: add destroy_model_storage and migrations code
81
+ # that removes the YAML file and remove this code
82
+ after :all do
83
+ if defined?(DataMapper::Adapters::YamlAdapter) && @alternate_adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
84
+ descendants = DataMapper::Model.descendants.to_a
85
+ while model = descendants.shift
86
+ descendants.concat(model.descendants.to_a - [ model ])
87
+
88
+ model.default_scope.clear
89
+ model.all(:repository => @alternate_repository).destroy!
90
+ end
91
+ end
92
+ end
93
+
94
+ self.instance_eval(&block)
95
+ end
96
+ end
97
+ end
98
+
99
+ def get_adapters(*adapters)
100
+ adapters.map! { |adapter_name| adapter_name.to_s }
101
+ adapters = ADAPTERS if adapters.include?('all')
102
+ ADAPTERS & adapters
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,18 @@
1
+ module DataMapper::Spec
2
+ module CollectionHelpers
3
+ module GroupMethods
4
+ def self.extended(base)
5
+ base.class_inheritable_accessor :loaded
6
+ base.loaded = false
7
+ end
8
+
9
+ def should_not_be_a_kicker(ivar = :@articles)
10
+ unless loaded
11
+ it 'should not be a kicker' do
12
+ instance_variable_get(ivar).should_not be_loaded
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ class CounterAdapter < DataMapper::Adapters::AbstractAdapter
2
+ instance_methods.each { |method| undef_method method unless %w[ __id__ __send__ send class dup object_id kind_of? instance_of? respond_to? equal? assert_kind_of should should_not instance_variable_set instance_variable_get extend ].include?(method.to_s) }
3
+
4
+ attr_reader :counts
5
+
6
+ def kind_of?(klass)
7
+ super || @adapter.kind_of?(klass)
8
+ end
9
+
10
+ def instance_of?(klass)
11
+ super || @adapter.instance_of?(klass)
12
+ end
13
+
14
+ def respond_to?(method, include_private = false)
15
+ super || @adapter.respond_to?(method, include_private)
16
+ end
17
+
18
+ private
19
+
20
+ def initialize(adapter)
21
+ @counts = Hash.new { |hash, key| hash[key] = 0 }
22
+ @adapter = adapter
23
+ @count = 0
24
+ end
25
+
26
+ def increment_count_for(method)
27
+ @counts[method] += 1
28
+ end
29
+
30
+ def method_missing(method, *args, &block)
31
+ increment_count_for(method)
32
+ @adapter.send(method, *args, &block)
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ module DataMapper::Spec
2
+ module PendingHelpers
3
+ def pending_if(*args)
4
+ message, boolean = parse_args(*args)
5
+
6
+ if boolean
7
+ pending(message) { yield }
8
+ else
9
+ yield
10
+ end
11
+ end
12
+
13
+ def rescue_if(*args)
14
+ message, boolean = parse_args(*args)
15
+
16
+ if boolean
17
+ raised = nil
18
+ begin
19
+ yield
20
+ raised = false
21
+ rescue Exception
22
+ raised = true
23
+ end
24
+
25
+ raise "should have raised: #{message || 'TODO'}" if raised == false
26
+ else
27
+ yield
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def parse_args(*args)
34
+ case args.map { |arg| arg.class }
35
+ when [ String, TrueClass ], [ String, FalseClass ] then args
36
+ when [ String, NilClass ] then [ args.first, false ]
37
+ when [ String ] then [ args.first, true ]
38
+ when [ TrueClass ], [ FalseClass ] then [ '', args.first ]
39
+ when [ NilClass ] then [ '', false ]
40
+ when [] then [ '', true ] # defaults
41
+ else
42
+ raise ArgumentError, "Invalid arguments: #{args.inspect}"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec/runner/formatter/base_text_formatter'
2
+
3
+ # Code is based on standard SpecdocFormatter, but will print full error details as soon as they are found.
4
+ # Successful or pending examples are written only as a dot in the output. Header is only printed if errors occur.
5
+ #
6
+ # To use it, add the following to your spec/spec.opts:
7
+ # --require
8
+ # lib/rspec_immediate_feedback_formatter.rb
9
+ # --format
10
+ # Spec::Runner::Formatter::ImmediateFeedbackFormatter
11
+
12
+ module Spec
13
+ module Runner
14
+ module Formatter
15
+ class ImmediateFeedbackFormatter < BaseTextFormatter
16
+
17
+ def add_example_group(example_group)
18
+ super
19
+ @current_group = example_group.description
20
+ end
21
+
22
+ def example_failed(example, counter, failure)
23
+ if @current_group
24
+ output.puts
25
+ output.puts @current_group
26
+ @current_group = nil # only print the group name once
27
+ end
28
+
29
+ message = if failure.expectation_not_met?
30
+ "- #{example.description} (FAILED - #{counter})"
31
+ else
32
+ "- #{example.description} (ERROR - #{counter})"
33
+ end
34
+
35
+ output.puts(red(message))
36
+ # output.puts(failure.expectation_not_met? ? red(message) : message)
37
+ dump_failure(counter, failure) # dump stacktrace immediately
38
+ output.flush
39
+ end
40
+
41
+ def example_passed(*)
42
+ output.print green('.')
43
+ output.flush
44
+ end
45
+
46
+ def example_pending(*)
47
+ super
48
+ output.print yellow('*')
49
+ output.flush
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1,6 @@
1
+ --exclude "spec"
2
+ --sort coverage
3
+ --callsites
4
+ --xrefs
5
+ --profile
6
+ --text-summary