dm-persevere-adapter 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/model_json_support.rb +51 -0
- data/lib/persevere.rb +9 -10
- data/lib/persevere_adapter.rb +150 -19
- data/spec/adapter_shared_spec.rb +311 -0
- data/spec/lib/adapter_helpers.rb +105 -0
- data/spec/persevere_adapter_spec.rb +120 -61
- data/spec/persevere_spec.rb +6 -7
- data/spec/spec_helper.rb +52 -14
- data/spec/unit/create_spec.rb +13 -0
- metadata +70 -65
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.18.0
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Model
|
3
|
+
# module Json
|
4
|
+
def to_json_schema(repository_name = default_repository_name)
|
5
|
+
to_json_schema_compatible_hash(repository_name).to_json
|
6
|
+
end
|
7
|
+
|
8
|
+
#TODO: Add various options in.
|
9
|
+
def to_json_schema_compatible_hash(repository_name = default_repository_name)
|
10
|
+
usable_properties = properties.select{|p| p.name != :id }
|
11
|
+
schema_hash = {}
|
12
|
+
schema_hash['id'] = self.storage_name(repository_name)
|
13
|
+
properties_hash = {}
|
14
|
+
usable_properties.each{|p| properties_hash[p.name] = p.to_json_schema_hash if p.name != :id }
|
15
|
+
schema_hash['properties'] = properties_hash
|
16
|
+
return schema_hash
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class Property
|
22
|
+
def to_json_schema_hash
|
23
|
+
json_hash = { "type" => to_json_type }
|
24
|
+
{ "optional" => true }.merge(json_hash) unless required? == true
|
25
|
+
# MIN
|
26
|
+
# MAX
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def to_json_type
|
32
|
+
# A case statement doesn't seem to be working when comparing classes.
|
33
|
+
# That's why we're using a if elseif block.
|
34
|
+
if type == DataMapper::Types::Serial
|
35
|
+
return "string"
|
36
|
+
elsif type == String
|
37
|
+
return "string"
|
38
|
+
elsif type == Float
|
39
|
+
return "number"
|
40
|
+
elsif type == DataMapper::Types::Boolean
|
41
|
+
return "boolean"
|
42
|
+
elsif type == DataMapper::Types::Text
|
43
|
+
elsif type == "string"
|
44
|
+
elsif type == Integer
|
45
|
+
return "integer"
|
46
|
+
else
|
47
|
+
return"string"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/persevere.rb
CHANGED
@@ -34,10 +34,9 @@ class PersevereResult
|
|
34
34
|
end
|
35
35
|
|
36
36
|
class Persevere
|
37
|
-
VERSION = '1.1'
|
38
37
|
HEADERS = { 'Accept' => 'application/json',
|
39
38
|
'Content-Type' => 'application/json'
|
40
|
-
}
|
39
|
+
} unless defined?(HEADERS)
|
41
40
|
|
42
41
|
attr_accessor :server_url, :pservr
|
43
42
|
|
@@ -49,12 +48,12 @@ class Persevere
|
|
49
48
|
end
|
50
49
|
|
51
50
|
# Pass in a resource hash
|
52
|
-
def create(path, resource)
|
51
|
+
def create(path, resource, headers = {})
|
53
52
|
json_blob = resource.to_json
|
54
53
|
response = nil
|
55
54
|
while response.nil?
|
56
55
|
begin
|
57
|
-
response = @persevere.send_request('POST', path, json_blob, HEADERS)
|
56
|
+
response = @persevere.send_request('POST', path, json_blob, HEADERS.merge(headers))
|
58
57
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
59
58
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
60
59
|
puts "Persevere Create Failed: #{e}, Trying again."
|
@@ -63,11 +62,11 @@ class Persevere
|
|
63
62
|
return PersevereResult.make(response)
|
64
63
|
end
|
65
64
|
|
66
|
-
def retrieve(path)
|
65
|
+
def retrieve(path, headers = {})
|
67
66
|
response = nil
|
68
67
|
while response.nil?
|
69
68
|
begin
|
70
|
-
response = @persevere.send_request('GET', path, nil, HEADERS)
|
69
|
+
response = @persevere.send_request('GET', path, nil, HEADERS.merge(headers))
|
71
70
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
72
71
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
73
72
|
puts "Persevere Create Failed: #{e}, Trying again."
|
@@ -76,13 +75,13 @@ class Persevere
|
|
76
75
|
return PersevereResult.make(response)
|
77
76
|
end
|
78
77
|
|
79
|
-
def update(path, resource)
|
78
|
+
def update(path, resource, headers = {})
|
80
79
|
json_blob = resource.to_json
|
81
80
|
# puts "JSON to PERSEVERE: #{json_blob}"
|
82
81
|
response = nil
|
83
82
|
while response.nil?
|
84
83
|
begin
|
85
|
-
response = @persevere.send_request('PUT', path, json_blob, HEADERS)
|
84
|
+
response = @persevere.send_request('PUT', path, json_blob, HEADERS.merge(headers))
|
86
85
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
87
86
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
88
87
|
puts "Persevere Create Failed: #{e}, Trying again."
|
@@ -91,11 +90,11 @@ class Persevere
|
|
91
90
|
return PersevereResult.make(response)
|
92
91
|
end
|
93
92
|
|
94
|
-
def delete(path)
|
93
|
+
def delete(path, headers = {})
|
95
94
|
response = nil
|
96
95
|
while response.nil?
|
97
96
|
begin
|
98
|
-
response = @persevere.send_request('DELETE', path, nil, HEADERS)
|
97
|
+
response = @persevere.send_request('DELETE', path, nil, HEADERS.merge(headers))
|
99
98
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
100
99
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
101
100
|
puts "Persevere Create Failed: #{e}, Trying again."
|
data/lib/persevere_adapter.rb
CHANGED
@@ -3,11 +3,99 @@ require 'dm-core'
|
|
3
3
|
require 'extlib'
|
4
4
|
require 'json'
|
5
5
|
|
6
|
+
require 'model_json_support'
|
6
7
|
require 'persevere'
|
7
8
|
|
8
9
|
module DataMapper
|
10
|
+
module Migrations
|
11
|
+
module PersevereAdapter
|
12
|
+
# @api private
|
13
|
+
def self.included(base)
|
14
|
+
DataMapper.extend(Migrations::SingletonMethods)
|
15
|
+
|
16
|
+
[ :Repository, :Model ].each do |name|
|
17
|
+
DataMapper.const_get(name).send(:include, Migrations.const_get(name))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns whether the storage_name exists.
|
22
|
+
#
|
23
|
+
# @param [String] storage_name
|
24
|
+
# a String defining the name of a storage, for example a table name.
|
25
|
+
#
|
26
|
+
# @return [Boolean]
|
27
|
+
# true if the storage exists
|
28
|
+
#
|
29
|
+
# @api semipublic
|
30
|
+
def storage_exists?(storage_name)
|
31
|
+
class_names = JSON.parse(@persevere.retrieve('/Class/[=id]').body)
|
32
|
+
return true if class_names.include?("Class/"+storage_name)
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Creates the persevere schema from the model.
|
38
|
+
#
|
39
|
+
# @param [DataMapper::Model] model
|
40
|
+
# The model that corresponds to the storage schema that needs to be created.
|
41
|
+
#
|
42
|
+
# @api semipublic
|
43
|
+
def create_model_storage(model)
|
44
|
+
name = self.name
|
45
|
+
properties = model.properties_with_subclasses(name)
|
46
|
+
|
47
|
+
return false if storage_exists?(model.storage_name(name))
|
48
|
+
return false if properties.empty?
|
49
|
+
|
50
|
+
schema_hash = model.to_json_schema_compatible_hash
|
51
|
+
|
52
|
+
return true unless put_schema(schema_hash).nil?
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Updates the persevere schema from the model.
|
58
|
+
#
|
59
|
+
# @param [DataMapper::Model] model
|
60
|
+
# The model that corresponds to the storage schema that needs to be updated.
|
61
|
+
#
|
62
|
+
# @api semipublic
|
63
|
+
def upgrade_model_storage(model)
|
64
|
+
name = self.name
|
65
|
+
properties = model.properties_with_subclasses(name)
|
66
|
+
|
67
|
+
if success = create_model_storage(model)
|
68
|
+
return properties
|
69
|
+
end
|
70
|
+
|
71
|
+
table_name = model.storage_name(name)
|
72
|
+
schema_hash = model.to_json_schema_compatible_hash
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Destroys the persevere schema from the model.
|
77
|
+
#
|
78
|
+
# @param [DataMapper::Model] model
|
79
|
+
# The model that corresponds to the storage schema that needs to be destroyed.
|
80
|
+
#
|
81
|
+
# @api semipublic
|
82
|
+
def destroy_model_storage(model)
|
83
|
+
return true unless storage_exists?(model.storage_name(name))
|
84
|
+
schema_hash = model.to_json_schema_compatible_hash
|
85
|
+
return true unless delete_schema(schema_hash).nil?
|
86
|
+
false
|
87
|
+
end
|
88
|
+
|
89
|
+
end # module PersevereAdapter
|
90
|
+
end # module Migrations
|
91
|
+
|
9
92
|
module Adapters
|
10
93
|
class PersevereAdapter < AbstractAdapter
|
94
|
+
extend Chainable
|
95
|
+
extend Deprecate
|
96
|
+
|
97
|
+
include Migrations::PersevereAdapter
|
98
|
+
|
11
99
|
##
|
12
100
|
# Used by DataMapper to put records into a data-store: "INSERT"
|
13
101
|
# in SQL-speak. It takes an array of the resources (model
|
@@ -37,7 +125,7 @@ module DataMapper
|
|
37
125
|
tblname = resource.model.storage_name
|
38
126
|
|
39
127
|
path = "/#{tblname}/"
|
40
|
-
payload = resource.attributes
|
128
|
+
payload = resource.attributes.reject{ |key,value| value.nil? }
|
41
129
|
payload.delete(:id)
|
42
130
|
|
43
131
|
response = @persevere.create(path, payload)
|
@@ -98,7 +186,9 @@ module DataMapper
|
|
98
186
|
tblname = resource.model.storage_name
|
99
187
|
path = "/#{tblname}/#{resource.id}"
|
100
188
|
|
101
|
-
|
189
|
+
payload = resource.attributes.reject{ |key,value| value.nil? }
|
190
|
+
|
191
|
+
result = @persevere.update(path, payload)
|
102
192
|
|
103
193
|
if result.code == "200"
|
104
194
|
updated += 1
|
@@ -193,8 +283,6 @@ module DataMapper
|
|
193
283
|
resources = read_many(query)
|
194
284
|
end
|
195
285
|
|
196
|
-
puts resources.inspect
|
197
|
-
|
198
286
|
resources.each do |resource|
|
199
287
|
tblname = resource.model.storage_name
|
200
288
|
path = "/#{tblname}/#{resource.id}"
|
@@ -225,13 +313,13 @@ module DataMapper
|
|
225
313
|
path = "/Class/#{project}/#{name}"
|
226
314
|
end
|
227
315
|
|
228
|
-
|
229
|
-
|
230
|
-
if
|
231
|
-
return
|
316
|
+
result = @persevere.retrieve(path)
|
317
|
+
|
318
|
+
if result.code == "200"
|
319
|
+
return result.body
|
232
320
|
else
|
233
|
-
return
|
234
|
-
end
|
321
|
+
return false
|
322
|
+
end
|
235
323
|
end
|
236
324
|
|
237
325
|
def put_schema(schema_hash, project = nil)
|
@@ -246,16 +334,56 @@ module DataMapper
|
|
246
334
|
puts "You need an id key/value in the hash"
|
247
335
|
end
|
248
336
|
end
|
249
|
-
|
250
|
-
|
337
|
+
|
338
|
+
result = @persevere.create(path, schema_hash)
|
339
|
+
if result.code == '201'
|
340
|
+
return JSON.parse(result.body)
|
341
|
+
else
|
342
|
+
return false
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
def update_schema(schema_hash, project = nil)
|
347
|
+
|
348
|
+
id = schema_hash['id']
|
349
|
+
payload = schema_hash.reject{|key,value| key.to_sym.eql?(:id) }
|
350
|
+
|
251
351
|
|
252
|
-
if
|
253
|
-
|
352
|
+
if project.nil?
|
353
|
+
path = "/Class/#{id}"
|
254
354
|
else
|
255
|
-
|
256
|
-
end
|
355
|
+
path = "/Class/#{project}/#{id}"
|
356
|
+
end
|
357
|
+
# debugger
|
358
|
+
result = @persevere.update(path, payload)
|
359
|
+
|
360
|
+
if result.code == '200'
|
361
|
+
return result.body
|
362
|
+
else
|
363
|
+
return false
|
364
|
+
end
|
257
365
|
end
|
258
366
|
|
367
|
+
def delete_schema(schema_hash, project = nil)
|
368
|
+
if ! project.nil?
|
369
|
+
if schema_hash.has_key?("id")
|
370
|
+
if ! schema_hash['id'].index(project)
|
371
|
+
schema_hash['id'] = "#{project}/#{schema_hash['id']}"
|
372
|
+
end
|
373
|
+
else
|
374
|
+
puts "You need an id key/value in the hash"
|
375
|
+
end
|
376
|
+
end
|
377
|
+
path = "/Class/#{schema_hash['id']}"
|
378
|
+
result = @persevere.delete(path)
|
379
|
+
|
380
|
+
if result.code == "204"
|
381
|
+
return true
|
382
|
+
else
|
383
|
+
return false
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
259
387
|
private
|
260
388
|
|
261
389
|
##
|
@@ -383,6 +511,9 @@ module DataMapper
|
|
383
511
|
|
384
512
|
query
|
385
513
|
end
|
386
|
-
end
|
387
|
-
|
388
|
-
end
|
514
|
+
end # class PersevereAdapter
|
515
|
+
const_added(:PersevereAdapter)
|
516
|
+
end # module Adapters
|
517
|
+
|
518
|
+
|
519
|
+
end # module DataMapper
|
@@ -0,0 +1,311 @@
|
|
1
|
+
share_examples_for 'An Adapter Foo' do
|
2
|
+
|
3
|
+
def self.adapter_supports?(*methods)
|
4
|
+
methods.all? do |method|
|
5
|
+
# TODO: figure out a way to see if the instance method is only inherited
|
6
|
+
# from the Abstract Adapter, and not defined in it's class. If that is
|
7
|
+
# the case return false
|
8
|
+
|
9
|
+
# CRUD methods can be inherited from parent class
|
10
|
+
described_type.instance_methods.any? { |instance_method| method.to_s == instance_method.to_s }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
before :all do
|
15
|
+
raise '+@adapter+ should be defined in before block' unless instance_variable_get('@adapter')
|
16
|
+
|
17
|
+
class ::Heffalump
|
18
|
+
include DataMapper::Resource
|
19
|
+
|
20
|
+
property :id, Serial
|
21
|
+
property :color, String
|
22
|
+
property :num_spots, Integer
|
23
|
+
property :striped, Boolean
|
24
|
+
end
|
25
|
+
|
26
|
+
# create all tables and constraints before each spec
|
27
|
+
|
28
|
+
# if @repository.respond_to?(:auto_migrate!)
|
29
|
+
Heffalump.auto_migrate!
|
30
|
+
# end
|
31
|
+
end
|
32
|
+
|
33
|
+
if adapter_supports?(:create)
|
34
|
+
describe '#create' do
|
35
|
+
it 'should not raise any errors' do
|
36
|
+
lambda {
|
37
|
+
Heffalump.create(:color => 'peach')
|
38
|
+
}.should_not raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should set the identity field for the resource' do
|
42
|
+
heffalump = Heffalump.new(:color => 'peach')
|
43
|
+
heffalump.id.should be_nil
|
44
|
+
heffalump.save
|
45
|
+
heffalump.id.should_not be_nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
else
|
49
|
+
it 'needs to support #create'
|
50
|
+
end
|
51
|
+
|
52
|
+
if adapter_supports?(:read)
|
53
|
+
describe '#read' do
|
54
|
+
before :all do
|
55
|
+
@heffalump = Heffalump.create(:color => 'brownish hue')
|
56
|
+
#just going to borrow this, so I can check the return values
|
57
|
+
@query = Heffalump.all.query
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should not raise any errors' do
|
61
|
+
lambda {
|
62
|
+
Heffalump.all()
|
63
|
+
}.should_not raise_error
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should return stuff' do
|
67
|
+
Heffalump.all.should be_include(@heffalump)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
71
|
+
it 'needs to support #read'
|
72
|
+
end
|
73
|
+
|
74
|
+
if adapter_supports?(:update)
|
75
|
+
describe '#update' do
|
76
|
+
before do
|
77
|
+
@heffalump = Heffalump.create(:color => 'indigo')
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should not raise any errors' do
|
81
|
+
lambda {
|
82
|
+
@heffalump.color = 'violet'
|
83
|
+
@heffalump.save
|
84
|
+
}.should_not raise_error
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should not alter the identity field' do
|
88
|
+
id = @heffalump.id
|
89
|
+
@heffalump.color = 'violet'
|
90
|
+
@heffalump.save
|
91
|
+
@heffalump.id.should == id
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should update altered fields' do
|
95
|
+
@heffalump.color = 'violet'
|
96
|
+
@heffalump.save
|
97
|
+
Heffalump.get(*@heffalump.key).color.should == 'violet'
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should not alter other fields' do
|
101
|
+
color = @heffalump.color
|
102
|
+
@heffalump.num_spots = 3
|
103
|
+
@heffalump.save
|
104
|
+
Heffalump.get(*@heffalump.key).color.should == color
|
105
|
+
end
|
106
|
+
end
|
107
|
+
else
|
108
|
+
it 'needs to support #update'
|
109
|
+
end
|
110
|
+
|
111
|
+
if adapter_supports?(:delete)
|
112
|
+
describe '#delete' do
|
113
|
+
before do
|
114
|
+
@heffalump = Heffalump.create(:color => 'forest green')
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should not raise any errors' do
|
118
|
+
lambda {
|
119
|
+
@heffalump.destroy
|
120
|
+
}.should_not raise_error
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should delete the requested resource' do
|
124
|
+
id = @heffalump.id
|
125
|
+
@heffalump.destroy
|
126
|
+
Heffalump.get(id).should be_nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
it 'needs to support #delete'
|
131
|
+
end
|
132
|
+
|
133
|
+
if adapter_supports?(:read, :create)
|
134
|
+
describe 'query matching' do
|
135
|
+
before :all do
|
136
|
+
@red = Heffalump.create(:color => 'red')
|
137
|
+
@two = Heffalump.create(:num_spots => 2)
|
138
|
+
@five = Heffalump.create(:num_spots => 5)
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'conditions' do
|
142
|
+
describe 'eql' do
|
143
|
+
it 'should be able to search for objects included in an inclusive range of values' do
|
144
|
+
Heffalump.all(:num_spots => 1..5).should be_include(@five)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should be able to search for objects included in an exclusive range of values' do
|
148
|
+
Heffalump.all(:num_spots => 1...6).should be_include(@five)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should not be able to search for values not included in an inclusive range of values' do
|
152
|
+
Heffalump.all(:num_spots => 1..4).should_not be_include(@five)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should not be able to search for values not included in an exclusive range of values' do
|
156
|
+
Heffalump.all(:num_spots => 1...5).should_not be_include(@five)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe 'not' do
|
161
|
+
it 'should be able to search for objects with not equal value' do
|
162
|
+
Heffalump.all(:color.not => 'red').should_not be_include(@red)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should include objects that are not like the value' do
|
166
|
+
Heffalump.all(:color.not => 'black').should be_include(@red)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should be able to search for objects with not nil value' do
|
170
|
+
Heffalump.all(:color.not => nil).should be_include(@red)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should not include objects with a nil value' do
|
174
|
+
Heffalump.all(:color.not => nil).should_not be_include(@two)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should be able to search for object with a nil value using required properties' do
|
178
|
+
Heffalump.all(:id.not => nil).should == [ @red, @two, @five ]
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should be able to search for objects not in an empty list (match all)' do
|
182
|
+
Heffalump.all(:color.not => []).should == [ @red, @two, @five ]
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should be able to search for objects in an empty list and another OR condition (match none on the empty list)' do
|
186
|
+
Heffalump.all(:conditions => DataMapper::Query::Conditions::Operation.new(
|
187
|
+
:or,
|
188
|
+
DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:color], []),
|
189
|
+
DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:num_spots], [5]))).should == [ @five ]
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should be able to search for objects not included in an array of values' do
|
193
|
+
Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should be_include(@two)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'should be able to search for objects not included in an array of values' do
|
197
|
+
Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should_not be_include(@five)
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should be able to search for objects not included in an inclusive range of values' do
|
201
|
+
Heffalump.all(:num_spots.not => 1..4).should be_include(@five)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should be able to search for objects not included in an exclusive range of values' do
|
205
|
+
Heffalump.all(:num_spots.not => 1...5).should be_include(@five)
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'should not be able to search for values not included in an inclusive range of values' do
|
209
|
+
Heffalump.all(:num_spots.not => 1..5).should_not be_include(@five)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should not be able to search for values not included in an exclusive range of values' do
|
213
|
+
Heffalump.all(:num_spots.not => 1...6).should_not be_include(@five)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
describe 'like' do
|
218
|
+
it 'should be able to search for objects that match value' do
|
219
|
+
Heffalump.all(:color.like => '%ed').should be_include(@red)
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'should not search for objects that do not match the value' do
|
223
|
+
Heffalump.all(:color.like => '%blak%').should_not be_include(@red)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe 'regexp' do
|
228
|
+
before do
|
229
|
+
if (defined?(DataMapper::Adapters::Sqlite3Adapter) && @adapter.kind_of?(DataMapper::Adapters::Sqlite3Adapter) ||
|
230
|
+
defined?(DataMapper::Adapters::SqlserverAdapter) && @adapter.kind_of?(DataMapper::Adapters::SqlserverAdapter))
|
231
|
+
pending 'delegate regexp matches to same system that the InMemory and YAML adapters use'
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should be able to search for objects that match value' do
|
236
|
+
Heffalump.all(:color => /ed/).should be_include(@red)
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'should not be able to search for objects that do not match the value' do
|
240
|
+
Heffalump.all(:color => /blak/).should_not be_include(@red)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should be able to do a negated search for objects that match value' do
|
244
|
+
Heffalump.all(:color.not => /blak/).should be_include(@red)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should not be able to do a negated search for objects that do not match value' do
|
248
|
+
Heffalump.all(:color.not => /ed/).should_not be_include(@red)
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
|
253
|
+
describe 'gt' do
|
254
|
+
it 'should be able to search for objects with value greater than' do
|
255
|
+
Heffalump.all(:num_spots.gt => 1).should be_include(@two)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'should not find objects with a value less than' do
|
259
|
+
Heffalump.all(:num_spots.gt => 3).should_not be_include(@two)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe 'gte' do
|
264
|
+
it 'should be able to search for objects with value greater than' do
|
265
|
+
Heffalump.all(:num_spots.gte => 1).should be_include(@two)
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should be able to search for objects with values equal to' do
|
269
|
+
Heffalump.all(:num_spots.gte => 2).should be_include(@two)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should not find objects with a value less than' do
|
273
|
+
Heffalump.all(:num_spots.gte => 3).should_not be_include(@two)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe 'lt' do
|
278
|
+
it 'should be able to search for objects with value less than' do
|
279
|
+
Heffalump.all(:num_spots.lt => 3).should be_include(@two)
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should not find objects with a value less than' do
|
283
|
+
Heffalump.all(:num_spots.gt => 2).should_not be_include(@two)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe 'lte' do
|
288
|
+
it 'should be able to search for objects with value less than' do
|
289
|
+
Heffalump.all(:num_spots.lte => 3).should be_include(@two)
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'should be able to search for objects with values equal to' do
|
293
|
+
Heffalump.all(:num_spots.lte => 2).should be_include(@two)
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'should not find objects with a value less than' do
|
297
|
+
Heffalump.all(:num_spots.lte => 1).should_not be_include(@two)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe 'limits' do
|
303
|
+
it 'should be able to limit the objects' do
|
304
|
+
Heffalump.all(:limit => 2).length.should == 2
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
else
|
309
|
+
it 'needs to support #read and #create to test query matching'
|
310
|
+
end
|
311
|
+
end
|
@@ -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
|
@@ -1,47 +1,26 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
require 'pathname'
|
3
|
-
require 'rubygems'
|
4
|
-
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
5
2
|
gem 'rspec'
|
6
3
|
require 'spec'
|
7
|
-
|
8
|
-
require Pathname(__FILE__).dirname.expand_path.parent + 'lib/persevere_adapter'
|
9
|
-
|
10
|
-
DataMapper.setup(:default, {
|
11
|
-
:adapter => 'persevere',
|
12
|
-
:host => 'localhost',
|
13
|
-
:port => '8080',
|
14
|
-
:uri => 'http://localhost:8080'
|
15
|
-
})
|
16
|
-
|
17
|
-
#
|
18
|
-
# I need to make the Book class for Books to relate to
|
19
|
-
#
|
20
|
-
|
21
|
-
class Book
|
22
|
-
include DataMapper::Resource
|
23
|
-
|
24
|
-
# Persevere only does id's as strings.
|
25
|
-
property :id, String, :serial => true
|
26
|
-
property :author, String
|
27
|
-
property :created_at, DateTime
|
28
|
-
property :title, String
|
29
|
-
end
|
30
|
-
|
31
|
-
require 'dm-core'
|
32
|
-
require 'extlib'
|
33
4
|
|
5
|
+
require 'ruby-debug'
|
34
6
|
require DataMapper.root / 'lib' / 'dm-core' / 'spec' / 'adapter_shared_spec'
|
35
7
|
require Pathname(__FILE__).dirname.expand_path.parent + 'lib/persevere_adapter'
|
36
8
|
|
37
9
|
describe DataMapper::Adapters::PersevereAdapter do
|
38
10
|
before :all do
|
39
11
|
# This needs to point to a valid persevere server
|
40
|
-
@adapter = DataMapper.setup(:default, { :adapter => 'persevere',
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
12
|
+
@adapter = DataMapper.setup(:default, { :adapter => 'persevere', :host => 'localhost', :port => '8080' })
|
13
|
+
|
14
|
+
class Bozon
|
15
|
+
include DataMapper::Resource
|
16
|
+
|
17
|
+
# Persevere only does id's as strings.
|
18
|
+
property :id, String, :serial => true
|
19
|
+
property :author, String
|
20
|
+
property :created_at, DateTime
|
21
|
+
property :title, String
|
22
|
+
end
|
23
|
+
|
45
24
|
@test_schema_hash = {
|
46
25
|
'id' => 'Vanilla',
|
47
26
|
'properties' => {
|
@@ -50,40 +29,120 @@ describe DataMapper::Adapters::PersevereAdapter do
|
|
50
29
|
'data' => { 'type' => 'string'}
|
51
30
|
}
|
52
31
|
}
|
53
|
-
end
|
54
32
|
|
55
|
-
|
33
|
+
@test_schema_hash_alt = {
|
34
|
+
'id' => 'test1/Vanilla',
|
35
|
+
'properties' => {
|
36
|
+
'cid' => {'type' => 'string' },
|
37
|
+
'parent' => { 'type' => 'string'},
|
38
|
+
'data' => { 'type' => 'string'}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
@test_schema_hash_mod = {
|
42
|
+
'id' => 'Vanilla',
|
43
|
+
'properties' => {
|
44
|
+
'cid' => {'type' => 'string' },
|
45
|
+
'newdata' => { 'type' => 'any'}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
@test_schema_hash_alt_mod = {
|
50
|
+
'id' => 'test1/Vanilla',
|
51
|
+
'properties' => {
|
52
|
+
'cid' => {'type' => 'string' },
|
53
|
+
'newdata' => { 'type' => 'any'}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
describe 'migrations' do
|
59
|
+
it 'should create the Bozon storage' do
|
60
|
+
Bozon.auto_migrate!
|
61
|
+
Bozon.auto_migrate_down!
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should destroy Create then Remove the Bozon Storage" do
|
65
|
+
@adapter.get_schema(Bozon.storage_name).should == false
|
66
|
+
Bozon.auto_migrate_up!
|
67
|
+
@adapter.get_schema(Bozon.storage_name).should_not == false
|
68
|
+
Bozon.auto_migrate_down!
|
69
|
+
@adapter.get_schema(Bozon.storage_name).should == false
|
70
|
+
end
|
71
|
+
end
|
61
72
|
|
62
|
-
|
63
|
-
@adapter.get_schema("Object")
|
64
|
-
end
|
73
|
+
it_should_behave_like 'An Adapter Foo'
|
65
74
|
|
66
|
-
|
67
|
-
|
68
|
-
|
75
|
+
describe '#put_schema' do
|
76
|
+
it 'should create the json schema for the hash' do
|
77
|
+
@adapter.put_schema(@test_schema_hash).should_not == false
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should create the json schema for the hash under the specified project' do
|
81
|
+
@adapter.put_schema(@test_schema_hash, "test").should_not == false
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should create the json schema for the hash under the specified project' do
|
85
|
+
@adapter.put_schema(@test_schema_hash_alt).should_not == false
|
86
|
+
end
|
87
|
+
end
|
69
88
|
|
70
|
-
|
71
|
-
|
72
|
-
|
89
|
+
describe '#get_schema' do
|
90
|
+
it 'should return all of the schemas (in json) if no name is provided' do
|
91
|
+
result = @adapter.get_schema()
|
92
|
+
result.should_not == false
|
93
|
+
JSON.parse(result).class.should == Array
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should return the json schema of the class specified' do
|
97
|
+
result = @adapter.get_schema("Object")
|
98
|
+
result.should_not == false
|
99
|
+
JSON.parse(result)["id"].should == "Object"
|
73
100
|
end
|
101
|
+
|
102
|
+
# I don't think we need these tests.
|
103
|
+
# it 'should return all of the schemas (in json) for a project if no name is provided' do
|
104
|
+
# result = @adapter.get_schema(nil, "Class")
|
105
|
+
# debugger
|
106
|
+
# result
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# it 'should return all of the schemas (in json) if no name is provided' do
|
110
|
+
# @adapter.get_schema("Object", "Class")
|
111
|
+
# end
|
112
|
+
end
|
74
113
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
114
|
+
describe '#update_schema' do
|
115
|
+
it 'should update a previously existing schema' do
|
116
|
+
result = @adapter.update_schema(@test_schema_hash_mod)
|
117
|
+
result.should_not == false
|
79
118
|
|
80
|
-
|
81
|
-
|
82
|
-
|
119
|
+
@test_schema_hash_mod['id'].should match(JSON.parse(result)['id'])
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should update a previously created schema under the specified project' do
|
123
|
+
result = @adapter.update_schema(@test_schema_hash_mod, "test")
|
124
|
+
result.should_not == false
|
125
|
+
@test_schema_hash_mod['id'].should match(JSON.parse(result)['id'])
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should update a previously created schema under the specified project' do
|
129
|
+
result = @adapter.update_schema(@test_schema_hash_alt_mod)
|
130
|
+
result.should_not == false
|
131
|
+
@test_schema_hash_alt_mod['id'].should match(JSON.parse(result)['id'])
|
132
|
+
end
|
133
|
+
end
|
83
134
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
135
|
+
describe '#delete_schema' do
|
136
|
+
it 'should delete the specified schema' do
|
137
|
+
@adapter.delete_schema(@test_schema_hash).should == true
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should delete the specified schema in the specified project' do
|
141
|
+
@adapter.delete_schema(@test_schema_hash, "test").should == true
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should delete the specified schema in the specified project' do
|
145
|
+
@adapter.delete_schema(@test_schema_hash_alt).should == true
|
88
146
|
end
|
89
147
|
end
|
148
|
+
end
|
data/spec/persevere_spec.rb
CHANGED
@@ -57,7 +57,6 @@ describe Persevere do
|
|
57
57
|
result = @p.create('/Class/', @blobObj)
|
58
58
|
result.code.should == "201"
|
59
59
|
JSON.parse(result.body).should == @blobObj
|
60
|
-
# result.body.should == "\"Can not modify queries\""
|
61
60
|
# This shouldn't be a 201, it should say something mean.
|
62
61
|
end
|
63
62
|
end
|
@@ -73,7 +72,7 @@ describe Persevere do
|
|
73
72
|
end
|
74
73
|
|
75
74
|
it 'should 404 on a non-existent object' do
|
76
|
-
result = @p.retrieve('/Class/
|
75
|
+
result = @p.retrieve('/Class/GetNotThere')
|
77
76
|
result.code.should == "404"
|
78
77
|
result.message.should == "Not Found"
|
79
78
|
end
|
@@ -91,9 +90,10 @@ describe Persevere do
|
|
91
90
|
end
|
92
91
|
|
93
92
|
it 'should fail to modify a non-existent item' do
|
94
|
-
result = @p.update('/Class/
|
93
|
+
result = @p.update('/Class/NonExistent', @blobObj)
|
95
94
|
result.code.should == "500"
|
96
95
|
result.body.should == "\"id does not match location\""
|
96
|
+
@p.delete('/Class/NonExistent') # A bug(?) in Persevere makes a broken NonExistent class.
|
97
97
|
# This should be a 404 and not throw a persevere server exception
|
98
98
|
end
|
99
99
|
end
|
@@ -110,10 +110,9 @@ describe Persevere do
|
|
110
110
|
|
111
111
|
it 'should fail to delete a non-existent item' do
|
112
112
|
result = @p.delete('/Class/NotThere')
|
113
|
-
result.code.should == "
|
114
|
-
result.message.should == "
|
115
|
-
result.body.should
|
116
|
-
# This should be a 404 and not fail silently with a 204
|
113
|
+
result.code.should == "404"
|
114
|
+
result.message.should == "Not Found"
|
115
|
+
result.body.should == "\"Class/NotThere not found\""
|
117
116
|
end
|
118
117
|
end
|
119
118
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,14 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
1
|
+
require 'pathname'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
require 'addressable/uri'
|
5
|
+
require 'spec'
|
6
|
+
|
7
|
+
require 'ruby-debug'
|
8
|
+
|
9
|
+
require 'dm-core'
|
10
|
+
|
11
|
+
require 'adapter_shared_spec'
|
12
|
+
|
13
|
+
SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
|
14
|
+
# $LOAD_PATH.unshift(SPEC_ROOT.parent + 'lib')
|
15
|
+
|
16
|
+
Pathname.glob((SPEC_ROOT + '{lib,*/shared}/**/*.rb').to_s).each { |file| require file }
|
17
|
+
|
18
|
+
ENV['ADAPTERS'] ||= 'all'
|
19
|
+
|
20
|
+
ADAPTERS = []
|
21
|
+
|
22
|
+
PRIMARY = {
|
23
|
+
'persevere' => {:adapter => 'persevere', :host => 'localhost', :port => '8080'}
|
24
|
+
}
|
25
|
+
|
26
|
+
adapters = ENV['ADAPTERS'].split(' ').map { |adapter_name| adapter_name.strip.downcase }.uniq
|
27
|
+
adapters = PRIMARY.keys if adapters.include?('all')
|
28
|
+
|
29
|
+
PRIMARY.only(*adapters).each do |name, default|
|
30
|
+
connection_string = ENV["#{name.upcase}_SPEC_URI"] || default
|
31
|
+
begin
|
32
|
+
adapter = DataMapper.setup(name.to_sym, connection_string)
|
33
|
+
|
34
|
+
# test the connection if possible
|
35
|
+
if adapter.respond_to?(:query)
|
36
|
+
name == 'oracle' ? adapter.select('SELECT 1 FROM dual') : adapter.select('SELECT 1')
|
37
|
+
end
|
38
|
+
|
39
|
+
ADAPTERS << name
|
40
|
+
PRIMARY[name] = connection_string # ensure *_SPEC_URI is saved
|
41
|
+
rescue Exception => exception
|
42
|
+
puts "Could not connect to the database using #{connection_string.inspect} because: #{exception.inspect}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
logger = DataMapper::Logger.new(DataMapper.root / 'log' / 'dm.log', :debug)
|
47
|
+
logger.auto_flush = true
|
48
|
+
|
49
|
+
Spec::Runner.configure do |config|
|
50
|
+
config.extend(DataMapper::Spec::AdapterHelpers)
|
51
|
+
# config.include(DataMapper::Spec::PendingHelpers)
|
52
|
+
end
|
data/spec/unit/create_spec.rb
CHANGED
@@ -2,6 +2,19 @@ $LOAD_PATH << File.dirname(__FILE__)
|
|
2
2
|
|
3
3
|
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
4
4
|
|
5
|
+
#
|
6
|
+
# I need to make the Book class for Books to relate to
|
7
|
+
#
|
8
|
+
class Book
|
9
|
+
include DataMapper::Resource
|
10
|
+
|
11
|
+
# Persevere only does id's as strings.
|
12
|
+
property :id, String, :serial => true
|
13
|
+
property :author, String
|
14
|
+
property :created_at, DateTime
|
15
|
+
property :title, String
|
16
|
+
end
|
17
|
+
|
5
18
|
describe 'A Persevere adapter' do
|
6
19
|
|
7
20
|
before do
|
metadata
CHANGED
@@ -1,92 +1,95 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-persevere-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
|
8
|
-
|
7
|
+
- Ivan R. Judson
|
8
|
+
- The Yogo Data Management Development Team
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-01-
|
13
|
+
date: 2010-01-13 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: dm-core
|
18
|
+
type: :runtime
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.10.1
|
25
|
+
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: extlib
|
28
|
+
type: :runtime
|
29
|
+
version_requirement:
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "0"
|
35
|
+
version:
|
36
36
|
description: A DataMapper Adapter for persevere
|
37
37
|
email:
|
38
|
-
|
38
|
+
- irjudson [a] gmail [d] com
|
39
39
|
executables: []
|
40
40
|
|
41
41
|
extensions: []
|
42
42
|
|
43
43
|
extra_rdoc_files:
|
44
|
-
|
45
|
-
|
44
|
+
- LICENSE.txt
|
45
|
+
- README.txt
|
46
46
|
files:
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
47
|
+
- .gitignore
|
48
|
+
- History.txt
|
49
|
+
- LICENSE.txt
|
50
|
+
- Manifest.txt
|
51
|
+
- README.txt
|
52
|
+
- Rakefile
|
53
|
+
- VERSION
|
54
|
+
- lib/model_json_support.rb
|
55
|
+
- lib/persevere.rb
|
56
|
+
- lib/persevere_adapter.rb
|
57
|
+
- persevere/History.txt
|
58
|
+
- persevere/LICENSE.txt
|
59
|
+
- persevere/Manifest.txt
|
60
|
+
- persevere/README.txt
|
61
|
+
- spec/adapter_shared_spec.rb
|
62
|
+
- spec/lib/adapter_helpers.rb
|
63
|
+
- spec/persevere_adapter_spec.rb
|
64
|
+
- spec/persevere_spec.rb
|
65
|
+
- spec/spec.opts
|
66
|
+
- spec/spec_helper.rb
|
67
|
+
- spec/unit/create_spec.rb
|
68
|
+
- spec/unit/delete_spec.rb
|
69
|
+
- spec/unit/read_spec.rb
|
70
|
+
- spec/unit/update_spec.rb
|
71
|
+
- tasks/spec.rb
|
69
72
|
has_rdoc: true
|
70
73
|
homepage: http://github.com/yogo/dm-persevere-adapter
|
71
74
|
licenses: []
|
72
75
|
|
73
76
|
post_install_message:
|
74
77
|
rdoc_options:
|
75
|
-
|
76
|
-
|
78
|
+
- --main
|
79
|
+
- README.txt
|
77
80
|
require_paths:
|
78
|
-
|
81
|
+
- lib
|
79
82
|
required_ruby_version: !ruby/object:Gem::Requirement
|
80
83
|
requirements:
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "0"
|
84
87
|
version:
|
85
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
89
|
requirements:
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: "0"
|
90
93
|
version:
|
91
94
|
requirements: []
|
92
95
|
|
@@ -96,10 +99,12 @@ signing_key:
|
|
96
99
|
specification_version: 3
|
97
100
|
summary: A DataMapper Adapter for persevere
|
98
101
|
test_files:
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
102
|
+
- spec/adapter_shared_spec.rb
|
103
|
+
- spec/lib/adapter_helpers.rb
|
104
|
+
- spec/persevere_adapter_spec.rb
|
105
|
+
- spec/persevere_spec.rb
|
106
|
+
- spec/spec_helper.rb
|
107
|
+
- spec/unit/create_spec.rb
|
108
|
+
- spec/unit/delete_spec.rb
|
109
|
+
- spec/unit/read_spec.rb
|
110
|
+
- spec/unit/update_spec.rb
|